
MODX Revolution Meets Fenom
Recently, in the English-speaking community of MODX there has been a lot of discussion on the topic “how can we live further”. Everyone is intermittently discussing the upcoming (in a few years, I suppose) major version 3, but for now we are improving the current version with our additions.
A recent event that I would like to share with a wide audience is the release of a new version of pdoTools with the Fenom template engine , which will allow you to completely get rid of piling up tags in the conditions of chunks and rewrite them in a simple and understandable template language.
The procedure does not require changes to the site, just upgrade pdoTools to version 2.0 and you can use the new syntax . The best part is that MODX tags are perfectly adjacent to Fenom and work together without any problems. A simple example for seed:
So, the pdoTools parser is a separate class that is registered in the MODX system settings and intercepts the tag processing on the page.
In older versions of the component, the inclusion of the parser had to be confirmed during installation, but from version 2.1.1-pl it is enabled by default. If, for some reason, this does not suit you, delete the system settings
By default, MODX does not have these settings, they are only needed to connect an external parser, as in our case.
pdoParser can be used in two cases:
In the pdoTools class there are 2 methods for this, very similar to those in the modX class:
The main feature of the work of these methods is that the protected _loadChunk method is used to load the chunk , which can not only load the chunk from the database, but also turn arbitrary strings into it.
So, both pdoTools methods support the following types of chunk names:
One of the most popular options is to indicate the body of the chunk directly on the page. For instance:
There is a peculiarity in such an indication that many people don’t think about - all placeholders inside the chunk will be processed by the parser before the snippet is called.
That is, if you call the snippet on the page like this:
and at the same time placeholders are set in the system’s memory ,
Just the same values that some other snippet set earlier. That is why in the example we have such unusual placeholders -
You can use curly braces as a frame for placeholders in all pdoTools chunks - it will turn them into
For the same reason, calls to snippets and filters in INLINE chunks will never work for you. This will not work :
And so - no problem
Remember this nuance when using INLINE chunks.
Many people blame MODX for not being able to store chunks in files and forcing it to work with the database once again. This is both inconvenient for a version control system and slower.
Since version 2.2 MODX suggests using static elements for these purposes , but for a number of reasons, this method may still be less convenient than direct work with files.
pdoTools opens this possibility when specifying @FILE:
For security purposes, you can only use files with the html and tpl extension , and only from a specific, predefined directory. By default, this is:
You can specify your own directory for files through the parameter
The file will be downloaded from the file
This type of chunk allows you to use system templates (i.e. modTemplate objects) to style output.
If an empty template is specified and in the selected records there is a field
This is an analogue of the renderResources snippet .
When displaying a template, you can also specify a set of parameters (like snippets):
Then the values from this set will be inserted into the template.
This is the default mode, which loads the chunk from the database:
Parameter sets are also supported in the same way:
These methods of loading chunks work in all native pdoTools snippets and in all others that use the pdoTools
The declaration of this method looks like this:
The method loads the specified chunk (following the instructions of @BINDING, if any) and completely reverses it, replacing all placeholders with the values passed (parameter $ properties).
The third parameter
A recursive parser is one of the advantages of MODX and specially left tags are very often found in the logic of the system snippets. Therefore, it is
The pdoTools parser will not call the system parser if it was able to parse all the placeholders on its own. If any calls to filters or snippets remain in the chunk, then the work is transferred to modParser, which requires additional processing time.
And this method is declared like this:
It also creates a chunk from the specified name, parsing @BINDING, if any, and then simply replaces the placeholders with values, without any special processing.
This is the easiest and fastest way to format data in chunks.
If pdoParser is enabled in the settings, it is also called to process the entire page when it is displayed to the user.
Using this parser, all MODX chunks and add-ons are processed a little faster. Just "a little" because it does not take on the conditions and filters, processing only simple tags, such as
In addition to a possible increase in speed, you also get new opportunities for convenient output of data from various resources.
At the end of 2012, a small plug-in was introduced to the public with the addition of new tags to the MODX parser, which then grew into a fastField component .
He adds to the system the processing of additional placeholders, such as
All fastField tags begin with
The output of the usual resource fields:
TV resource parameters:
MiniShop2 product fields:
Arrays of resources and goods:
Superglobal arrays:
You can specify any fields in arrays:
If you do not know what values are inside the array, just specify it and it will be printed completely:
FastField tags can be combined with MODX tags:
Support for the Fenom template engine appeared in pdoTools from version 2.0 , after which it began to require PHP 5.3+.
It works much faster than the native modParser, and if you rewrite your chunk so that it does not have a single MODX tag, then modParser will not start at all. At the same time, of course, the simultaneous operation of both old tags and new ones in one chunk is allowed .
The following system settings affect the processing by the template engine:
So, by default, Fenom is enabled to work only in chunks that go through pdoTools. It is completely safe and system managers do not receive any additional features, except for more convenient syntax and high speed.
Enabling pdotools_fenom_parser allows you to use the Fenom syntax directly in the content of documents and page templates, but there is one caveat - the template engine can incorrectly respond to curly braces, which MODX really likes.
In such cases, the author recommends using the { ignore } tag .
If you plan to enable Fenom globally for the entire site, you need to check if it works fine on all pages.
To begin, I advise you to read the official documentation , and then we will consider the syntax with respect to MODX.
All variables from snippets are transferred to the chunk as is, so rewriting old chunks with the new syntax is a real pleasure.
To use more complex entities, pdoParser provides a service variable {$ _modx} , which gives safe access to some variables and methods of the system.
In addition, variables are available to you:
{$ _modx-> config} - system settings
{$ _modx-> user} - an array of the current user. If it is authorized, then data from the profile is added:
{$ _modx-> context} - an array with the current context
{$ _modx-> resource} - an array with the current resource, as you already saw in the examples above
{$ _modx-> lexicon} - an object (not an array!) modLexicon , which can be used to load arbitrary dictionaries:
A separate function is responsible for the output of records
Fenom uses a point to access the value of the array, and MODX usually puts placeholders from arrays like this. Accordingly, for the [[+ tag.sub_tag]] tags there are no analogues in Fenom.
Therefore, for such placeholders you need to use the second utility variable - {$ _pls} :
The variable
Therefore, snippets and chunks are called like this:
As you can see, the syntax almost completely repeats PHP, which opens up new possibilities. For example, you can specify arrays instead of JSON strings.
By default, all snippets are called cached, but you can add
If the native MODX method is used to call the snippet, pdoTools is launched to display the chunks, and you can use all its features:
The examples above are a little crazy, but they work for themselves.
The modX :: cacheManager service is available in the {$ _modx} object, which allows you to set arbitrary caching times for called snippets:
You can see this cache in
And you can start system processors (if you have enough rights):
Since there is no object with the user
These methods should be familiar to all MODX developers, so just show them with examples:
Using the Fenom template engine allows you to include one chunks (templates in others) and even expand them.
For example, you can simply load the contents of the chunk:
Read more about { include } in the official documentation.
A much more interesting function is the { extends } of templates, it requires the included system settings pdotools_fenom_parser .
We write the basic template "Fenom Base":
It includes regular chunks (in which, by the way, ordinary MODX placeholders from Theme.Bootstrap component ) and defines several blocks
Now we write "Fenom Extended":
So you can write one basic template and expand it with children.
In the same way, you can write and expand chunks, just note that to work with modTemplate you need to specify the template: prefix , but for chunks not - they work by default in all
We create a new site and add 1000 resources to it with this console script:
Then create 2 chunks:
and
And we add two console testing scripts. For the native parser MODX
And for pdoTools:
Since pdoTools understands both syntaxes, there are 2 tests for it - in MODX tag mode, and in Fenom mode.
In the scripts there is an indication of limit = 10, then in the table I give the numbers with its increase:
And now, let's complicate the chunks a bit - add the link generation for the resource and the output
and
As you can see, processing chunks via pdoTools is faster in all cases.
It is also noticeable that Fenom chunks have a certain minimum for starting, which is due to the need to compile the template.
Let's summarize the pdoTools parser features:
At the moment, pdoTools has been downloaded more than 40,000 times from the official repository and more than 10,000 from the modstore.pro repository , which allows us to hope for the wide spread of new template technologies in MODX.
Many thanks to aco habrayuzer for a wonderful template engine!
A recent event that I would like to share with a wide audience is the release of a new version of pdoTools with the Fenom template engine , which will allow you to completely get rid of piling up tags in the conditions of chunks and rewrite them in a simple and understandable template language.
The procedure does not require changes to the site, just upgrade pdoTools to version 2.0 and you can use the new syntax . The best part is that MODX tags are perfectly adjacent to Fenom and work together without any problems. A simple example for seed:
{if $parent == 3}
[[!pdoMenu?parents=`0`]]
{else}
[[!pdoResources?parents=`1,2,3`]]
{/if}
Under the cut, a huge amount of information about the pdoTools parser, which I have never collected in one place. So, the pdoTools parser is a separate class that is registered in the MODX system settings and intercepts the tag processing on the page.
In older versions of the component, the inclusion of the parser had to be confirmed during installation, but from version 2.1.1-pl it is enabled by default. If, for some reason, this does not suit you, delete the system settings
- parser_class - parser class name
- parser_class_path - path to the parser class
By default, MODX does not have these settings, they are only needed to connect an external parser, as in our case.
Principle of operation
pdoParser can be used in two cases:
- when rendering a chunk with a snippet - this always happens in all snippets using pdoTools, regardless of system settings.
- when rendering a page - only if the parser is enabled in the system settings.
Chunk Processing
In the pdoTools class there are 2 methods for this, very similar to those in the modX class:
- getChunk - full chunk processing, can use the native MODX parser
- parseChunk - only replacing placeholders with values, modParser is not called
The main feature of the work of these methods is that the protected _loadChunk method is used to load the chunk , which can not only load the chunk from the database, but also turn arbitrary strings into it.
Chunk Options
So, both pdoTools methods support the following types of chunk names:
@INLINE or @CODE
One of the most popular options is to indicate the body of the chunk directly on the page. For instance:
[[!pdoResources?
&parents=`0`
&tpl=`@INLINE {{+id}} - {{+pagetitle}}
`
]]
There is a peculiarity in such an indication that many people don’t think about - all placeholders inside the chunk will be processed by the parser before the snippet is called.
That is, if you call the snippet on the page like this:
[[!pdoResources?
&parents=`0`
&tpl=`@INLINE [[+id]] - [[+pagetitle]]
`
]]
and at the same time placeholders are set in the system’s memory ,
[[+id]]
or the [[+pagetitle]]
already processed chunk will come to the snippet and you will get the same lines on the page, such as:15 - тест
15 - тест
15 - тест
Just the same values that some other snippet set earlier. That is why in the example we have such unusual placeholders -
{{+}}
instead [[+]]
. The system parser does not touch them, and pdoTools replaces them with normal ones during operation. You can use curly braces as a frame for placeholders in all pdoTools chunks - it will turn them into
[[+]]
when loading. For the same reason, calls to snippets and filters in INLINE chunks will never work for you. This will not work :
[[!pdoResources?
&parents=`0`
&tpl=`@INLINE [[+id]] - [[+pagetitle:default=`название страницы`]]
`
]]
And so - no problem
[[!pdoResources?
&parents=`0`
&tpl=`@INLINE {{+id}} - {{+pagetitle:default=`название страницы`}}
`
]]
Remember this nuance when using INLINE chunks.
@FILE
Many people blame MODX for not being able to store chunks in files and forcing it to work with the database once again. This is both inconvenient for a version control system and slower.
Since version 2.2 MODX suggests using static elements for these purposes , but for a number of reasons, this method may still be less convenient than direct work with files.
pdoTools opens this possibility when specifying @FILE:
[[!pdoResources?
&parents=`0`
&tpl=`@FILE resources/mychank.tpl`
]]
For security purposes, you can only use files with the html and tpl extension , and only from a specific, predefined directory. By default, this is:
/assets/elements/chunks/
. You can specify your own directory for files through the parameter
&tplPath
:[[!pdoResources?
&parents=`0`
&tpl=`@FILE resources/mychunk.tpl`
&tplPath=`/core/elements`
]]
The file will be downloaded from the file
/core/elements/resources/mychunk.tpl
from the root of the site.@TEMPLATE
This type of chunk allows you to use system templates (i.e. modTemplate objects) to style output.
[[!pdoResources?
&parents=`0`
&tpl=`@TEMPLATE Base Template`
]]
If an empty template is specified and in the selected records there is a field
template
with id or the name of the template, then the record will be wrapped in this template:[[!pdoResources?
&parents=`0`
&tpl=`@TEMPLATE`
]]
This is an analogue of the renderResources snippet .
When displaying a template, you can also specify a set of parameters (like snippets):
[[!pdoResources?
&parents=`0`
&tpl=`@TEMPLATE Base Template@MyPropertySet`
]]
Then the values from this set will be inserted into the template.
Ordinary chunks
This is the default mode, which loads the chunk from the database:
[[!pdoResources?
&parents=`0`
&tpl=`MyChunk`
]]
Parameter sets are also supported in the same way:
[[!pdoResources?
&parents=`0`
&tpl=`MyChunk@MyPropertySet`
]]
These methods of loading chunks work in all native pdoTools snippets and in all others that use the pdoTools
getChunk
and methods parseChunk
.GetChunk method
The declaration of this method looks like this:
getChunk(string $chunkName, array $properties, bool $fastMode = false)
The method loads the specified chunk (following the instructions of @BINDING, if any) and completely reverses it, replacing all placeholders with the values passed (parameter $ properties).
The third parameter
fastMode
cuts out all the remaining raw placeholders so that there are no extra tags on the page. If this is not done, then the parser will try to parse these tags recursively (up to 10 iterations by default), which can lead to a slowdown. A recursive parser is one of the advantages of MODX and specially left tags are very often found in the logic of the system snippets. Therefore, it is
fastMode
disabled by default and you need to use it only if you are sure of what you are doing.The pdoTools parser will not call the system parser if it was able to parse all the placeholders on its own. If any calls to filters or snippets remain in the chunk, then the work is transferred to modParser, which requires additional processing time.
ParseChunk method
And this method is declared like this:
parseChunk(string $name, array $properties, string $prefix = '[[+', string $suffix = ']]')
It also creates a chunk from the specified name, parsing @BINDING, if any, and then simply replaces the placeholders with values, without any special processing.
This is the easiest and fastest way to format data in chunks.
Page processing
If pdoParser is enabled in the settings, it is also called to process the entire page when it is displayed to the user.
Using this parser, all MODX chunks and add-ons are processed a little faster. Just "a little" because it does not take on the conditions and filters, processing only simple tags, such as
[[+id]]
and [[~15]]
. However, he does it faster than modParser, because he does not create unnecessary objects. In addition to a possible increase in speed, you also get new opportunities for convenient output of data from various resources.
Tags fastField
At the end of 2012, a small plug-in was introduced to the public with the addition of new tags to the MODX parser, which then grew into a fastField component .
He adds to the system the processing of additional placeholders, such as
[[#15.pagetitle]]
. With the permission of the author , this functionality is already included in pdoParser, and even slightly expanded. All fastField tags begin with
#
and continue to contain either the id of the desired resource or the name of the global array. The output of the usual resource fields:
[[#15.pagetitle]]
[[#20.content]]
TV resource parameters:
[[#15.date]]
[[#20.some_tv]]
MiniShop2 product fields:
[[#21.price]]
[[#22.article]]
Arrays of resources and goods:
[[#12.properties.somefield]]
[[#15.size.1]]
Superglobal arrays:
[[#POST.key]]
[[#SESSION.another_key]]
[[#GET.key3]]
[[#REQUEST.key]]
[[#SERVER.key]]
[[#FILES.key]]
[[#COOKIE.some_key]]
You can specify any fields in arrays:
[[#15.properties.key1.key2]]
If you do not know what values are inside the array, just specify it and it will be printed completely:
[[#GET]]
[[#15.colors]]
[[#12.properties]]
FastField tags can be combined with MODX tags:
[[#[[++site_start]].pagetitle]]
[[#[[++site_start]]]]
Fenom Template Engine
Support for the Fenom template engine appeared in pdoTools from version 2.0 , after which it began to require PHP 5.3+.
It works much faster than the native modParser, and if you rewrite your chunk so that it does not have a single MODX tag, then modParser will not start at all. At the same time, of course, the simultaneous operation of both old tags and new ones in one chunk is allowed .
The following system settings affect the processing by the template engine:
- pdotools_fenom_default - enables pdoTools chunks processing through Fenom. Enabled by default.
- pdotools_fenom_parser - includes processing by the template engine of all pages of the site. That is, not only chunks, but also patterns.
- pdotools_fenom_php — включает поддержку PHP функций в шаблонизаторе. Очень опасная функция, так как любой менеджер получит доступ к PHP прямо из чанка.
- pdotools_fenom_modx — добавляет системные переменные
{$modx}
и{$pdoTools}
в шаблоны Fenom. Тоже очень опасно — любой менеджер может управлять объектами MODX из чанков. - pdotools_fenom_options — JSON строка с массивом настроек согласно официальной документации. Например:
{"auto_escape":true,"force_include":true}
- pdotools_fenom_cache — кэширование скопмилированных шаблонов. Имеет смысл только для сложных чанков на рабочих сайтах, по умолчанию отключено.
So, by default, Fenom is enabled to work only in chunks that go through pdoTools. It is completely safe and system managers do not receive any additional features, except for more convenient syntax and high speed.
Enabling pdotools_fenom_parser allows you to use the Fenom syntax directly in the content of documents and page templates, but there is one caveat - the template engine can incorrectly respond to curly braces, which MODX really likes.
In such cases, the author recommends using the { ignore } tag .
If you plan to enable Fenom globally for the entire site, you need to check if it works fine on all pages.
Syntax
To begin, I advise you to read the official documentation , and then we will consider the syntax with respect to MODX.
All variables from snippets are transferred to the chunk as is, so rewriting old chunks with the new syntax is a real pleasure.
MODX | Fenom |
[[+ id]] | {$ id} |
[[+ id: default = `test`]] | {$ id?: 'test'} |
[[+ id: is = ``: then = `test`: else =` [[+ pagetitle]] `]]] | {$ id == ''? 'test': $ pagetitle} |
To use more complex entities, pdoParser provides a service variable {$ _modx} , which gives safe access to some variables and methods of the system.
MODX | Fenom |
[[* id]] | {$ _modx-> resource.id} |
[[* tv_param]] | {$ _modx-> resource.tv_param} |
[[% lexicon]] | {$ _modx-> lexicon ('lexicon')} |
[[~ 15]] | {$ _modx-> makeUrl (15)} |
[[~ [[* id]]]] | {$ _modx-> makeUrl ($ _ modx-> resource.id)} |
[[++ system_setting]] | {$ _modx-> config.system_setting} |
In addition, variables are available to you:
{$ _modx-> config} - system settings
{$_modx->config.site_name}
{$_modx->config.emailsender}
{$_modx->config['site_url']}
{$_modx->config['any_system_setting']}
{$ _modx-> user} - an array of the current user. If it is authorized, then data from the profile is added:
{if $_modx->user.id > 0}
Привет, {$_modx->user.fullname}!
{else}
Вам нужно авторизоваться.
{/if}
{$ _modx-> context} - an array with the current context
Вы находитесь в контексте {$_modx->context.key}
{$ _modx-> resource} - an array with the current resource, as you already saw in the examples above
{$_modx->resource.id}
{$_modx->resource.pagetitle}
{$_modx->makeUrl($_modx->resource.id)}
{$ _modx-> lexicon} - an object (not an array!) modLexicon , which can be used to load arbitrary dictionaries:
{$_modx->lexicon->load('ms2gallery:default')}
Проверка словарей ms2Gallery: {$_modx->lexicon('ms2gallery_err_gallery_exists')}
A separate function is responsible for the output of records
{$_modx->lexicon()}
.Placeholders with a point
Fenom uses a point to access the value of the array, and MODX usually puts placeholders from arrays like this. Accordingly, for the [[+ tag.sub_tag]] tags there are no analogues in Fenom.
Therefore, for such placeholders you need to use the second utility variable - {$ _pls} :
{$_pls['tag.subtag']}
Conclusion of snippets and chunks
The variable
{$_modx}
is actually a simple and safe microMODX class.Therefore, snippets and chunks are called like this:
{$_modx->runSnippet('!pdoPage@PropertySet', [
'parents' => 0,
'showLog' => 1,
'element' => 'psoResources',
'where' => ['isfolder' => 1],
'showLog' => 1,
])}
{$_modx->getPlaceholder('page.total')}
{$_modx->getPlaceholder('page.nav')}
As you can see, the syntax almost completely repeats PHP, which opens up new possibilities. For example, you can specify arrays instead of JSON strings.
By default, all snippets are called cached, but you can add
!
before the name - as in MODX tags. If the native MODX method is used to call the snippet, pdoTools is launched to display the chunks, and you can use all its features:
{$_modx->getChunk('MyChunk@PropertySet')}
{$_modx->parseChunk('MyChunk', [
'pl1' => 'placeholder1',
'pl2' => 'placeholder2',
])}
{$_modx->getChunk('@TEMPLATE Base Template')}
{$_modx->getChunk('@INLINE
Имя сайта: {$_modx->config.site_name}
')}
{$_modx->getChunk(
'@INLINE Передача перемнной в чанк: {$var}',
['var' => 'Тест']
)}
{$_modx->getChunk('
@INLINE Передача переменной в вызов сниппета:
{$_modx->runSnippet("pdoResources", [
"parents" => $parents
])}
Всего результатов: {$_modx->getPlaceholder("total")}
',
['parents' => 0]
)}
The examples above are a little crazy, but they work for themselves.
Caching management
The modX :: cacheManager service is available in the {$ _modx} object, which allows you to set arbitrary caching times for called snippets:
{if !$snippet = $_modx->cacheManager->get('cache_key')}
{set $snippet = $_modx->runSnippet('!pdoResources', [
'parents' => 0,
'tpl' => '@INLINE {$id} - {$pagetitle}',
'showLog' => 1,
])}
{set $null = $_modx->cacheManager->set('cache_key', $snippet, 1800)}
{/if}
{$snippet}
You can see this cache in
/core/cache/default/
; in the example, it is stored for 30 minutes. set $null = ...
needed to cacheManager->set
not display 1 (i.e. true) on the page. And you can start system processors (if you have enough rights):
{$_modx->runProcessor('resource/update', [
'id' => 10,
'alias' => 'test',
'context_key' => 'web',
])}
Authorization Check
Since there is no object with the user
{$_modx}
, the methods for checking authorization and access rights are taken directly to the class:{$_modx->isAuthenticated()}
{$_modx->hasSessionContext('web')}
{$_modx->hasPermission('load')}
Other methods
These methods should be familiar to all MODX developers, so just show them with examples:
{$_modx->regClientCss('/assets/css/style.css')}
{$_modx->regClientScript('/assets/css/script.js')}
{$_modx->sendForward(10)}
{$_modx->sendRedirect('http://yandex.ru')}
{$_modx->setPlaceholder('key', 'value')}
{$_modx->getPlaceholder('key')}
{if $res = $_modx->findResource('url-to/doc/')}
{$_modx->sendRedirect( $_modx->makeUrl($res) )}
{/if}
Template Extension
Using the Fenom template engine allows you to include one chunks (templates in others) and even expand them.
For example, you can simply load the contents of the chunk:
Обычный чанк {include 'имя чанка'}
Шаблон modTemplate {include 'template:имя шаблона'}
Чанк с набором параметров
{include 'chunk@propertySet'}
{include 'template:Name@propertySet'}
Read more about { include } in the official documentation.
A much more interesting function is the { extends } of templates, it requires the included system settings pdotools_fenom_parser .
We write the basic template "Fenom Base":
{include 'head'}
{block 'navbar'}
{include 'navbar'}
{/block}
{block 'content'}
{$_modx->resource.content}
{/block}
{block 'sidebar'}
Sidebar
{/block}
{block 'footer'}
{include 'footer'}
{/block}
It includes regular chunks (in which, by the way, ordinary MODX placeholders from Theme.Bootstrap component ) and defines several blocks
{block}
that can be expanded in another template. Now we write "Fenom Extended":
{extends 'template:Fenom Base'}
{block 'content'}
{$_modx->resource.pagetitle}
{parent}
{/block}
So you can write one basic template and expand it with children.
In the same way, you can write and expand chunks, just note that to work with modTemplate you need to specify the template: prefix , but for chunks not - they work by default in all
{include}
and {extends}
.Performance testing
We create a new site and add 1000 resources to it with this console script:
getService('error','error.modError');
$modx->setLogLevel(modX::LOG_LEVEL_FATAL);
$modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');
for ($i = 1; $i <= 1000; $i++) {
$modx->runProcessor('resource/create', array(
'parent' => 1,
'pagetitle' => 'page_' . rand(),
'template' => 1,
'published' => 1,
));
}
Then create 2 chunks:
modx
and fenom
with the following contents, respectively:[[+id]] - [[+pagetitle]]
and
{$id} - {$pagetitle}
And we add two console testing scripts. For the native parser MODX
getService('error','error.modError');
$modx->setLogLevel(modX::LOG_LEVEL_FATAL);
$modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');
$res = array();
$c = $modx->newQuery('modResource');
$c->select($modx->getSelectColumns('modResource'));
$c->limit(10);
if ($c->prepare() && $c->stmt->execute()) {
while ($row = $c->stmt->fetch(PDO::FETCH_ASSOC)) {
$res .= $modx->getChunk('modx', $row);
}
}
echo number_format(microtime(true) - $modx->startTime, 4), 's
';
echo number_format(memory_get_usage() / 1048576, 4), 'mb
';
echo $res;
And for pdoTools:
getService('error','error.modError');
$modx->setLogLevel(modX::LOG_LEVEL_FATAL);
$modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');
$pdoTools = $modx->getService('pdoTools');
$res = array();
$c = $modx->newQuery('modResource');
$c->select($modx->getSelectColumns('modResource'));
$c->limit(10);
if ($c->prepare() && $c->stmt->execute()) {
while ($row = $c->stmt->fetch(PDO::FETCH_ASSOC)) {
$res .= $pdoTools->getChunk('fenom', $row);
//$res .= $pdoTools->getChunk('modx', $row);
}
}
echo number_format(microtime(true) - $modx->startTime, 4), 's
';
echo number_format(memory_get_usage() / 1048576, 4), 'mb
';
echo $res;
Since pdoTools understands both syntaxes, there are 2 tests for it - in MODX tag mode, and in Fenom mode.
In the scripts there is an indication of limit = 10, then in the table I give the numbers with its increase:
Limit | MODX | pdoTools (MODX) | pdoTools (Fenom) |
10 | 0.0369s 8.1973mb | 0.0136s 7.6760mb | 0.0343s 8.6503mb |
100 | 0.0805s 8.1996mb | 0.0501s 7.6783mb | 0.0489s 8.6525mb |
500 | 0.2498s 8.2101mb | 0.0852s 7.6888mb | 0.0573s 8.6630mb |
1000 | 0.4961s 8.2232mb | 0.1583s 7.7019mb | 0.0953s 8.6761mb |
And now, let's complicate the chunks a bit - add the link generation for the resource and the output
menutitle
:
and
Limit | MODX | pdoTools (MODX) | pdoTools (Fenom) |
10 | 0.0592s 8.2010mb | 0.0165s 7.8505mb | 0.0346s 8.6539mb |
100 | 0.1936s 8.2058mb | 0.0793s 7.8553mb | 0.0483s 8.6588mb |
500 | 0.3313s 8.2281mb | 0.2465s 7.8776mb | 0.0686s 8.6811mb |
1000 | 0.6073s 8.2560mb | 0.4733s 7.9055mb | 0.1047s 8.7090mb |
As you can see, processing chunks via pdoTools is faster in all cases.
It is also noticeable that Fenom chunks have a certain minimum for starting, which is due to the need to compile the template.
Conclusion
Let's summarize the pdoTools parser features:
- Quick work
- Download chunks from various sources, including files
- FastField tag support
- Fenom Template Engine Support
- Template Inheritance
- Template Extension
- Secure access to advanced MODX features
At the moment, pdoTools has been downloaded more than 40,000 times from the official repository and more than 10,000 from the modstore.pro repository , which allows us to hope for the wide spread of new template technologies in MODX.
Many thanks to aco habrayuzer for a wonderful template engine!