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 = "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]]
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
- Download and unpack the archive.
Update
- Download and unpack the archive.
- Rename the /assets/plugins/phx directory to /assets/plugins/phx-old
- Create a "phx" directory in the /assets/plugins folder.
- Upload via FTP or simply copy the contents of the archive to /assets/plugins/phx
- 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
- 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
Modifier | Description | Example |
---|---|---|
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
Modifier | Description | Example |
---|---|---|
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`]]