mazoola
Forum Replies Created
-
Forum: Plugins
In reply to: [Airpress] Documentation for ShortcodesAfter 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.
Forum: Plugins
In reply to: [Airpress] Documentation for ShortcodesUsual 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
Forum: Plugins
In reply to: [Airpress] Documentation for ShortcodesI’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
Forum: Plugins
In reply to: [Airpress] loop failure or operator error?Chester –
After a lot of working on this one (and more airpress_debug() statements than I care to remember), I managed to come up with a construction that worked as desired. (Note: I still needed the SORT_REGULAR sorttype on line 231 of AirpressCollection.php, so if that introduces failures down the line, I guess this isn’t resolved.) I am still interested in understanding better some of the rules of Airpress (for instance, for the apr_loop3, below, I populate “outfit|garment” but loop only on “garment” — why?), but for the moment, I can at least move on.
Again, the situation is as follows: I’m displaying a ‘garment’ record via a VirtualPost. One or more garments may be brought together into an outfit (a record in the ‘outfits’ table), and a garment may be part of more than one outfit. As part of the garment display, I want to show all outfits of which it is a part, displayed as the outfit name, thumbnails of images of the outfit, and then all garments that make up the outfit (including the current garment), as well as thumbnails of all garment images.
Here’s the structure that ultimately worked, minus field display shortcodes, etc.:
garment [apr_populate field="outfit" relatedTo="outfits"] [apr_loop field="outfit"] [apr_loop2 field="outfitImages"] [/apr_loop2] [apr_populate field="outfit|garment" relatedTo="garments"] [apr_loop3 field="garment"] [apr_loop4 field="images"] [/apr_loop4] [/apr_loop3] [/apr_loop]
Once it was done, I could understand better why it required the syntax it does. Maybe with my next display, I’ll be better able to anticipate this.
Thanks,
MazForum: Plugins
In reply to: [Airpress] trouble reproducing Virtual Post exampleChester –
Adding the optional sortingtype of SORT_REGULAR to the call to ‘array_unique’ at line 231 of AirpressCollection.php fixes this error.* Does it introduce others? Quite possibly; I’ll update you if it does.
Maz
__________
* That is, it resolves the fatal error first described. For expediency’s sake, I now build the {{Container|Name}} ‘href’ — from the opening “<a href
” through the trailing"<br>"
— as a formula field within AirTable I then insert en masse. This avoids, but does not correct, the problem I described in my previous reply.- This reply was modified 7 years, 10 months ago by mazoola. Reason: fix embedded code
Forum: Plugins
In reply to: [Airpress] trouble reproducing Virtual Post exampleBTW, as a follow-up to footnote 1, I’m having difficulty finding a way to define an href to make [apr field=”Container|Name”] a hyperlink. Neither the {{}} nor the shortcode variations work within the hyperlink itself.
Forum: Plugins
In reply to: [Airpress] test url = default value?If you’re logged into WordPress admin, you’re able to load the “Map to this page” and Airpress will use the “Test URL” to populate it. … If you’re not logged into WordPress admin, you’ll get a 404 when you attempt to directly access the Virtual Post “Map to this page” URL.
Ah — makes sense!
I’m curious, with your specific example (a single VirtualPost config of ^folder/subfolder/(.*)/?), what did you expect to see (or want to see) when you visited /folder/subfolder/ ?
I expected a 404 or ‘no data returned’ page, as this is an erroneous entry. I don’t anticipate users of the final app to enter the URL manually — but if they did, I didn’t want a default value to be populated unexpectedly. (Actually, in this case it probably wouldn’t matter, as the returned page simply displays a list of records; I was more concerned about similar behavior on pages that might feed an edit or delete function.)
The application in question is a costume wardrobe database I’ve been fiddling with in part as a field test of AirTable and similar SAS offerings (exec summary: Airtable wins, hands-down) and in part to help in liquidating assets of a failed business venture that ended up in my lap. The index (archive?) Virtual Posts map to such things as ‘/wardrobe/genre/1940s’ or ‘/wardrobe/item/jacket’. Individual records will be accessed through RECORD_ID or a slug field, either as ‘/wardrobe/[key]’ or ‘/wardrobe/[item]/[key]’; I’ve not yet decided if there’s any value or detriment that would result from using the latter construction.
I think I may have made things more confusing by changing permalink formatting in midstream; that in combination with the “jes’ grew” nature of this development resulted in the template page permalink being the same as the Virtual Post match pattern sans $1. Accordingly,
nam[ing] all your “Map to this page” templates with a prefix of “TEMPLATE” so that the page slug is “template-something”
and changing the permalink to match took care of my concern, even if I mistakenly enter the truncated Virtual post URL while logged into WordPress.
Thanks for tracking this down so quickly and clearly!
Forum: Plugins
In reply to: [Airpress] nested loops?Thanks! Works great with the couple of test cases I’ve thrown at it so far.
(Ten deep, eh? This could be fun…)
Thanks!
Forum: Plugins
In reply to: [Airpress] trouble reproducing examplesPerfect! That fixed it — your screenshot configurations are good-to-go again…
Forum: Plugins
In reply to: [Airpress] trouble reproducing examplesGreat! I’ll give it a try.
BTW, using [apr_loop] without a field allowed me to access the records in my actual airtable database as I had initially intended. If I’d known about that, I never would have stumbled across this other issue. ??
Forum: Plugins
In reply to: [Airpress] trouble reproducing examplesUsing [apr_loop]..[/apr_loop] gets me closer; the page doesn’t hang, and I’m able to return to using ‘Restaurants’ as the name of the field in the Cuisines table.
However, {{Name}} within the loop returns only ‘Burgers’; {{Restaurants|Name}} returns the comma-delimited list of restaurant names….