A simple AJAX filter for MODX using pdoPage. Conditional modifiers for templates in MODX Modx modifiers

Filters in the revolution allow you to control the way data is presented. They allow you to change values ​​within templates.

In Revolution, the output filter is applied one or more times to a series of output modifiers that behave similar to the PHx calls in MODx Evolution - except that they are built into the kernel. The syntax is as follows:

[ ]

They can also be connected (done from left to right):

[ ]

You can also use them to change the snippet's output; Please note, the modifier comes after the snippet name and before the question mark, for example,

[ ]

The following table lists some of the existing modifiers and provides examples of their use. Although the examples below are for some tags, output modifiers can be used with any MODx tag. Make sure the modifier is receiving data.

Conditional modifiers:

Modifier

Description

Example

if, input

Logical OR

[ [+numbooks:is=`5`:or:is=`6`:then=`There are 5 or 6 books!`:else=`Not sure how many books`] ]

Logical AND

isequalto, isequal, equalto, equals, is, eq

[ [+numbooks:isequalto=`5`:then=`There are 5 books!`:else=`Not sure how many books`] ]

notequalto, notequals, isnt, isnot, neq, ne

[ [+numbooks:notequalto=`5`:then=`Not sure how many books`:else=`There are 5 books!`] ]

greater thanorequalto, equalorgreaterthen, ge, eg, isgte, gte

Greater than or equal to

[ [+numbooks:gte=`5`:then=`There are 5 books or more than 5 books`:else=`There are less than 5 books`] ]

isgreaterthan, greaterthan, isgt, gt

[ [+numbooks:gt=`5`:then=`There are more than 5 books`:else=`There are less than 5 books`] ]

equaltoorlessthan, lessthanorequalto, el, le, islte, lte

Less than or equal to

[ [+numbooks:lte=`5`:then=`There are 5 or less than 5 books`:else=`There are more than 5 books`] ]

islowerthan, islessthan, lowerthan, lessthan, islt, lt

[ [+numbooks:lt=`5`:then=`There are less than 5 books`:else=`There are more than 5 books`] ]

[ [+numbooks:lt=`1`:hide] ]

[ [+numbooks:gt=`0`:show] ]

[ [+numbooks:gt=`0`:then=`Now available!`] ]

[ [+numbooks:gt=`0`:then=`Now available!`:else=`Sorry, currently sold out.`] ]

memberof, ismember, mo

[ [+modx.user.id:memberof=`Administrator`] ]

String modifiers:

Modifier

Description

Example

If not empty

[ [+numbooks:cat=` books`] ]

lcase, lowercase, strtolower

Transformation to small letters

[ [+title:lcase] ]

ucase, uppercase, strtoupper

Transformation to capital letters

[ [+headline:ucase] ]

Capitalize the first letter of a word

[ [+title:ucwords] ]

The first letter is capitalized

[ [+name:ucfirst] ]

htmlent, htmlentities

Replacing HTML Tags

[ [+email:htmlent] ]

esc,escape

Safely removes characters

[ [+email:escape] ]

Replacing carriage returns, tabs, and multiple spaces with a single space

[ [+textdocument:strip] ]

stripString

Removes a value from a string

[ [+name:stripString=`Mr.`] ]

Replacing a value

[ [+pagetitle:replace=`Mr.==Mrs.`] ]

striptags, stripTags, notags, strip_tags

Removes HTML tags

[ [+code:strip_tags=`

len,length,strlen

String length

[ [+longstring:strlen] ]

reverse, strev

Reverse line

[ [+mirrortext:reverse] ]

wordwrap

New line after the specified number of characters

[ [+bodytext:wordwrap=`80`] ]

wordwrapcut

Inserts a newline character after a specified number of characters.

[ [+bodytext:wordwrapcut=`80`] ]

Number of characters displayed

[ [+description:limit=`50`] ]

ellipsis

Trimming a line after the specified number of characters

[ [+description:ellipsis=`50`] ]

Displays a raw element without a: tag. Useful for documentation.

[ [+showThis:tag] ]

If the value can change dynamically, then it should be made uncached. For example:

[ [+placeholder:default=`A default value!`] ]

This means that the value may sometimes be empty and sometimes not. Why store it in cache? This may rule out that the value may appear.

If you are not sure whether the result will be when executing the snippet, then it is logical to make a default value:

[ [!getResources:default=`Sorry - nothing matched your search.`? &tplFirst=`blogTpl` &parents=`2,3,4,8` &tvFilters=`blog_tags==%%` &includeTVs=`1`] ]

Greetings, friends! Today we will learn how to create a resource filter in MODx Revolution with the ability to sort by any TV field and load the results by clicking “Load more”. To display the results we will use the pdoResources snippet.

Cool

Stammer

Download all snippets and necessary lesson files.

First you need to install the package pdoResources, which is included in the package pdoTools. You can install either the entire set of pdo packages (pdoTools) or just pdoResources as a separate package to create a filter on MODx Revolution.

After installing the packages, let's include the snippet that you downloaded into your project. If you are currently developing a directory from scratch, then I advise you to stick to using specific classes for Ajax filtering. Class naming scheme:

However, if you already have a ready-made directory, you can define the Ajax filter element classes in the JS file (see below).

note that .ajax-item must be a direct descendant .ajax-container. If you are using the Bootstrap grid for column layout, you can define the container class as "row ajax-container", and the item columns are like "col-md-4 ajax-item".

Connecting a JS script to an Ajax filter

Let's connect the JS script to the project. You can connect it either as a separate file or directly into the project’s custom scripts file. The script requires jQuery to run.

$(function() ( //MODx pdoResources Ajax Filter //Filter Settings var fadeSpeed ​​= 200, // Fade Animation Speed ​​ajaxCountSelector = ".ajax-count", // CSS Selector of Items Counter ajaxContainerSelector = ".ajax-container" , // CSS Selector of Ajax Container ajaxItemSelector = ".ajax-item", // CSS Selector of Ajax Item ajaxFormSelector = ".ajax-form", // CSS Selector of Ajax Filter Form ajaxFormButtonStart = ".ajax-start", // CSS Selector of Button Start Filtering ajaxFormButtonReset = ".ajax-reset", // CSS Selector of Button Reset Ajax Form sortDownText = "Descending", sortUpText = "Ascending"; function ajaxCount() ( if($(" .ajax-filter-count").length) ( var count = $(".ajax-filter-count").data("count"); $(ajaxCountSelector).text(count); ) else ( $(ajaxCountSelector ).text($(ajaxItemSelector).length); )ajaxCount(); function ajaxMainFunction() ( $.ajax(( data: $(ajaxFormSelector).serialize()).done(function(response) ( var $ response = $(response); $(ajaxContainerSelector).fadeOut(fadeSpeed); setTimeout(function() ( $(ajaxContainerSelector).html($response.find(ajaxContainerSelector).html()).fadeIn(fadeSpeed); ajaxCount(); ), fadeSpeed); )); ) $(ajaxContainerSelector).on("click", ".ajax-more", function(e) ( e.preventDefault(); var offset = $(ajaxItemSelector).length; $.ajax(( data: $(ajaxFormSelector ).serialize()+"&offset="+offset )).done(function(response) ( $(".ajax-more").remove(); var $response = $(response); $response.find( ajaxItemSelector).hide(); $(ajaxContainerSelector).append($response.find(ajaxContainerSelector).html()); $(ajaxItemSelector).fadeIn()); e) ( e.preventDefault(); ajaxMainFunction(); )) $(ajaxFormButtonReset).click(function(e) ( e.preventDefault(); $(ajaxFormSelector).trigger("reset"); $("input" ).val("pagetitle"); $("input").val("asc"); setTimeout(function() ( $("").data("sort-dir", "asc").toggleClass( "button-sort-asc").text(sortUpText); fadeSpeed); ajaxMainFunction(); )) $(""+ajaxFormSelector+" input").change(function() ( ajaxMainFunction(); )) $("").data("sort-dir", "asc").click(function() ( var ths = $(this); $("input").val($(this).data("sort-by")); $("input").val($(this).data("sort-dir")); setTimeout(function() ( $("").not(this).toggleClass("button-sort-asc").text(sortUpText); ths.data("sort-dir") == "asc" ? ths .data("sort-dir", "desc").text(sortDownText) : ths.data("sort-dir", "asc").text(sortUpText); $(this).toggleClass("button-sort" -asc"); ), fadeSpeed); ajaxMainFunction(); )); ));

  • Lines 5-13: defining variables for CSS Ajax filter selectors. We do not change if we use standard values, as in the figure above;
  • Lines 15-22: resource counter script in filtering results;
  • Lines 24-35: main Ajax filtering function;
  • Lines 37-49: event handler for clicking on the "Load more" button;
  • Lines 51-54: event handler for clicking on the "filter" button. This button may be absent, since filtering occurs automatically. Automatic filtering can be disabled by removing lines 68-70;
  • Lines 56-66: event handler for clearing the form and resetting the filter. Lines 59-63 are responsible for resetting the collation;
  • Lines 68-70: automatic sorting function when changing filter form fields;
  • Lines 72-82: universal sorting function by TV parameter.

I tried to make this script as universal as possible, so if you use standard Ajax filter element selectors, then you don’t need to edit anything.

Connecting a PHP snippet to MODx Revolution

Create a new snippet in the MODx control panel catalogFilter and fill it with the following content:

=".$_GET["area_from"]; ) if($_GET["area_to"]) ( $filter = "area<=".$_GET["area_to"]; } //Checkbox Type if($_GET["garage"]) { $filter = "garage=1"; } //End Settings //Sort if($_GET["sortby"]) { $sortby = $_GET["sortby"]; } else { $sortby = "pagetitle"; } if($_GET["sortdir"]) { $sortdir = $_GET["sortdir"]; } else { $sortdir = "asc"; } //End Sort //Offset $offset = 0; if($_GET["offset"]){ $offset = $_GET["offset"]; } if($filter) { $where = $modx->toJSON(array($filter)); ) else ( $where = ""; ) $params_count = array("parents" => $parents, "limit" => 0, "tpl" => "@INLINE ,", "select" => "id", "includeTVs" => $fields, "showHidden" => "1", "where" => $where); $count = $modx->runSnippet("pdoResources",$params_count); $count = count(explode(",",$count))-1; $modx->setPlaceholder("count",$count); $params = array("parents" => $parents, "limit" => $limit, "offset" => $offset, "tpl" => $tpl, "select" => "id,pagetitle,introtext,content ", "includeTVs" => $fields, "showHidden" => "1", "sortby" => $sortby, "sortdir" => $sortdir, "where" => $where); $more = $count - $offset - $limit; $lim = $more > $limit ? $limit: $more; $button = ""; if($more > 0)( $button = "
Load more ".$lim." from ".$more."
"; ) return $modx->runSnippet("pdoResources",$params).$button;

Between comments //Filter Fields Settings And //End Settings There are parameters that you need to edit to suit your project. There is nothing complicated here, just write the name of the input fields and check them with an if condition. For fields like Radio, Select and Text, we use the example from lines 5-8. To determine the intermediate value from and to, you can use the example from lines 11-16. For checkboxes, the example from lines 19-21 is suitable.

In line 74 of the snippet you can define your classes, but do not remove the current markup, as it is used in the scripts for loading content.

Example of possible values ​​in the MODx control panel for radio buttons: First==1||Second==2||Third==3


An example of displaying radio buttons in the frontend:

Here's the naming name="floor" matches lines 6-8 of our snippet catalogFilter. The processing of other form fields is implemented similarly. I think this is understandable and creating your own fields will not be a problem for you.

The snippet is output in the catalog template as follows:

[[!catalogFilter? &tpl=`tplCatItem` &limit=`3` &parents=`5` &fields=`image,area,floor,garage,price`]]

  • tpl=`tplCatItem`- chunk item in the catalog list;
  • limit=`3`- How many records to display and how many records to load when you click on the “Load more” button;
  • parents=`5`- indicate the id of the parent document for the resource catalog;
  • fields=`image,area,floor,garage,price`- list the TV's that need to be shown in the tplCatItem chunk and that need to be processed when filtering.

Chunk example tplCatItem

[[+pagetitle]]

[[+tv.area:isnot=``:then=` `]]
Floor [[+tv.floor]]
Square [[+tv.area]] sq.m.
Garage [[+tv.garage:is=`1`:then=`Yes`:else=`No`]]
Price: [[+tv.price]]

You can see a complex example of output to the frontend in the project repository on Github in the file demo.html.

Ajax sorting by TV

Our script has a ready-made solution for sorting filtering results by any TV field. Insert the following hidden fields into the filter form and do not change their value, they just need to be in the filter form:

Anywhere in your HTML template, make a button output and in the data attribute specify the field by which you want to filter the results:

Sort by price: Ascending

When clicked, the class is toggled button-sort-asc, which you can use to design a button when changing the sorting direction, adding arrows, etc. to the attribute data-sort-by You can write any TV that participates in filtering. That's all with sorting.

So, we looked at creating a simple Ajax resource filter in MODx with the results displayed in a snippet pdoResources.

Conditional modifiers in Revolution allow you to manipulate the way data is presented or parsed in tags. They also allow you to change values ​​inside your templates.

For example, we have a MainSlide snippet (it displays images from a MySql table into a slider):

To display a slider on the main page, you need to make a simple condition using the MODX modifier. This notempty modifier checks whether the placeholder contains a string or not:

[[+PlSliderMain:notempty=`[[+PlSliderMain]]`]]

In this example, we put the data in the placeholder and then check it through the modifier; you can also check the MODX fields and created additional fields:

If you have longer code in the a:then = ``:else = `` statement and you want to make it more readable by putting it on multiple lines, you would do it like this:

[[+placeholder:is=`0`:then=`
// code
`:else=`
// code
`]]

The following list lists the most useful conditional modifiers available and provides examples of their use. Output modifiers can be used with any MODx tag.

Modifier or,and

Checking for multiple values.

[[+slide:is=`5`:or:is=`6`:then=`The slider has content`:else=`The slider is empty`]]
[[+slide:is=`5`:and:is=`6`:then=`The slider has content`:else=`The slider is empty`]]

Modifier is

If the tag is equal to the modifier.

[[*slide:is=`5`:then=`There is content in the slider`]]
[[*slide:is=`5`:then=`The slider has content`:else=`The slider is empty`]]

Modifier ne

If the tag is not equal to the modifier.

[[*id:ne=`1`:then=`Not the main page`:else=`Main page`]]

Modifier notempty

Returns the specified modifier if the value is not empty.

[[*content:notempty=`[[*content]]`]]

Modifier hide, show

Hides the element if the condition is true or shows.

Modifier then, else

Condition: if the tag matches the modifier, we display a message.
Condition: if the tag does not match the modifier, display a message. Only used in conjunction with "then"

[[*id:is=`1`:then=`Display the slider`:else=`Slider only on the main page`]]

PHx (Placeholders Xtended) adds new capabilities for displaying placeholders, MODx tags (including TV parameters) and site settings tags. The recursive parser allows the use of nested tags. It is possible to create your own modifiers by creating snippets.

You can download the latest version of PHx from the MODX repository using this link.

New installation

  1. Download and unpack the archive.

Update

  1. Download and unpack the archive.
  2. Rename the /assets/plugins/phx directory to /assets/plugins/phx-old
  3. Create a "phx" directory in the /assets/plugins folder.
  4. Upload via FTP or simply copy the contents of the archive to /assets/plugins/phx
  5. Create a new plugin "PHx" in the MODx Control Panel (Elements - Element Management - Plugins) and copy the contents of the phx.plugin.txt file into it
  6. Check the "OnParseDocument" event in the "System Events" tab

Configuration

On the configuration tab, while editing the plugin, copy into the "Plugin configuration" field:

&phxdebug=Event log;int;0 &phxmaxpass=Max. number of passes;int;50

For advanced users

You can change the default settings for the PHx plugin:

Event log

0 = Disabled
1 = PHx event logging enabled
If enabled, PHx creates a detailed log for each event recorded in the event log (Reports->Event Viewer)

Max. number of passes

Defines the maximum depth of nested tags that can be processed. It is recommended to leave the value at 50.

PHx (Placeholders Xtended) expands the use of placeholders, content tags (including TV parameters) and site settings tags. Thanks to this, you can easily determine the output format of the final result. PHx is built into the MODX parser, expanding its functionality with modifiers, conditions and, as a bonus, making it truly recursive.

Supported tags

PHx supports the following MODx tags:

  • [+placeholder+]
  • [*content tags*] (for example: [*content*], [*pagetitle*] and others)
  • [*TV parameters*]
  • [(customization tags)] (for example: [(base_url)], [(site_name)] and others)

Snippets supporting PHx

  • Ditto
  • MaxiGallery

You can use PHx syntax in chunks used by snippets not on this list, but this requires a different method (see Tips & Tricks section)

Regular view placeholder

[+placeholder+]

easily turns into a PHx placeholder:

[+placeholder:esc+]

You can do the same with the content tag:

[*createdby*]

Add a modifier:

[*createdby:date=`%a %B %d, %Y at %H:%M`*]

You can also use several modifiers at once. They will be processed from left to right:

Somevar:esc:nl2br:strip

Advanced Applications

The presence of a special placeholder "phx" allows you to use PHx syntax without having a real variable.

[+phx:if=`[+this+]`:is=`[+that+]`:then=`do this`:else=`do that`+]

With some modifiers, this placeholder takes on a certain meaning. In the case of the "userinfo" modifier, it returns the corresponding value from the information about the current user:

[+phx:userinfo=`username`+]

Known Issues

Syntax

This seems logical, but it's worth focusing on. Avoid using the following constructs in a template unless they are part of a MODx tag:

[+
[*
[(
+]
*]
)]
]]

The parser will try to process them and MODx will throw an error. Usually this problem does not arise. But in the case of JavaScript, you might have a construct similar to this:

Array

Which will provoke strange behavior due to +]. Also the CDATA closing tag:

/* ]]> */

May create problems.

Remember that you cannot lose your site data by using incorrect PHx syntax. The worst that can happen is that your template will not display correctly.

Strings

lcase

ucase

Converts all characters in a string to uppercase.

[+string:ucase+]

At the entrance:

This is a string

THIS IS A STRING

ucfirst

The first letter in the line will become capitalized.

[+string:ucfirst+]

At the entrance:

length | len

Returns the length of the string.

At the entrance:

This is a string

notags

Will cut all HTML tags from a string.

[+string:notags+]

At the entrance:

This is a string

This is a string

esc

Removes html tags and line breaks

htmlent

Converts the original variable to an html entity. Analogous to htmlentities() in PHP.

nl2br

Converts newline characters to tags.

[+string:nl2br+]

At the entrance:

This is
a string

This is
a string

strip

Removes newline characters (\n), tabs (\t), and consecutive spaces.

[+string:strip+]

At the entrance:

This is
a
string

This is a string

Other modifiers

reverse

Turns letters backwards.

wordwrap

Breaks words in the current value longer than the given length of characters by putting a space in between.

Default: 70 characters.

Wordwrap(=`length`)

length - characters

limit

Returns the first X characters from the current value.

Default: 100 characters.

limit(=`length`)

Special

date

Converts a unix timestamp to match the specified format.

date(=`dateformat`)

dateformat: According to the format of the PHP function strftime

[*createdon:date=`%d.%m.%Y`*]

In order for the date to be displayed in accordance with the current site language, you need to set the locale at the beginning of the PHx plugin code. Example below for German:

setlocale(LC_ALL, "de_DE@euro", "de_DE", "de", "ge");

md5

Creates an MD5 hash of the current value.

userinfo

Fields used in the MODx database from the user_attributes table (for example: username, useremail).

Userinfo=`field`

  • cachepwd: Cache password
  • comment: Comment
  • country: Country
  • dob: Date of birth in UNIX time format
  • email: Email
  • fax: Fax
  • fullname: Full name
  • gender: Floor
  • internalKey:User internal key
  • lastlogin: Last login, in UNIX time format
  • logincount: Number of logins
  • mobilephone: Mobile phone
  • password: Password
  • phone: Telephone
  • photo: Photo
  • role: Role
  • state: Status
  • thislogin: This login, in UNIX time format
  • username: Login
  • zip: Postal code

math

Use calculations such as - * + /.

Math=`calculation`

"?" the symbol is replaced with the current value of the extension, but you can also use nested tags.

Calculation example: ?+1+(2+3)+4/5*6

ifempty

Use "other value" if placeholder/templatevar value is empty.

Ifempty=`other value`

select

Takes a value depending on the placeholder/templatevar values.

Select=`options`

parameters: value1=output1&value2=output2

At the entrance: 1

[+placeholder:select=`0=OFF&1=ON&2=UNKNOWN`+]

Return: ON

Conditional Expressions

is

ne

alias: isnot, isnt

not equal (!=)

eg

greater than or equal to (>=)

el

less than or equal to (<=)

GT

more (>)

lt

less (<)

mo=`Webgroups`

synonyms (aliases): isinrole, ir, memberof

Takes a comma-separated list of web groups as a parameter and returns true/false depending on whether the current user belongs to any of these groups or not (replaces the modifier "inrole", which had to be combined with a conditional operator).

[+phx:mo=`myWebgroup`:then=`I"m a member`:else=`I"m NOT a member`+]

if =`value`

Takes a comparison variable as a parameter. Can also be used in combination with :or or :and.

[+phx:if=`[+price+]`:gt=`0`:then=`Price: [+price+]`+]

or

Logical OR (checks whether the first or second condition is true).

[+phx:if=`[*id*]`:is=`2`:or:is=`3`:then=`((Chunk))`:else=`((OtherChunk))`+]

In this example, if the current ID is 2 or 3, then the chunk ((Chunk)) is displayed, otherwise the chunk ((OtherChunk)) is displayed.

and

Logical AND (checks if both conditions are true).

[+phx:if=`[!UltimateParent!]`:is=`1`:and:isnot=`[*id*]`:then=`((ChildChunk))`:else=`((ParentChunk)) `+]

In this example, if UltimateParent is equal to 1 and not equal to the current ID, then the chunk ((ChildChunk)) is displayed, otherwise the chunk ((ParentChunk)) is displayed.

then =`template`

Meaning template is displayed when all conditions are true. Here you can specify a call ((chunk)), [[snippet]] or pure HTML.

else =`template`

Meaning template is displayed when the conditions are not true. Here you can specify a call ((chunk)), [[snippet]] or pure HTML.

show

Used similarly then, but the original value is used as the output template. Executes if the conditions are true.

[+myplaceholder:len:gt=`3`:show+]

In this example, the placeholder value will be displayed if its length is more than 3 characters.

Custom modifiers

A modifier is a simple snippet that processes a given value. It is possible to create your own modifiers/mini-snippets by adding a new snippet in the MODx resource manager or by creating a file in the modifiers folder of the PHx plugin.

Since the modifier code is simple, it does not need any parameters, except for those that it receives from the parser.

There are two main variables:

$output- contains the current value of the variable that needs to be modified.
$options- an optional parameter, the value of which is passed to the modifier.

Example.

Let's give a couple of examples of using modifiers. Let's say that the placeholder myplaceholder matters "test":

[+myplaceholder:mymodifier+]

The $output variable contains the value "test".
The $options variable does not contain anything, because no parameter was passed to the modifier.

[+myplaceholder:mymodifier=`my options`+]

The $output variable still contains the value "test".
The $options variable now contains the value "my options"

Other variables (for advanced users)

$input - contains the original unmodified value.
$condition is an array containing the elements that form the conditional expression (0, 1, || and &&).

Creating your own modifier

Example 1: I love MODx

Using the knowledge gained, we will create a new custom modifier. This will be a parameterless modifier that will simply add the text "because I love MODx" to the variable. To do this you need to take the following steps:

1. In the Resource Manager, go to Resources (Elements) -> Manage Resources (Elements) -> Snippets

2. Click "New snippet"

phx:love"

In order for a snippet to be perceived as a modifier for PHx, its name must have the prefix "phx:" without spaces between it and the snippet name itself. Then you can use it as a modifier by adding: love to any placeholder, for example: [+myplaceholder:love+].

4. Now let's add the modifier code to the code field. Let's say this is code like this:

5. Save the changes and our new modifier ( :love) ready to use!

Example 2: I love MODx even more

Let's create a modifier similar to the modifier :love from the previous example, but we will additionally give it the ability to add to the source string the value of the passed parameter, if it was specified.

1. In the Resource Manager, go to Resources (Elements) -> Manage Resources (Elements) -> Snippets

2. Click "New snippet"

3. Set the snippet name to " phx:love2"

In order for a snippet to be perceived as a modifier for PHx, its name must be prefixed with " phx:" without spaces between it and the snippet name itself. Then you can use it as a modifier by adding: love to any placeholder, for example: [+myplaceholder:love2+] .

ChunkGood.

Other examples

[+myplaceholder:gt=`1`:then=`Yes`:else=`No`+]
[+myplaceholder:lt=`3`:and:gt=`1`:then=`Yes`:else=`No`+]
[+myplaceholder:lt=`[+someplaceholder+]`:then=`Yes`:else=`No`+]
[+myplaceholder:islt=`2`:then=`Yes`:else=`No`+]
[+myplaceholder:isnot=`2`:or:lt=`3`:then=`Yes`:else=`No`+]

All examples will be returned Yes.

[+myplaceholder:isnot=`2`:then=`Yes`:else=`No`+]
[+myplaceholder:gt=`[+someplaceholder+]`:then=`Yes`:else=`No`+]
[+myplaceholder:lt=`2`:then=`Yes`:else=`No`+]
[+myplaceholder:gt=`2`:then=`Yes`:else=`No`+]
[+myplaceholder:lt=`1`:then=`Yes`:else=`No`+]

All examples will be returned No.

In this article I would like to tell you about filters (modifiers) in MODx.

In principle, you can live without them, but knowing how and where they are used, the developer receives a powerful tool with which you can add small, but sometimes very useful logic to your site.

In this article I will talk about MODx Revolution. The ability to apply filters exists thanks to the PHx snippet, which by default is already built into the MODx Revolution core, but PHx is not included in the Evolution core, so it must be installed separately on Evo.

So, filters allow you to manipulate data that is obtained as a result of parsing placeholders and tags. They provide an opportunity modify data directly in your templates.

The syntax for filters is as follows:

It’s very convenient that they can be arranged in chains:

At the same time, it is also possible to pass parameters to snippets. The main thing is that the filter is written between the snippet name and the question mark:

The following table lists some of the filters and example showing them application. Although the examples use a placeholder, filters can be applied to any MODx tag. Make sure that the placeholder actually returns something.

Conditional modifiers

ModifierDescriptionExample
or Can be used with string modifiers to create a logical AND relationship
and Can be used with string modifiers to create a logical "OR" relationship
isequalto, isequal, equalto, equals, is, eq Compares the output with the specified value and, if there is a match, continues parsing the tag. Used in conjunction with "then" and "else" [[+numbooks:isequalto=`5`:then=`There are 5 books!`:else=`Not sure how many books`]]
notequalto, notequals, isnt, isnot, neq, ne Compares the output with the specified value and, if it does not match, continues parsing the tag. Used in conjunction with "then" and "else" [[+numbooks:notequalto=`5`:then=`Not sure how many books`:else=`There are 5 books!`]]
greater thanorequalto, equalorgreaterthen, ge, eg, isgte, gte

Compares the output with the specified value and, if the output is greater than or equal to the passed value, continues parsing the tag. Used in conjunction with "then" and "else"

[[+numbooks:gte=`5`:then=`There are 5 books or more than 5 books`:else=`There are less than 5 books`]]
isgreaterthan, greaterthan, isgt, gt

Compares the output with a given value. If the output is larger, parsing continues. Used with "then" and "else"

[[+numbooks:gt=`5`:then=`There are more than 5 books`:else=`There are less than 5 books`]]
equaltoorlessthan, lessthanorequalto, el, le, islte, lte Compares the output with the specified value and, if the output is less than or equal to the passed value, continues parsing the tag. Used in conjunction with "then" and "else" [[+numbooks:lte=`5`:then=`There are 5 or less than 5 books`:else=`There are more than 5 books`]]
islowerthan, islessthan, lowerthan, lessthan, islt, lt Compares the output with a given value. If the output is less, parsing continues. Used with "then" and "else" [[+numbooks:lte=`5`:then=`Less than 5 books`:else=`More than 5 books`]]
hide Checks the preceding conditions. If they were true, hides the element. [[+numbooks:lt=`1`:hide]]
show Checks the preceding conditions. If they were true, displays the element. [[+numbooks:gt=`0`:show]]
then Used as a consequence of some condition [[+numbooks:gt=`0`:then=`Now available!`]]
else Used as a consequence of some condition. Used in conjunction with "then" [[+numbooks:gt=`0`:then=`Now available!`:else=`Sorry, currently sold out.`]]
memberof, ismember, mo Returns the result of checking whether a user belongs to a given group. [[+modx.user.id:memberof=`Administrator`]]

String modifiers

ModifierDescriptionExample
cat Appends the specified string to the output if the output is not empty. [[+numbooks:cat=` books`]]
lcase, lowercase, strtolower Converts all characters in a string to lowercase. Identical to PHP function strtolower [[+title:lcase]]
ucase, uppercase, strtoupper Converts all characters in a string to uppercase. Identical to PHP function strtoupper [[+headline:ucase]]
ucwords Converts the first letters of all words in a string to uppercase. Identical to PHP ucwords function [[+title:ucwords]]
ucfirst Converts the first letter of a string to uppercase. Identical to PHP function ucfirst [[+name:ucfirst]]
htmlent, htmlentities

Identical to the PHP htmlentities function. Uses the current value of the system parameter "modx_charset" with the ENT_QUOTES flag

[[+email:htmlent]]
esc,escape Safely mnemonizes characters using regular expressions and str_replace. Also understands [, ] and ` [[+email:escape]]
strip Replaces all line breaks, tabs, and multiple spaces with a single space. [[+textdocument:strip]]
stripString Removes the specified substring from a string. [[+name:stripString=`Mr.`]]
replace Replaces one substring with another. [[+pagetitle:replace=`Mr.==Mrs.`]]
striptags, stripTags, notags, strip_tags Removes all PHP and HTML tags except the specified one. Identical to the PHP strip_tags function [[+code:strip_tags=`

`]]

len,length,strlen Prints the length of the string. Identical to PHP strlen function [[+longstring:strlen]]
reverse, strev Identical to PHP function strrev [[+mirrortext:reverse]]
wordwrap Identical to the PHP wordwrap function. Takes the optimal value for setting the word wrap position. [[+bodytext:wordwrap=`80`]]
wordwrapcut Identical to PHP wordwrap function with word breaks. Takes the optimal value for setting the word wrap position. [[+bodytext:wordwrapcut=`80`]]
limit Limits (truncates) the length of a string in a specified number of characters. The default length limit is 100 characters. [[+description:limit=`50`]]
ellipsis Trims a string to the specified number of characters and adds an ellipsis. The default limit is 100 characters. [[+description:ellipsis=`50`]]
tag Displays the called element without :tag. Useful for documentation, for example, like mine =) [[+showThis]]
math Returns the result of calculations (not recommended because it creates a load on the processor)
add,increment,incr Returns a value incremented by a specified amount (by default, by one) [[+downloads:incr]]
[[+blackjack:add=`21`]]
subtract, decrement, decr Decrements the specified value from a value (default: -1) [[+countdown:decr]]
[[+moneys:subtract=`100`]]
multiply,mpy Returns the result of multiplication by a number (default: *2) [[+trifecta:mpy=`3`]]
divide,div Returns the result of division by a number (default: /2) 0 is not allowed. [[+rating:div=`4`]]
modulus, mod Returns the remainder of a division (Default: %2, returns 0 or 1) [[+number:mod]]
ifempty,default,empty,isempty Returns the given string if the output is empty. [[+name:default=`anonymous`]]
notempty, !empty, ifnotempty, isnotempty Returns the given string if the output is not empty. [[+name:notempty=`Hello [[+name]]!`]]
nl2br Identical to the PHP nl2br function. All line breaks are replaced by
[[+textfile:nl2br]]
date Identical to the PHP strftime function. The format is passed as a value. See Date Formats. [[+birthyear:date=`%Y`]]
strtotime Identical to the PHP strtotime function. Applies to dates only. See Date Formats. [[+thetime:strtotime]]
fuzzydate Returns the date in the format "today at 13:40", "yesterday at 18:40". [[+publishedon:fuzzydate]]
ago Returns the number of seconds, minutes, hours, weeks, etc. from the date to the current moment. Applies to dates only [[+createdon:ago]]
md5 Identical to the PHP md5 function. [[+password:md5]]
cdata Encloses a string in CDATA tags. [[+content:cdata]]
userinfo Returns the requested user data. Applies to user ID in MODx. The modifier contains the field that needs to be returned. [[+modx.user.id:userinfo=`username`]]
isloggedin Returns "true" if the user is authorized in this context. [[+modx.user.id:isloggedin]]
isnotloggedin Returns "true" if the user is authorized in this context [[+modx.user.id:isnotloggedin]]
urlencode Identical to PHP urlencode function [[+mystring:urlencode]]
urldecode Identical to PHP urldecode function [[+myparam:urldecode]]

Creating custom modifiers

Snippets can be used as modifiers. To do this, simply replace the name of the filter with the name of the snippet. For example, we have a snippet called "makeDownloadLink"

[[+file:makeDownloadLink=`notitle`]]

This call will pass the following parameters to the snippet:


The result will be what will be returned snippet.

Examples of use

Here is an example where the filters are called one after another. This example formats a date from a string to another format:

[[+mydate:strtotime:date=`%Y-%m-%d`]]

Direct access to the modx_user_attributes table from the database from the snippet can be replaced by simply using the userinfo modifier. To get the required field, you need to pass the name of the column from the database to the modifier parameters.

Internal key: [[!+modx.user.id:userinfo=`internalKey`]]

Username: [[!+modx.user.id:userinfo=`username`]]

Full name: [[!+modx.user.id:userinfo=`fullname`]]

Role: [[!+modx.user.id:userinfo=`role`]]

E-mail: [[!+modx.user.id:userinfo=`email`]]

Phone: [[!+modx.user.id:userinfo=`phone`]]

Mobile: [[!+modx.user.id:userinfo=`mobilephone`]]

Fax: [[!+modx.user.id:userinfo=`fax`]]

Date of birth: [[!+modx.user.id:userinfo=`dob`:date=`%Y-%m-%d`]]

Gender: [[!+modx.user.id:userinfo=`gender`]]

Country: [[+modx.user.id:userinfo=`country`]]

Region: [[+modx.user.id:userinfo=`state`]]

Postal code: [[+modx.user.id:userinfo=`zip`]]

Avatar: [[+modx.user.id:userinfo=`photo`]]