Jump to main content Jump to doc navigation

MODX разбирает вложенные теги изнутри наружу и по-разному обрабатывает кэшированные и некэшированные теги. Это удобно, когда TV вложен в свойство сниппета. Тем же объясняется, почему условие с полными тегами в обеих ветках может выполнить тяжёлый код, который вам не нужен.

Эта страница дополняет короткие заметки на Синтаксис тегов. Правила кэширования взяты из руководства Mark Hamstra и статьи о вложенном кэше. Паттерн «mosquito» описан в посте Jason Coward.

Порядок разбора (сначала кэш)

На каждом проходе парсер находит теги, выполняет их по приоритету, затем снова ищет теги в результате и повторяет цикл.

Типичный приоритет:

  1. Вложенный кэшированный тег
  2. Кэшированный тег
  3. Вложенный некэшированный тег
  4. Некэшированный тег

Важен и порядок в исходнике: тег раньше в шаблоне выполняется раньше тега с тем же приоритетом позже по тексту.

Некэшированные теги ждут, пока для этого прохода закончится кэшированная работа. Если ресурс кэшируемый, в кэш страницы пишется 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`]]]]

Порядок работы:

  1. Внешние скобки ждут.
  2. Внутренний [[*id:is=...]] возвращает !FirstChildRedirect или $videoGallery.
  3. С внешними скобками получается [[!FirstChildRedirect]] или [[$videoGallery]].
  4. Выполняется только этот тег.

Сниппет без токена: если нужен без кэша, поставьте ! в возвращаемом имени (!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``
]]

Плейсхолдеры только собирают имя элемента и строку свойств. Тяжёлый сниппет выполняется один раз на следующем проходе.

Практические проверки

  1. Ищите в шаблонах :then=[[и:else=[[. Если ветки вызывают сниппеты или большие чанки, предпочтите mosquito-возврат.
  2. Держите навигацию и getResources в кэше, пока разметка не станет по-настоящему персональной или зависящей от запроса.
  3. После смены вложенности посмотрите HTML страницы или Extra для отладки парсера и убедитесь, что неиспользуемые ветки не выполняются как сниппеты в логе.

См. также

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

  • modmore
  • STERC
  • Digital Penguin
  • Jens Wittmann – Gestaltung & Entwicklung
  • CrewMark
  • Fabian Christen
  • Sepia River Studios
  • Dannevang Digital
  • Alex
  • A. Moreno
  • Chris Fickling
  • Stéphane Jäggi
  • Murray Wood
  • Anton Tarasov
  • deJaya
  • JT Skaggs
  • Lefthandmedia
  • eydolan
  • Following Sea
  • Guido Gallenkamp
  • YJ
  • Raffy
  • Snow Creative
  • Nick Clark
  • Guest
  • Helen
  • krisznet
  • Yanni
  • Richard

Budget

$204 per month—let's make that $500!

Learn more