Вложенные теги, кэш и mosquito-условия
Последнее обновление not available | История страницы | Улучшить эту страницу | Сообщить о проблеме
Support the team building MODX with a monthly donation.
The budget raised through OpenCollective is transparent, including payouts, and any contributor can apply to be paid for their work on MODX.
Backers
Budget
$204 per month—let's make that $500!
Learn moreMODX разбирает вложенные теги изнутри наружу и по-разному обрабатывает кэшированные и некэшированные теги. Это удобно, когда TV вложен в свойство сниппета. Тем же объясняется, почему условие с полными тегами в обеих ветках может выполнить тяжёлый код, который вам не нужен.
Эта страница дополняет короткие заметки на Синтаксис тегов. Правила кэширования взяты из руководства Mark Hamstra и статьи о вложенном кэше. Паттерн «mosquito» описан в посте Jason Coward.
Порядок разбора (сначала кэш)¶
На каждом проходе парсер находит теги, выполняет их по приоритету, затем снова ищет теги в результате и повторяет цикл.
Типичный приоритет:
- Вложенный кэшированный тег
- Кэшированный тег
- Вложенный некэшированный тег
- Некэшированный тег
Важен и порядок в исходнике: тег раньше в шаблоне выполняется раньше тега с тем же приоритетом позже по тексту.
Некэшированные теги ждут, пока для этого прохода закончится кэшированная работа. Если ресурс кэшируемый, в кэш страницы пишется HTML с оставшимися некэшированными тегами. На следующих запросах снова выполняются только теги с !.
Пример с вложением¶
Фильтр TV со вложенными чанками:
[[*featured:is=`1`:then=`[[$chunkA]]`:else=`[[$chunkB]]`]]
Парсер сначала разбирает внутренние [[$chunkA]] и [[$chunkB]] (и всё внутри них) до оценки :is. После этого прохода можно увидеть что-то вроде:
[[*featured:is=`1`:then=`Title-[[!snippetA]]`:else=`Title-[[!snippetB]]`]]
Затем выполняется кэшированный TV/фильтр. В выводе остаётся одна ветка, но обе уже отработали. Некэшированный сниппет в выбранной ветке остаётся в файле кэша и крутится на каждом запросе.
Краткие правила кэша¶
| Ситуация | Предпочтительно |
|---|---|
| Меню, списки, статичные чанки, поля ресурса | Кэш (без !) |
| Login / профиль / вывод только для участника | Без кэша |
| Вывод от query string или POST | Без кэша |
| Сниппет, который только делает редирект | Без кэша |
| Внешние данные со своим сроком жизни | Свой кэш внутри сниппета |
Не снимайте кэш с Wayfinder или getResources только чтобы правки «сразу были видны». Сохранение контента очищает кэш.
Если некэшированный сниппет ставит плейсхолдеры, вызывайте эти плейсхолдеры тоже без кэша:
[[!Profile]]
Hello [[!+username]]
Почему условия «кусают» (mosquitoes)¶
Так выглядит аккуратно и часто плохо для производительности:
[[*id:is=`1`:then=`[[!FirstChildRedirect]]`:else=`[[$videoGallery]]`]]
Разбор идёт изнутри наружу, поэтому FirstChildRedirect и $videoGallery оба выполняются до решения :is. Редирект может сработать даже когда условие выбрало бы галерею.
Условия с полными тегами в :then / :else похожи на москитов: каждый вложенный тег «кусает», нужна эта ветка или нет.
Собирайте тег из результата условия¶
Возвращайте токены и имена тегов, а не готовые теги. Оберните всё выражение во внешние [[ ]], чтобы следующий проход парсера собрал настоящий тег:
[[[[*id:is=`1`:then=`!FirstChildRedirect`:else=`$videoGallery`]]]]
Порядок работы:
- Внешние скобки ждут.
- Внутренний
[[*id:is=...]]возвращает!FirstChildRedirectили$videoGallery. - С внешними скобками получается
[[!FirstChildRedirect]]или[[$videoGallery]]. - Выполняется только этот тег.
Сниппет без токена: если нужен без кэша, поставьте ! в возвращаемом имени (!FirstChildRedirect). У чанков остаётся $. Чтобы на другой ветке ничего не делать, верните токен комментария -: внешний тег станет [[-]] и будет пропущен.
Паттерн sidebox¶
Пример чанка sidebox от Jason:
<div class="sidebox">
<h1>[[+title]]</h1>
[[[[+element]][[+properties]]]]
</div>
Вызов (имя и свойства собирают следующий тег):
[[$sidebox?
&title=`[[getValue? &class=`modResource` &field=`menutitle` &where=`{"id":[[UltimateParent]]}`]]`
&element=`Wayfinder`
&properties=`@SidebarMenu? &startId=`[[UltimateParent]]` &level=`1``
]]
Плейсхолдеры только собирают имя элемента и строку свойств. Тяжёлый сниппет выполняется один раз на следующем проходе.
Практические проверки¶
- Ищите в шаблонах
:then=[[и:else=[[. Если ветки вызывают сниппеты или большие чанки, предпочтите mosquito-возврат. - Держите навигацию и getResources в кэше, пока разметка не станет по-настоящему персональной или зависящей от запроса.
- После смены вложенности посмотрите HTML страницы или Extra для отладки парсера и убедитесь, что неиспользуемые ветки не выполняются как сниппеты в логе.
См. также¶
- Синтаксис тегов
- Фильтры вывода / модификаторы
- Caching Guidelines for MODX Revolution (Mark Hamstra)
- Nested caching in MODX Revolution (Mark Hamstra)
- Tags as the Result or How Conditionals are like Mosquitoes (Jason Coward)
Support the team building MODX with a monthly donation.
The budget raised through OpenCollective is transparent, including payouts, and any contributor can apply to be paid for their work on MODX.
Backers
Budget
$204 per month—let's make that $500!
Learn more










