MODx/Подключаемые плагины/PHx
Материал из Викиучебника
Содержание |
[править] Введение
PHx (Placeholders Xtended) добавляет новые возможности для отображения плейсхолдеров, тегов MODx (включая TV параметры) и теги настроек сайта. Рекурсивный парсер позволяет использовать вложенные теги. Возможно создавать свои модификаторы, путем создания сниппетов.
[править] Загрузка
Скачать последнюю версию PHx из репозитория MODx можно по этой ссылке. Текущая версия 2.1.3
[править] Установка
[править] Новая установка
- Скачайте и распакуйте архив.
- Создайте директорию "phx" в папке /assets/plugins.
- Закачайте через FTP или просто скопируйте содержимое архива в /assets/plugins/phx
- Создайте новый плагин "PHx" в Панели управления MODx (Элементы-Управление элементами-Плагины) и скопируйте в него содержимое файла phx.plugin.txt
- Отметьте событие "OnParseDocument" на вкладке "Системные события"
[править] Обновление
- Скачайте и распакуйте архив.
- Переименуйте директорию /assets/snippets/phx в /assets/snippets/phx-old
- Создайте директорию "phx" в папке /assets/plugins.
- Закачайте через FTP или просто скопируйте содержимое архива в /assets/plugins/phx
- Создайте новый плагин "PHx" в Панели управления MODx (Элементы-Управление элементами-Плагины) и скопируйте в него содержимое файла phx.plugin.txt
- Отметьте событие "OnParseDocument" на вкладке "Системные события"
[править] Настройка
На вкладке конфигурация, во время редактирования плагина скопируйте в поле "Конфигурация плагина":
[pseudocode,N]&phxdebug=Лог событий;int;0 &phxmaxpass=Макс. число проходов;int;50
[править] Для опытных пользователей
Вы можете изменить настройки по умолчанию для плагина PHx:
- Лог событий
- 0 = Отключен
- 1 = Включено логирование событий PHx
- Если включено PHx создает подробный лог на каждое событие, записанное в протоколе событий ( Отчеты->Просмотр событий)
- Макс. число проходов
- Определяет максимально обрабатываемую глубину вложенных тегов. Рекомендуется оставить значение 50.
[править] Описание
PHx (Placeholders Xtended) расширяет возможности использования плейсхолдеров, тегов содержимого (включая TV параметры) и тегов настройки сайта. Благодаря этому вы можете с легкостью определять формат вывода конечного результата. PHx встраиваится в парсер MODx, расширяя его функционал модификаторами, условиями и в качестве бонуса делает его по-настоящему рекурсивным. PHx will also eliminate the need for lesser parameter snippets where you'd use them to format a value for display.
Великолепно для шаблонов!
Преобразовать значение также просто, как добавить :modifier.
[править] Поддерживаемые теги
PHx поддерживает следующие теги MODx:
- [+placeholder+]
- [*теги содержимого*] ([*content*], [*pagetitle*], например)
- [*TV параметры*]
- [(теги настройки)] (например, [(base_url)], [(site_name)] и другие)
[править] Сниппеты, поддерживающие PHx
- Ditto
- Jot
- MaxiGallery
Вы можете использовать PHx синтаксис в чанках, используемых сниппетами не из этого списка, но для этого требуется другой метод (см. раздел Tips & Tricks)
[править] Использование
Обычный плейсхолдер вида [+placeholder+] легко превращается в плейсхолдер PHx: [+placeholder:esc+]. Тоже самое вы можете сделать с тегом содержимого:
[*createdby*]
Добавляем модификатор:
[*createdby:date=`%a %B %d, %Y at %H:%M`*]
Также можно использовать несколько модификаторов сразу. Они будут обработаны слева направо:
somevar:esc:nl2br:strip
[править] Расширенное применение
Наличие специального плейсхолдера "phx" позволяет использовать синтаксис PHx без наличия реальной переменной.
[+phx:if=`[+this+]`:is=`[+that+]`:then=`do this`:else=`do that`+]
С некоторыми модифиакторами этот плейсхолдер приобретает определенное значение. В случае с модификатором "userinfo" он соответствующее значение:
[+phx:userinfo=`username`+]
[править] Известные проблемы
[править] Синтаксис
Это кажется логичным, но на этом стоит заострить внимание. Избегайте использования следующих конструкций в шаблоне, если они не являются частью тега MODx:
[+ [* [( +] *] )] ]]
Парсер попытается их обработать и MODx выдаст ошибку. Обычно такой проблемы не возникает. Но в случае с JavaScript у вас может быть конструкция, похожая на эту:
array[counter++]
... которая спровоцирует странное поведени из-за +]. Также закрывающий тег CDATA:
/* ]]> */
... может создать проблемы.
Помните, что вы не сможете потерять данные вашего сайта, используя неправильный синтаксис PHx. Худшее, что может случится - ваш шаблон неправильно отобразится.
[править] Модификаторы
[править] Строки
[править] lcase
Возвращает строку, приведенную к нижнему регистру.
- Example:
[pseudocode,N][+string:lcase+]
- Input:
[pseudocode,N]Это СтроКа - Returns:
[pseudocode,N]это строка
[править] ucase
Приведет все символы строки к верхнему регистру.
- Example:
[pseudocode,N][+string:ucase+]
- Input:
[pseudocode,N]This is a string - Returns:
[pseudocode,N]THIS IS A STRING
[править] ucfirst
Первая буква в строке станет заглавной.
- Example:
[pseudocode,N][+string:ucfirst+]
- Input:
[pseudocode,N]иванов - Returns:
[pseudocode,N]Иванов
[править] length | len
Возвратит длину строки.
- Example:
[pseudocode,N][+string:len+]
- Input:
[pseudocode,N]this is a string - Returns:
[pseudocode,N]16
[править] notags
Вырежет все HTML теги из строки.
- Example:
[pseudocode,N][+string:notags+]
- Input:
[pseudocode,N]this is a string - Returns:
[pseudocode,N]this is a string
[править] esc
Удаляет html теги и разрывы строк
[править] htmlent
Конвертирует исходную переменную в html сущности. Аналог htmlentities() в PHP.
[править] nl2br
Конвертирует символы перевода строки в теги.
- Example:
[pseudocode,N][+string:nl2br+]
- Input:
[pseudocode]
this is a string
- Returns:
[pseudocode,N]this is
a string
[править] strip
Удалит символы новой строки(\n), табуляторы(\t), идущие подряд пробелы.
- Example:
[pseudocode,N][+string:strip+]
- Input:
[pseudocode]
this is
a
string
- Returns:
[pseudocode,N]this is a string
[править] Другие модификаторы
- reverse
- Перевернет задом наоборот буквы.
- wordwrap(=`length`)
- length - characters
- Breaks words in the current value longer than the given length of characters by putting a space in between.
- Default: 70 characters.
- limit(=`length`)
- Returns the first X characters from the current value.
- Default: 100 characters.
[править] Специальные
[править] date(=`dateformat`)
- dateformat: Like PHP strftime
- Converts unix timestamps to the format specified.
Example:
[*createdon:date=`%d.%m.%Y`*]
To change the output of date according to the language of the website, insert setlocale at the beginning of the PHx-plugin (this is an example for German language):
setlocale(LC_ALL, 'de_DE@euro', 'de_DE', 'de', 'ge');
[править] md5
- Creates a MD5 hash from the current value.
[править] userinfo=`field`
- field: Similar to the fields used in the database. Like: username, useremail
Formats a userid value (webuser have negative ids) to a field specified.
[править] math=`calculation`
- Use simple calculations like - * + /.
- The "?" character is replaced by the current value of the extension but you can also use nested tags.
- Example calculation: ?+1+(2+3)+4/5*6
[править] ifempty=`other value`
- Use "other value" when the output of the placeholder/templatevar is empty.
[править] select=`options`
Translates the value of placeholder/templatevar to a specified output.
- options like: value1=output1&value2=output2
Example:
- Input: 1
[pseudocode,N][+placeholder:select=`0=OFF&1=ON&2=UNKNOWN`+]
- Returns ON
[править] Условные выражения
[править] is
- alias: eq
равно (==)
[править] ne
- alias: isnot, isnt
не равно (!=)
[править] eg
- alias: isgt
больше или равно (>=)
[править] el
- alias: islt
меньше или равно (<=)
[править] gt
больше (>)
[править] lt
меньше (<)
[править] mo=`Webgroups`
- aliases: isinrole, ir, memberof
Takes a comma-separated list of webgroup names and returns true/false depending on the user being in the group or not (replaces the "inrole" modifier which had to be combined with a conditional operator).
- Example:
[+phx:mo=`myWebgroup`:then=`I'm a member`:else=`I'm NOT a member`+]
[править] if =`value`
Takes a new value. Will normally be used before :or or :and
[править] or
Previous OR next statement
[+phx:if=`[*id*]`:is=`2`:or:is=`3`:then=`{ {Chunk} }`:else=`{ {OtherChunk} }`+]
[править] and
Previous AND next statement
[+phx:if=`[!UltimateParent!]`:is=`1`:and:isnot=`[*id*]`:then=`{ {ChildChunk} }`:else=`{ {ParentChunk} }`+]
[править] then =`template`
template : This is shown if conditions are true. Template can be a { {chunk} }, [ [ snippet] ] or just plain html.
[править] else =`template
template : This is shown if conditions are false. Template can be a { {chunk} }, [ [ snippet] ] or just plain html.
[править] show
Similar to then except that it uses the original input as 'template' when the condition is true.
[pseudocode,N][+myplaceholder:len:gt=`3`:show+]
- Will return the value of myplaceholder if it contains more then 3 characters.
[править] More examples
[править] Example 1
myplaceholder is set to myvalue
- [+myplaceholder:is=`myvalue`:then=`Correct`:else=`Incorrect`+]
- will return: Correct
- [+myplaceholder:isnot=`myvalue`:then=`Correct`:else=`Incorrect`+]
- [+myplaceholder:is=`othervalue`:then=`Correct`:else=`Incorrect`+]
- will both return: Incorrect
[править] Example 2
- myplaceholder is set to 2
- someplaceholder is set to 3
- otherplaceholder is set to 1
[html] [+myplaceholder:is=`2`:then=` Шаблон:ChunkGood `:else=` Шаблон:ChunkBad `+]
Will display the contents of chunk called ChunkGood.
[+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`+]
Will all return 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`+]
Will all return No.
[править] Custom modifiers
A modifier is in fact a replacement for a simple snippet to process a given value to anything you like. It's possible to create your own custom modifiers/mini-snippets by adding a new snippet into the MODx resource manager.
Because a modifier doesn't hold complicated code you don't need parameters other than what a modifier in PHx gets from the parser. There are two main variables:
- $output
- the current value of the variable that is getting "modified"
- $options
- (optional) an optionial string that a modifier could have
To bring this into perspective here are some short examples assuming myplaceholder is set to "test":
[+myplaceholder:mymodifier+]
- $output contains the value "test".
- $options contains nothing because they aren't specified.
[+myplaceholder:mymodifier=`my options`+]
- $output still contains the value "test".
- $options contains the value "my options".
Other variables (advanced users)
- $input contains the original input (starting value).
- $condition an array containing the elements that make up a conditional statement (0, 1, || and &&).
[править] Creating a custom modifier
[править] Example: I love MODx
With this knowledge we are going to create a new custom modifier. In this example I want to create a modifier (without options) that adds the string " because I love MODx" to a variable.
- Login to the MODx manager
- Go to Resources -> Manage Resources -> Snippets
- Click "new snippet"
- For the snippet name we enter "'phx:love'"
- For PHx to know about the custom modifier all snippets created for PHx should be prefixed with "phx:" the string (containing NO spaces) after the prefix will be the actual modifier name. In this case our modifier will be triggered by adding :love to the placeholder like [+myplaceholder:love+].
- Now we are going to enter the modifier code into the snippet code field. For this example we create it like this:
[php]
<?php $newvalue = $output. " because I love MODx"; return $newvalue; ?>
- Click "Save" and your custom modifier (:love) is ready for use!
[править] Example: I love MODx even more
Similar to example 1 we are now going to create a modifier that will do the same BUT if there are options specified it will take the options value as the string to append.
- Login to the MODx manager
- Go to Resources -> Manage Resources -> Snippets
- Click "new snippet"
- For the snippet name we enter "phx:love2"
- For PHx to know about the custom modifier all snippets created for PHx should be prefixed with "phx:" the string (containing NO spaces) after the prefix will be the actual modifier name. In this case our modifier will be triggered by adding :love to the placeholder like [+myplaceholder:love2+].
- Now we are going to enter the modifier code into the snippet code field. For this example we create it like this:
[php]
<?php $defaultValue = " because I do love MODx"; if (strlen($options)>0) {
$newvalue = $output . $options;
} else {
$newvalue = $output . $defaultValue;
} return $newvalue; ?>
- Click "Save" and your custom modifier (:love2) is ready for use!
[править] Contributed
Check PHx/CustomModifiers for a list of custom modifiers you can install.
[править] Tips and Tricks
[править] Using PHx in non-phx snippet templates
Most snippets render their templates "locally" before they are passed to MODx. Unless the snippet's description states it's using PHx to render the templates it's not possible to use the modifiers directly, however you still CAN use PHx by using a special modifier called phx:input.
This example will not work with a non-PHx snippet:
[+myplaceholder:modifier1:modifier2+]
Try this method instead:
[+phx:input=`[+myplaceholder+]`:modifier1:modifier2+]
Or:
[*phx:input=`[+myplaceholder+]`:modifier1:modifier2*]
This example will work with a non-PHx snippet. Some restrictions may apply depending on the snippet logic.
[править] Technical Documentation
Эта часть не интересна большинству пользователей. Но здесь раскрываются секреты работы PHx.
PHx запускается при наступлении события OnParseDocument. OnParseDocument вызывается до того, как стандартные теги MODx будут обработы, поэтому PHx обрабатывает чистый (сырой) шаблон.
Этапы работы
- Начинаем если не превышено максимальное количество проходов.
- Сохраняем хэш текущего содержимого, чтобы обнаружить изменения после обработки.
- С помощью специальных фильтров избавляемся от ненужных символов (которые не являются частью тегов MODx).
- Содержимое документа попадает в основную функцию:
- A hash is made of the current content of the document to check for changes in the process later on.
- Chunks are merged using mergeChunkContent (MODx API).
- Snippets are detected using an advanced regular expression that takes nested tags into account:
- Snippet calls which contain no nested tags are matched.
- Each matching call is checked for (non-)cached output, prepared and passed to evalSnippets (MODx API).
- Snippet output is merged with the document.
- The rest of the MODx tags are detected using an advanced regular expression that takes nested tags into account:
- Document/Template Variable output is gathered from mergeDocumentContent (MODx API).
- Setting Variables output is gathered from mergeSettingsContent (MODx API).
- Placeholder output is gathered in the following order PHx, MODx.
- If the requested placeholder is not set it is skipped for the current pass (replaced with original).
- For each detected tag, the ones which also contains modifiers are passed to the filter that will modify the value as given.
- The final output for all tags is then merged into the document.
- A hash is made of the content of the merged document and compared to the initial hash to check if there were changes.
- If we did not reach maximum passes AND if the document content has changed we repeat this entire level (pass+1).
- The document's rogue bracket characters are restored to their non-escaped versions.
- The tags that are still present (and thus unresolved for the entire document) are removed from the output.
- A hash is made of the new document content and compared to the initial hash to check if there were changes.
- If the document content has changed let it repeat this entire level.
- Log the parser steps into the Event Log if required.
- Return the new documentOutput to MODx.
After the entire PHx logic is through, it's 99% certain that MODx does not have any tags left to parse. You could say that PHx replaces the core function of MODx that handles the merging (with added flexibility by allowing nesting). However, the different types of elements are still processed by the responsible MODx functions.