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.
Note that since we're using a placeholder to display our message, the Snippet tag doesn't need to go where the message should appear. That means the Snippet tag could actually go in a Template or Chunk, as long as it will be parsed before any placeholders it sets.
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 ''
It's important to always put a Snippet tag above any placeholders it sets. Otherwise, the placeholders won't be set at the time they are parsed, and they will be removed by the MODX parser.
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.