/setPlaceholders

A MODX snippet for getting fields and setting placeholders.

Primary LanguagePHP

setPlaceholders 2.2.1

A MODX Revolution snippet for getting fields and setting placeholders. Download from the MODX Extras Repository.

setPlaceholders combines the usefulness of placeholders—which are rather like local variables—with a fast and versatile engine for gathering up various data: fields and TVs from a resource or any of its ancestors, children or siblings, plus several other useful things. It provides the functionality of getResourceField, UltimateParent, and getUrlParam—in addition to quite a bit more—all in one lightweight package.

New and changed in this version

Please see the changelog for a summary. Version 2.2.1 adds two short aliases for the setPlaceholders snippet: sph and spho. sph is exactly the same, just easier to type: [[setPlaceholders? ... ]] or [[sph? ... ]]. spho (o for output) is equivalent to [[setPlaceholders? &output=`1` ... ]]

Examples

  • Showing the main functionality:
[[setPlaceholders?
 	&ph=`parent.pagetitle ||
      13.introtext !! "No Summary Available" ||
      section == Uparent.tv.section ||
      parent.tv.columns !! parent2.tv.columns ||
      color == "#a35c0a"`
]]

Sets the placeholders:
[[+sph.parent.pagetitle]] the current resource's parent's pagetitle
[[+sph.13.introtext]] resource 13's introtext, or No Summary Available if not found
[[+section]] the value of a TV named section for the current resource's ultimate parent
[[+sph.parent.tv.columns]] the value of the columns TV for the resource's parent, or if it's not found, for the same TV on the resource's grandparent
[[+color]] #a35c0a

  • As a getResourceField replacement:
[[spho? &ph=`Uparent2.tv.someTV !! "No such TV"`]]

Returns the value of someTV for the second-highest parent of the current resource, or “No such TV” if that TV is empty or not found. It also puts this value in [[+sph.Uparent2.tv.someTV]]
This is the equivalent of:

[[getResourceField? &id=`[[UltimateParent? &topLevel=`3`]]`
  &field=`someTV` &isTV=`1` &default=`No such TV`]]
  • Simple next / previous, first / last navigation:
[[sph?
  &ph=`next == next.uri || prev == prev.uri || first == prevM.uri || last == nextM.uri`
]]
<a href="[[+first]]">First<a> [[+prev:!empty=`<a href="[[+prev]]">Previous<a>`]] [[+next:!empty=`<a href="[[+next]]">Next<a>`]] <a href="[[+last]]">Last<a>

Using uri is faster than getting the id and turning it into a link with [[~]]. However it won’t work if the resource doesn't have an alias set.

  • Getting some URL parameters:
[[!setPlaceholders? &ph=`get.type !! "1" || person == get.person`]]

Sets the placeholders:
[[+sph.get.type]] $_GET['type'] (or 1 if there's no type given)
[[+person]] $_GET['person']

  • One more example, with some other options:
[[setPlaceholders? &id=`13`
  &ph=`parent.longtitle || parent2.longtitle !! "[[someSnippet]]"`
  &prefix=`` &output=`1` &delimiter=` > `
]]

Returns: Long Title #1 > Long Title #2 (of course it'd be the actual longtitles)
Sets the placeholders:
[[+parent.longtitle]] Resource 13's parent's longtitle
[[+parent2.longtitle]] Resource 13's grandparent's longtitle, or if it's empty, the output from someSnippet

Properties

PropertyDescriptionDefault
&id The resource id to use. Can be overridden for individual items. current resource
&ph A list of placeholders to set, separated by ||
This property offers a fairly rich syntax; see the special section on it below for a complete explanation.
&placeholders A simple list of user-defined placeholders to set. Unlike with the &ph property, values aren't processed in any way and so don't need to be quoted. If you just need to set a few placeholders and don't need &ph's special getter abilities, this is the fastest way to do it.
Format: name1 == value 1 || name2 == value 2
&prefix Prepended to any unspecified placeholder names to reduce the likelihood of placeholder name conflicts. Not added to any user-specified placeholder names. Can be set to an empty string to eliminate the prefix. sph.
&outputOutput mode.
No (0): only set placeholders
Yes (1): also output the value of any placeholders. This allows the snippet to be used like getResourceField. Multiple values will be separated by &delimiter.
No (0)
&delimiter Separates values when results are returned as a string (i.e. &output=`1`) ,
&sortby Sort by criterion. Used when selecting child or sibling resources. menuindex
&sortdir Sort direction. Used when selecting child or sibling resources. ASC
&processTVs Whether or not to process TV values. If the TV has special output options or needs a path from its media source, turn processing on. Otherwise leave it off for faster TV performance. No (0)
&staticCache Determines whether the resource/TV object cache is cleared on snippet exit or remains available for subsequent calls on the same page.
On potentially uses more memory while MODX builds a page. Use it only if you call setPlaceholders several times on the same page and use the same resources/TVs in the different calls.
Off (0)

&ph Property Syntax

&ph is where you specify all the placeholders you want set. Separate multiple ones by ||.

A placeholder consists of 1–3 parts:

  1. placeholder_name == (optional). If specified, this will be the placeholder name. If left off, the placeholder name will be formed from a prefix (&prefix) + the field name.
    Examples: pid == parent.id – parent.id will be stored in [[+pid]]
    parent.id – parent.id will be stored in [[+sph.parent.id]] since no specific placeholder name was given and sph. is the default prefix.

  2. A value or a field name. Values are in quotes and are simply passed on without being evaluated further (though the quotes are trimmed off). A value might be a bit of text or the output from another snippet. Field names are parsed and evaluated, and represent some bit of data you'd like retrieved. They can have multiple selector prefixes.
    Examples: Values"A text message", "[[someSnippet]]" (MODX will evaluate someSnippet; setPlaceholders won't do anything further to the result)
    Fieldnamespagetitle, 13.Uparent2.tv.someTV

  3. !! fallback (optional). If the fieldname wasn't found or was empty, the fallback will be used. Multiple fallbacks are allowed (i.e. field !! fallback1 !! fallback2) and may be fieldnames or values.

Fieldname selector prefixes

These are evaluated in the order listed. Items ending with a ▣ return a value; those ending with a . require a further selector or a field name. [square brackets] indicates an optional parameter, {curly braces} — a required one. Prefixes may be chained where it makes sense, but—except for child*—may not be repeated. For instance: parent.pagetitle or 42.parent.childR.tv.someTV (not that you'd want to do that :-)

All selector names are cAsE SensitiVe.

  • get.{variable name} ▣ – a variable from $_GET (be sure to call setPlaceholders uncached if you're using either get, post or request)
    Example: get.page – the value of $_GET['page']

  • post.{variable name} ▣ – a variable from $_POST

  • request.{variable name} ▣ – a variable from $_REQUEST

  • resource_id. – Selects a specific resource. Otherwise the value of &id (by default the current resource) is used.
    Example: 12.pagetitle – get the pagetitle of resource 12.

  • Uparent[level]. – selects the resource's ultimate parent, that is, its top-level ancestor in the resource tree. (Uparent and parent are essentially mirror images of one another.) Use the optional level number to move further down the tree.
    Examples: Uparent.id – the resource's ultimate parent's id
    Uparent2.id – the resource's 2nd top-most parent's id

  • UparentB[level]. – bounded Uparent. Unlike the standard Uparent which returns nothing if there is no ultimate parent (for a resource already at the top of the tree, for example), UparentB will select the resource itself if there isn’t an ultimate parent.
    Example: UparentB.id is equivalent to Uparent.id !! id.

  • parent[level]. – selects the resource's parent. Use the optional level number to move further up the tree.
    Examples: parent.id – the resource’s parent’s id
    parent2.id – the resource’s grandparent’s id

  • parentB[level]. – bounded parent. Similar idea to UparentB above.
    Example: parent25.id will return nothing (unless you have a crazy deep resource tree), but parentB25.id will be equivalent to UparentB.id since it won't let you go past the top of the resource tree.

  • parents ▣ – Returns a comma-separated list of the resource’s parents, from the ultimate parent on the left to the immediate parent on the right. Sometimes useful for passing on to pdoResources, getResources or similar.

  • parentsI ▣ – (uppercase i at the end) Same as parents but adds the resource’s id as the last term of the string.

  • next[index]. – selects the resource's next sibling. Use &sortby and &sortdir to control the sort order. Add a numeric index to jump ahead by that many. An index of M (max) selects the last sibling.
    Example: next2.id – returns the id of the resource's sibling-after-next.

  • prev[index]. – selects the resource's previous sibling. Use &sortby and &sortdir to control the sort order. Add a numeric index to jump back by that many. An index of M (max) selects the first sibling.

  • index ▣ – Returns a resource's index within a list of its siblings. The first sibling will return 1, the second — 2, and so on.

  • child[child #]. – selects one of the resource's children. Use &sortby and &sortdir to control the sort order and the optional child number to specify a particular child. Negative child numbers start with the last child and move towards the first. Unlike other selectors, child* may be repeated multiple times to move further down the tree.
    Examples: child.id – id of the resource's first child
    child3.id – id of the resource's third child
    child-1.id – id of the resource's last child
    child-2.id – id of the resource's second-to-last child
    child.child-1.id — id of the first child's last child

  • childR. – selects a random child. This selected child is cached, so you may reuse the selector with the same parent multiple times within a setPlaceholders call to get different values from the same random child. (Setting &staticCache will leave it available for the next setPlacholders call as well.)
    Example: 12.childR.id || 12.childR.pagetitle — returns the id number and pagetitle of the same randomly selected child of resource 12.

  • childC ▣ – returns a count of the resource's immediate children.

  • tv.{TV name} ▣ – returns the value of the specified TV. By default TV values are unprocessed. Use &processTVs to change this.

  • migx[object limit].{MIGX TV name} ▣ – special processing for MIGX TVs (or for other arrays of JSON objects). If you use this selector, setPlaceholders will loop through the array and create placeholders for each key/value pair (it skips MIGX_id), plus a total. The placeholder names are in the format [main placeholder name].[key][item #]. Adding an optional number after migx limits the results to the first N objects in the TV.
    Example: The parent resource has a MIGX TV called imagestv with two fields: title and image. The resource has three items stored in this tv. photos == parent.migx.imagestv will set 7 placeholders: [[+photos.title1]] [[+photos.image1]] [[+photos.title2]] [[+photos.image2]] [[+photos.title3]] [[+photos.image3]] and [[+photos.total]] (the number of items processed: 3)
    photos == parent.migx1.imagestv will set 3 placeholders: [[+photos.title1]] [[+photos.image1]] and [[+photos.total]] (1).

  • migxC.{MIGX TV name} ▣ – returns a count of the items in a MIGX TV.

  • migxR.{MIGX TV name} ▣ – returns a random item from a MIGX TV. Using the MIGX TV from the example above, photos == parent.migxR.imagestv will set the placeholders [[+photos.title1]] [[+photos.image1]] (with values from a random row in the MIGX TV) and [[+photos.total]] will be 1.

  • json[object limit].{JSON TV name} ▣ – an alias for migx. And jsonC and jsonR are aliases for migxC and migxR.

  • level ▣ – returns the resource's level number in the resouce tree. A top-level resource would return 1, its child — 2, etc.

  • field name ▣ — return the value of the specified field for the selected resource. Basically anything you could get with the [[* ]] tag.

setPlaceholders caches the results of the MODX API calls it makes, so getting multiple fields from the same resource or from various parents or children of the same resource is quite efficient.

Notes

  • If you're using setPlaceholders inside a chunk used multiple times on a page, like as a tpl for getResources, and are calling it uncached—which you shouldn't be in most cases—then you may run into an interesting aspect of evaluation order by the MODX parser. If you've got uncached snippets storing values in cached placeholders you can get unexpected results from the placeholders. See this issue for an in-depth discussion.

githalytics.com alpha