MODX Output Filters - If & PHx Conditional Statements Tutorial

Feb 6, 2012

An important update has recently been added to this post. Please see the bottom of the article.

If you started using MODX in its first incarnation, Evolution, you're probably familiar with PHx - a snippet that allowed you to make fairly easy work of conditional statements within MODX's PHP framework. When Revolution came around the If snippet was released to replace PHx's functionality. I'm not exactly sure as to the timeline, but perhaps MODX output filters weren't around in the earliest versions...? I jumped to Revolution immediately, at version 2.0.0 but I don't remember output filters until later. And I don't think I'm alone because the If snippet exists, and people use it. But really for a lot of use cases - you don't need it! MODX Revolution output filters give you the power of conditional statements, built right into the MODX core. And like everything else in MODX, it's super easy!

What Are Conditional Statements Good For?

If you're reading this you probably already know the answer, but here's a quick example: you use one template for all your interior pages. Some of those pages have photo galleries, and some don't. You only want the pages with galleries to load the gallery markup and scripts, so a conditional statement allows you to do that without making a dedicated gallery template. This is only one example of many, many possibilities, but we'll use this one to illustrate how easy it is to do this in MODX.

Snippets vs. Output Filters

The If snippet makes it pretty easy to implement conditional statements, and possibly it is more powerful than output filters, but I rarely run into the case where output filters don't do the job perfectly. It saves you from installing one more package and including one more snippet, and once you get used to the syntax it's faster and easier to add output filters than writing snippet calls. So let's dive right in! Note: this is a MODX beginner tutorial...

Official Documentation

There's a comprehensive list of available modifiers for use in your output filters in the official docs

There are some missing examples, which I've been trying to fill in bit by bit in the docs, but we'll go through a few of them here too.

Example

So let's say you have a chunk with all your gallery scripts [[$galleryScripts]] and another with your markup [[$galleryHTML]]. In this example we're going to enable or disable the gallery (by including or not including those chunks) based on the MODX Resource ID. Say for example our gallery page has an ID of 5. We'd add this to our page template in the head element where we want our scripts to load:

[[*id:is=`5`:then=`[[$galleryScripts]]`]]

Break it down:

  • [[*id » We start with the subject of the conditional statement. We want to enable the gallery based on ID, so we use the MODX ID tag to start.
  • :is » isequalto, isequal, equalto, equals, is, eq - these are all valid conditional modifiers that compares the subject to the passed value. In this case it compares the Resource ID with the value of "5".
  • :then=`[[$galleryScripts]]`]] » If the condition is met, that is the ID is "5", then the chunk [[$galleryScripts]] is inserted. Remember the chunk tag is nested inside the ID tag, so you need to close the containing tag with double square closing brackets.

To summarize the code above, you're telling MODX: "If the document resource ID is 5, include this chunk". You would do exactly the same thing in the body of the page template to include the [[$galleryHTML]] chunk. Now what if you had more than one page with a gallery on it? You'd want the conditional statement to cover both instances. This is done with an "or" modifier, like this:

[[*id:is=`5`:or:is=`6`:then=`[[$galleryScripts]]`]]

Break it down:

  • :or:is » This is the only new bit here. Adding the ":or" modifier calls the two modifiers ":is=`5`" and ":is=`6`" so that if either condition is met, the value of ":then=" is output - in this case our scripts chunk. Wasn't that easy?

It's worth noting that you can actually have another output filter inside the chunk being output. Or you can output a snippet call. I haven't had much luck nesting output filters but I think you're supposed to be able to do that.

OH, and the best part is, (and this is how powerful and flexible MODX is in general, so don't be too surprised to learn that) you can make pretty much anything the subject of the output filter. So any system or context setting, any available tag or placeholder, even a snippet's output! Some plain-language examples:

  • If the ID of the document's Ultimate Parent (output via the snippet of the same name) matches a certain value, render this submenu. (This could be a Wayfinder call or a chunk with html links in it.
  • If the custom MODX Context setting [[++site_wide_value]] matches a certain string, then load a different logo image than the one in the default context.
  • If a placeholder into which a snippet's output is being stored is empty, then do nothing, but if it has a value then render the output inside a containing html element.

The possibilities are endless, and this functionality is built right into the MODX core. It blows my mind the power they've given to front-end developers. Remember, you don't have to write ANY PHP to do this! It's absolute genius!

Wrap-Up

I hope this tutorial has been helpful for some people. If you want examples of how to form output filters for any of the above scenarios - or any scenario for that matter - just comment below and I'll try to respond with an example. If you have your own ninja output filter use cases, please share them with us :) Happy MODX-ing!

IMPORTANT UPDATE

This is a rather old post, and the performance hit that comes with using conditionals is all too obvious when you start hitting your sites with a ton of traffic. As such, I've consistently deployed Jason Coward's "Mosquito Optimization" syntax for years now – since before that blog post went Live. Sorry I've been so slow updating this post. Please do read that article.

This gist of it is: always use conditionals in a way that will avoid nested tags. For example:

[[*id:is=`1`:then=`[[$chunk]]`]]

is far less performant than:

[[[[*id:is=`1`:then=`$chunk`:else=`-`]]]]

Note the tags aren't nested the same way in the 2nd example, but rather a "quadruple bracket" syntax is used. Only after the inner tag evaluates will the outer tag be formed and be processed. In the first example, the chunk is always processed regardless of how the condition evaluates.

Check out this post or this one for more MODX optimization tips.