Documentation for Shortcodes
-
Hi!
I’m trying to find documentation for the shortcodes? I’m trying to wrap my head around the difference between apr_populate, apr and apr_include.
And thank you for this amazing plugin.
-
I’m sure Chester will chime in shortly with expansions or corrections, but here’s my quick first pass through this.
[apr xxxxx=”yyyyyy“] is the display shortcode. (I’m lifting these names from the names of the functions associated with the shortcode.) There are evidently 10 possible keywords that can replace xxxxx, but the main one you’ll use (and the only one I’ve shown to work) is “field”. In brief,
[apr field="field_name"]
inserts the value of Airtable column field_name for the current record (row). How you determine which is the current record depends upon your calling mechanism. Typically, you will either select a record through an Airpress Virtual Field or Virtual Post. This usage is pretty well-documented in the code examples Chester provides.
Note that within a loop as defined by the [apr_loop] shortcode you will ordinarily use double curly braces rather than [apr] — that is to say, inside a loop, instead of
[apr field="bonus"]
, use{{bonus}}
.In his discussion of Virtual Fields, Chester also documents the use of a second keyword, “glue,” which provides a limited looping mechanism within [apr] itself. Similar to Airtable’s ARRAYJOIN() function, [apr field=”xxxxxx glue=”yyy“] will return the multiple values within xxxxxx as a concatenated string with yyy as the separator.
The other defined [apr] keywords include ‘relatedto’, ‘recordtemplate’, ‘relatedtemplate’, ‘wrapper’, ‘single’, ‘rollup’, ‘default’, and ‘format’. At the moment, not all appear to be supported in code, so some may disappear before the final cut.
[apr_populate xxxxx=”yyyyyy” (..)] is the populate shortcode. It allows one to access fields within linked records. To date, the only documented usage is
[apr_populate field="xxxxxx" relatedTo="yyyyyy"]
This takes linked-record field xxxxxx in the current record, which links to the yyyyyy table, and returns a collection of yyyyyy records as an AirpressCollection, which can then be acted upon by other Airpress functions. I suspect the most-common use of this syntax will be to set up a loop through a group of related records. For instance, given a related record field children that links to records in the child table, the following call to [apr_populate] would return a collection of child records, which could then be stepped through to display fields from each record — as so:
[apr_populate field="children" relatedTo="child"] [apr_loop field="children"] {{childName}}, {{childAge}}, {{childGrade}} [/apr_loop]
As illustrated in his documentation of [apr_populate], in the case of recursive [apr_populate]s, the populate field needs to state explicitly it is a field of the earlier-populated record. I realize that explanation is probably worse than no explanation at all, but it’s much easier to understand with an illustration:
[apr_populate field="Location" relatedTo="Locations"] [apr_populate field="Location|Owner" relatedTo="Owners"]
If you are looping through the outermost populated records, you’ll want to perform the second [apr_populate] within the first loop, as such:
[apr_populate field="outfit" relatedTo="outfits"] [apr_loop field="outfit"] {{outfitName}} [apr_populate field="outfit|garment" relatedTo="garments"] [apr_loop2 field="garment"] {{garmentName}} [/apr_loop2] [/apr_loop]
There are other keywords defined for [apr_populate], none of which I’ve tested, but which suggest one might be able to populate a filtered collection — that is, a collection consisting of a subset of the records linked to by
field = ""
matching a predetermined filter instantiated (presumably) with the [apr] shortcode — a sorted collection, or a specified number of matching records: ‘filterbyformula’, ‘view’, ‘sort’, and ‘maxrecords’.[apr_loop], the — quelle surprise — loop shortcode, I largely covered in passing, with a few additional comments.
First, to allow nested loops, there are actually eleven [apr_loop] shortcodes: [apr_loop], [apr_loop1], [apr_loop2], and so on until [apr_loop10]. You’ll want to make sure to close your loops correctly to avoid problems like
[apr_loop field="xxxxxx"] [apr_loop1 field="yyyyyy"] [/apr_loop] [/apr_loop1]
Second, [apr_loop] is currently the only non-self-closing Airpress shortcode, so you’ll need to close the shortcode with [/apr_loop].
Third, in addition to Airpress Collections instantiated by [apr_populate], [apr_loop] also loops through arrays — including arrays of images as attachments. Take a look at Chester’s examples for info on the syntax used to select thumbnail or full-sized images. (Also note the full Airpress API — which is far more full-featured than that currently exposed through shortcodes — contains a function to generate images in a wider range of sizes than Airtable alone. Chester is reportedly creating a shortcode incorporating this functionality, so the image-specifying syntax will undoubtedly change.)
Fourth, ‘field’ is currently the only valid keyword for [apr_loop] — but it is possible to use [apr_loop] with no keyword in at least once instance. In the case of a Virtual Post where the ‘Filter by Formula’ matches more than one record, [apr_loop] in the VP template, without a specified field, loops through the records returned by the Virtual Post.
Finally, [apr_include path=”xxxxxx“] is the include shortcode, including [presumably] the output of a PHP file. I’ve not yet attempted this, and the implementation calls several functions I’ve not yet bothered to track down. Seemingly, ‘path’ is the only currently supported keyword of the three defined (‘path’, ‘value’, ‘title’) and indicates a .php file located on the server that is called by the shortcode. If I get around to playing with it and nothing burns down, I’ll document my experience here.
Hope this hasn’t been too rudimentary and might be of some assistance — or, at least, not too confusing.
Maz
-
This reply was modified 7 years, 10 months ago by
mazoola. Reason: munged formatting
Hi! I was particularly confused by the apr_loop and apr_populate shortcodes so I’m glad for your reply, thank you! I’ll post again if I have any trouble. ??
Thank you again for your detailed reply, am trying hard to understand your comment and the video/docs from Chester. (I am not good with watching videos, so and prefer examples and documentation in article form rather than video tutorials. So forgive me if I have overlooked details in the documentation videos.)
There is one very basic question I have right now – if I have more than one configuration in Virtual Fields, how does Airpress know which one to look for? Can I not configure that in the shortcodes? I am tripping over some really basic things at the moment at getting my Airtable data to show up correctly.
Also mostly I am working through shortcodes as I could not quite understand how to use the full Airpress API.
Usual caveat applies: This is my understanding of the plug-in, based on current documentation, my experiences with it, and occasional trawls through the code. I trust Chester will correct anything I get too horribly wrong….
At the heart of Airpress is a data structure called the Airpress Collection. Airpress shortcodes act upon the current Airpress Collection or the current Airpress Record within the current Airpress Collection; they have meaning only in relation to such currently active data structures.[1] In contrast, Airpress Virtual Fields and Virtual Posts are functions that generate an Airpress Collection which can then be accessed through a shortcode.
Accordingly, one cannot use a shortcode to choose from possible Virtual Fields. Instead, a Virtual Field or Post is selected based upon the specifics of the call resulting in the creation of a WordPress post or page. I see the difference between Virtual Fields and Posts being one of specificity: the Virtual Field function results from the matching of one or more Airtable records with a defined WordPress post or page, while a Virtual Post is based upon the matching of a WordPress URL with one or more Airtable records. In the latter case the resulting Airpress Collection is mapped against a defined WordPress template page.
The difference between matching a post or page and matching a URL is a subtle but important one and can probably best be explained by example. If you look at the Screenshots section of the Airpress plugin page, you’ll find Chester provides an introduction to the configuration of Airpress Connections, Virtual Fields, and Virtual Posts, and to the use of shortcodes, based upon Airtable’s Restaurant Field Guide template.[2]
Here’s Chester’s sample Virtual Field configuration:
With this configuration, each new successful call to display a WordPress post is parsed by Airpress. The
post_title
is extracted and matched against the {Name} field in the ‘Cuisines’ table, and a new Airpress Collection is generated containing all ‘Cuisines’ records where {Name} matchespost_title
.[3] If such a record is found, its fields may be accessed using Airpress shortcodes.Note that in this case there must be a defined post where
post_title
explicitly matches {Cuisines|Name}’ for Virtual Field to return an Airpress Collection. For instance, Chester offers the following example of a matching post:When this post is displayed, Airpress will query Airtable for the ‘Cuisines’ record where {Name} = ‘Burgers’ and make its variables accessible though shortcodes.[4] Again, this post only allows access to the ‘Burgers’ record; in order to display variables having to do with restaurants offering ‘Vegetarian’ cuisine, a dedicated post template must be created. If at some later point the user decides to add a ‘Paleo’ type to the ‘Cuisines’ multi-select, ‘Paleo’-related data will remain locked away until someone creates a ‘Paleo’-centric post.
As an alternative to the specificity of Virtual Fields, one might prefer to implement this as a Virtual Post, as such:[5]
Based on this configuration, all requested WordPress URLs are routed through Airpress and tested for a match to the regular expression
^Cuisines/(*.)
. If match tests positive, everything following the prefix — that is, the portion of the URL that matches(*.)
, referenced here as$1
, as the first matching regex capture group — is used to search for ‘Restaurants’ records where {Cuisine} contains $1. Once again, matching records are returned as an Airpress Collection (and, in this case, may certainly return multiple records), the individual variables of which are accessible through Airpress shortcodes.Note that here, rather than returning a specific post or page as based upon the called URL, WordPress maps the returned records against a specially created template file — in this case, something called ‘restaurant template’). This template may have no relationship (hierarchical or otherwise) with the requested URL; in fact, typically the template is not intended to be called directly by WordPress. As the page is displayed, shortcodes in the template will be expanded to reflect variables from the then-active Airpress Record.
The power of this functionality should be obvious: A single defined Virtual Post and its corresponding template are all that is required to display Airtable data for ‘Restaurant’ records of any ‘Cuisine’ type — including any cuisine types that defined in the future.
As a call to Virtual Post may return an Airpress Collection containing multiple records, this provides an ideal opportunity to make use of the non-specific [apr_loop] shortcode format I mentioned in my earlier response. For instance, give the Virtual Post configuration above, the following code, if contained in the specified template, will be replaced by a list of all restaurants that offer the requested cuisine:
[apr_loop]{{Name}}<br />[/apr_loop]
Even better, we can add a formula field to the ‘Restaurants’ table named “slug” containing the following formula:
SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(LOWER(Name)," ","-"),"&","%26"),":","%3A")
This encodes restaurant names into comparably unique, all-lower-case, HTML-safe strings suitable use in a URL. We can then configure a second Virtual Post, as such:
This causes Airpress to parse any WordPress page display request matching “/Restaurant/(.*)”, query Airtable for a ‘Restaurants’ record where {{Restaurants|slug}} = ‘$1’, and map the resulting record to a restaurant-centric template. We can then return to our initial, cuisine template and modify the loop to now read
[apr_loop]<a href="/Restaurant/{{slug}}">{{Name}}</a><br />[/apr_loop]
This now causes a call to “/Cuisines/[Type of Cuisine]” to replace the above code with a list of restaurants offering the desired cuisine, with each name in the listing linked to a restaurant detail page.
Furthermore,
[apr_loop]<a href="/Restaurant/{{slug}}">{{Name}}</a> [apr_loop1 field="Pictures"]<img src="{{thumbnails|small|url}}" /> [/apr_loop1]<br />[/apr_loop]
will result in the hyperlinked restaurant list, with each entry followed by thumbnails of the pictures associated with that restaurant. And
[apr_loop]<a href="/Restaurant/{{slug}}">{{Name}}</a> [apr_loop1 field="Pictures"]<a href="{{url}}" class="[Your favorite lightbox plugin]"><img src="{{thumbnails|small|url}}" /></a> [/apr_loop1]<br />[/apr_loop]
turns those thumbnail lists into miniature lightbox galleries.
A few odds and ends: If a call that would otherwise be processed by a Virtual Post maps to an actual WordPress page or post — for instance, if there actually is a ‘/Cuisines/Burgers’ page — Airpress yields to WordPress, and the defined page is displayed instead. And, conceivably, it should be possible to define a Virtual Field and a Virtual Post such that a single URL would be a valid trigger for either — or both; I have no idea what happens, then.
Again, I hope this is accurate enough to be of some help….
Vann
__________
1. Strictly speaking, the
[apr_loop]
shortcode does result in the creation of an Airpress Collection — but it does so only in context of the Airpress Collection active at the time of its call, so it can’t be used to generate the initial Collection accessed.2. I found one of the best introductions to Airpress is simply to try to implement the examples Chester provides. Admittedly, each time (once for Virtual Fields, once for Posts) in doing so I uncovered a bug in the then-current Airpress release, and there is at least one erroneous piece of sample code (hint: it still references the plugin’s original name of ‘Airfields’) — but I learned at least as much from figuring out what wasn’t working correctly as I did from successful attempts. (To create an Airtable base that will work with his examples, log into Airtable.com, choose “New Base,” and select “Start with a template”. On the “Templates” page, select “Everyday Life” from the menu in the left sidebar. “Restaurant Field Guide” is the first template on the “Everyday Life” page; select it, followed by “Use template” on the template page.)
3. I’m not sure if Virtual Field returns records where [Airtable Table|Airtable Column] includes the specified WordPress field or only if it matches it. From a comment in the code it appears the former functionality is desired but possibly not yet implemented.
4. Or through the full Airpress API, of course.
5. Here I part ways with Chester; this is my own example.
-
This reply was modified 7 years, 10 months ago by
mazoola. Reason: stupid typos
After looking at Frederick Jansen’s recent pull requests and stepping through the code, I’m starting to understand better some of Airpress’s un[der]documented shortcode keywords. For instance, the full suite of
[apr_populate]
keywords allows such functionality as having the Airpress Collection created by the shortcode to be sorted or filtered or to contain only ‘maxrecords’ entries.One semi-un[der]documented keyword for the
[apr]
shortcode is ‘single’, applicable to Airtable fields containing multiple values. For instance, given an attachment field named ‘images’, the following line of code will cause only a single image to be displayed, even if the field contains multiple images:<img src='[apr field="images|url" single]'>
Seemingly, ‘single’ will work on any field containing multiple values, including a multiple select field with multiple values selected, a linked-record field supporting multiple links, or formula, look-up, or roll-up fields resulting in multiple, comma-delimited values. Presumably, the single field displayed will be the first field in the resulting Airpress Collection, after application of any sorts or filters also defined in the
[apr]
shortcode.I’ll append additional shortcode info to this post as I work my way through them.
Thanks for your patience! And thank you @mazoola for stepping up and helping out!
I’m learning that writing good documentation is just about as difficult (or at least as time consuming) as writing code—hence I’ve focused on the code part since I’m actively using Airpress myself on projects.
The plugin is really a two-part beast, at least in usage, and should probably be more clearly separated. On one part we have how it’s used via PHP code. On the other, we have how it’s used via shortcodes in a post.
Somewhat joining the two are the settings pages—as they’re available to both. It’s a bit muddled since I built the plugin primarily for use in code and anticipated using just a few shortcode references that basically call a custom function that interface with Airpress. But I got hooked on the idea of having as much PHP goodness available via shortcodes right out of the box.
Basically, the shortcodes were (are?) a bit ambitious since the rest of the Airpress API isn’t even documented yet. But alas, it is what it is.
Thanks for helping each other out and for all the great feedback.
What I think my ultimate vision would be, is a configuration screen that allows you to create Queries. These queries could then be independently associated with specific URLs, Posts, Pages, etc. This way, when editing a post/page, you could simply select one or more queries that would be run when that page/post loads. This wouldn’t remove any functionality, rather just abstract the “query” away from the url/post/page on which its used.
Any other ideas?
-
This reply was modified 7 years, 10 months ago by
- The topic ‘Documentation for Shortcodes’ is closed to new replies.