MODX Snippet Development Part 6

Adding placeholders to the snippet to allow the user to put it anywhere on the page, in different places on different pages, or display it multiple times.

By Bob Ray  |  Updated: April 3, 2024  |  5 min read
MODX Snippet Development Part 6

In the last article, we changed the &interval property to make the Snippet more user-friendly, and we did a little error handling. In this article we'll look setting placeholders in order to give the user more control over the Snippet's output.

Starting Point

For reference here's where we left off in the last article:

/* NewResource Snippet */

/* Default return value */
$output = '';

/* Return value for new resources that are published */
$newOutput = $modx->getOption('showNew', $scriptProperties,
    '<span class="new_resource">NEW!</span>', true);

/* Set $interval as the number of seconds in two weeks */
$interval = $modx->getOption('interval', $scriptProperties, '2 weeks', true);

$cutoffTime = strtotime('now - ' . $interval);

if ($cutoffTime === false) {
    $output = '[NewResource] Invalid interval';
}

/* See if the resource is published */
$published = $modx->resource->get('published');

/* See if publication date is within the last 2 weeks */
if ($published && $cutoffTime) {
    /* Get the current time as a timestamp */
    $currentTime = time();

    /* Get the publishedon date and
       convert it to a unix timestamp */
    $ptime = strtotime($modx->resource->get('publishedon'));

    if ($ptime > $cutoffTime) {
        /* Yes, it's recent -- Set the return value */
            $output = $newOutput;
        }
    }
}

return $output;

A Feature Request

Imagine that you have a user who wants to display the Snippet's output in several places on the same page. It would be wasteful to have the Snippet run and do all the calculations for each location, since it only has to happen once. This is a perfect situation for placeholders. We'll create the option to set a placeholder with the Snippet's output. The user can put that placeholder anywhere on the page and use it in as many places as necessary.

We'll use a property called &ph. We'll let the user give us the name of the placeholder, and we'll only set it if it has a value. As long as the NewResource Snippet tag is above any placeholders on the page, they'll all be set:

[[!NewResource? &showNew=`NEW!!!` &ph=`MyPlaceholder]]

This page is [[+MyPlaceholder]] [[+MyPlaceholder]] [[+MyPlaceholder]] 

The three placeholders in the HTML above will be replaced by the &showNew value. If we wanted the message to be a little more eye-catching, we could do this:

[[!NewResource? &showNew=`<span style="color:red;">NEW!!!</span>` &ph=`MyPlaceholder]]

In keeping with our previous principle of not mixing style and content, though, this would be a better approach:

[[!NewResource? &showNew=`<span class="new_resource">NEW!!!</span>` &ph=`MyPlaceholder]]

Our CSS file could then contain this line, which could be changed later to alter the color of all messages on all pages:

.new_resource {
    color:red;
}

You might be thinking that the span tags should go in the page rather than the Snippet, since they are part of the view, not the business logic. The problem with this is that the span tags will then be part of the page regardless of the page's age and whether the user has set a placeholder or not. You can eliminate them with an output modifier that only displays them when they are not empty, but that's what our Snippet does, and it will do it much faster than the output modifier would. In the interest of faster page-load times, putting them in the Snippet is probably justified. And the user can still style the message any way they want.

Setting the Placeholder

To make the placeholder work, we'll add this code near the top of the Snippet to get the &ph property (the name of our placeholder):

$ph = $modx->getOption('ph', $scriptProperties, '', true);

If the user doesn't send that property, or if the property is empty, the $ph variable will be empty.

We also don't want to return the output (which would be displayed at the location of the Snippet tag), if the user has specified a placeholder. We'll change the return statement at the end accordingly:

if (!empty($ph)) {
    $modx->setPlaceholder($ph, $output);
    $output = '';
}

return $output;

This way, if the user sends the &ph property, the placeholder will be set and nothing will appear at the location of the Snippet. If the &ph property is empty or not sent, the output will appear where the Snippet tag is placed. This is why we've set the default placeholder as ''

New Code

Here's the final version of the code with the placeholder option:

/* NewResource Snippet */

/* Default return value */
$output = '';

/* Optional placeholder */
$ph = $modx->getOption('ph', $scriptProperties, '', true);

/* Return value for new resources that are published */
$newOutput = $modx->getOption('showNew', $scriptProperties,
    '<span class="new_resource">NEW!</span>', true);

/* Set $interval as the number of seconds in two weeks */
$interval = $modx->getOption('interval', $scriptProperties, '2 weeks', true);

$cutoffTime = strtotime('now - ' . $interval);

if ($cutoffTime === false) {
    $output = '[NewResource] Invalid interval';
}

/* See if the resource is published */
$published = $modx->resource->get('published');

/* See if publication date is within the last two weeks */
if ($published && $cutoffTime) {
    /* Get the current time as a timestamp */
    $currentTime = time();

    /* Get the publishedon date and
       convert it to a unix timestamp */
    $ptime = strtotime($modx->resource->get('publishedon'));

    if ($ptime > $cutoffTime) {
        /* Yes, it's recent -- Set the return value */
            $output = $newOutput;
        }
    }
}

if (!empty($ph)) {
    $modx->setPlaceholder($ph, $output);
    $output = '';
}

return $output;

Coming Up

In this article, we looked at using a placeholder to give the user more control over where the output appears. In the next one, we'll see how to internationalize our Snippet, so it can be used in more than one language.


Bob Ray is the author of the MODX: The Official Guide and dozens of MODX Extras including QuickEmail, NewsPublisher, SiteCheck, GoRevo, Personalize, EZfaq, MyComponent and many more. His website is Bob’s Guides. It not only includes a plethora of MODX tutorials but there are some really great bread recipes there, as well.