• Блог
  • Почему не работает тег ignore

Это достаточно частый вопрос. И даже мне из-за этого приходилось переделывать вёрстку. Ответ в понимании механизма парсинга. В предыдущей статье я уже описывал последовательность подготовки ответа пользователю. Давайте её вспомним. Сначала MODX получает контент шаблона и передаёт его парсеру (мы говорим о pdoParser). Если шаблона нет, то берётся контент ресурса. Далее:

  1. Парсер обрабатывает кэшируемые элементы в контенте, если ресурс не из кэша. На этом этапе Fenom не работает.
  2. Парсятся некэшируемые элементы. Нераспарсенные не удаляются. Здесь Fenom уже запускается, причём обрабатывает контент до парсера MODX. Т.е. сначала обработаются теги Fenom, а только потом теги MODX. При условии, что включена настройка обработки тегов Fenom на страницах.
  3. Парсятся некэшируемые элементы. Нераспарсенные удаляются. Fenom работает как на предыдущем шаге.

На каждом этапе MODX парсит контент на глубину до 10-го уровня. Т.е. распарсил тег, и если результат содержит ещё теги MODX, то запускается новый цикл парсинга. И так 10 раз.

Теперь давайте возьмём пример из первой ссылки. В шаблоне пишем теги Fenom:

# Блок кода №1
<!doctype html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    {$_modx->resource.content}
    {ignore}
    <input pattern="\+7\s\(\d{3}\)\s\d{3}-\d{2}-\d{2}"/>
    {/ignore}
</body>
</html>

И в ресурсе тоже вызываем сниппет через Fenom:

# Блок код №2
{$_modx->runSnippet('!pdoMenu', [
	'parents'    => $_modx->resource.id
	,'level'     => 1
	,'showHidden'=> 1
])}

Теперь посмотрим как это будет парсится по шагам.

Шаг 1. Обработка кэшируемых элементов

На этом шаге в парсер попадет контент шаблона (см. код выше). Теги Fenom на этом этапе не парсятся. MODX ищет кэшируемые теги. Таких, как мы видим, нет. Обработка закончена.

Шаг 2. Обработка некэшируемых элементов без удаления нераспарсенных тегов

На этом этапе Fenom уже запускается (только если есть теги Fenom). Он получает первоначальный контент и парсит его. Результат будет такой:

# Блок кода №3
<!doctype html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    {$_modx->runSnippet('!pdoMenu', [
        'parents'    => $_modx->resource.id
        ,'level'     => 1
        ,'showHidden'=> 1
    ])}
    <input pattern="\+7\s\(\d{3}\)\s\d{3}-\d{2}-\d{2}"/>
</body>
</html>

Тег {$_modx->resource.content} заменён на контент ресурса, а тег {ignore} исчез. Но он исчез не по ошибке, он отработал согласно указанной ему задаче — вернул завёрнутый в него код без обработки. Дальше запускается парсер MODX и ищет стандартные некэшируемые теги со знаком !. Их в контенте нет, поэтому обработка завершается.

Шаг 3. Обработка некэшируемых элементов с удалением нераспарсенных тегов

Вот теперь самое интересное. На этом шаге в контенте всё ещё присутствуют теги Fenom. Поэтому он, имея полное право, парсит их. А своими тегами Fenom считает всё, что обернуто фигурными скобками, но за одним исключением (и это исключение добавил Василий) — теги должны начинаться с $, ', (, строки с пробела (вот тут я об этом писал). А так как тега {ignore} уже нет, то Fenom обрабатывает все фигурные скобки и в том числе {3}.

Примечание

Если в контенте есть только теги типа {3}, Fenom их пропускает, так как они не подходят под регулярку (если только вы не правили её, удалив, например, \s). Он просто не запустится. Но если на странице есть правильные теги, то он обработает все фигурные скобки без исключений. Т.е. вместе с «правильными» тегами Fenom обработает и те, которые изначально игнорирует.

Надеюсь, теперь понятно, почему «не работает» тег {ignore}. Теперь давайте рассмотрим вариант решения.

Вариант 1

Самый просто вариант — указать в шаблоне кэшируемый тег [[*content]] вместо {$_modx->resource.content}:

# Блок кода №4
<!doctype html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    [[*content]]
    {ignore}
    <input pattern="\+7\s\(\d{3}\)\s\d{3}-\d{2}-\d{2}"/>
    {/ignore}
</body>
</html>

Тогда MODX уже на первом шаге подготовит для Fenom такой контент:

# Блок кода №5
<!doctype html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    {$_modx->runSnippet('!pdoMenu', [
        'parents'    => $_modx->resource.id
        ,'level'     => 1
        ,'showHidden'=> 1
    ])}
    {ignore}
    <input pattern="\+7\s\(\d{3}\)\s\d{3}-\d{2}-\d{2}"/>
    {/ignore}
</body>
</html>

Здесь уже и контент ресурса и тег {ignore}. Fenom его учтёт и вернёт уже такой результат (это второй шаг):

# Блок кода №6
<!doctype html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    ... Результат работы сниппета ...
    <input pattern="\+7\s\(\d{3}\)\s\d{3}-\d{2}-\d{2}"/>
</body>
</html>

На третьем шаге Fenom пропустит этот контент, так как теги {цифра} не соответствуют регулярному выражению (если вы его не правили).

В итоге вы получите ожидаемый результат.

Вариант 2

Перенести блок с тегом {ignore} в ресурс. Тогда Fenom только на третьем (последнем) шаге получит контент из блока кода №5 и Fenom пропустит всё что указанно в {ignore}.

Заключение

В общем идея должна быть понятна — тег {ignore} должен присутствовать в итерации, после которой больше не будет тегов Fenom. К сожалению, добиться этого не всегда получается. Специфика MODX.

Update 07.12.2017

В новой версии pdoTools эта проблема устранена. Решение простое — содержимое тега {ignore} перед запуском парсера вырезается и возвращается обратно перед выводом ответа пользователю. Правда, как выяснилось, не работает если код шаблона или чанка находится в файле.

0   2644

Комментарии ()

  1. shock 15 февраля 2018, 19:20 # 0
    Добрый день!
    Спасибо за ваш труд, Сергей!
    Подскажите как вы экранируете тег
    {/ignore}
    в подсветке кода?
    Дело в том, что если код помещать в
    {ignore}{/ignore}
    , наличие второго
    {/ignore}
    приводит к ошибке.
    Буду очень признателен за подсказку.
    1. Сергей Шлоков 15 февраля 2018, 20:48 # 0
      Здравствуйте!
      Просто я использую Tickets. Он сам всё экранирует. Для самостоятельного экранирования используйте мнемоники. Коды 123 и 125 соответственно вместо скобок.
      1. shock 15 февраля 2018, 21:14 # 0
        Спасибо, понял.
        В Tickets случайно не jevix этим занимается?
        1. Сергей Шлоков 15 февраля 2018, 21:17 # 0
          Он самый.
    2. Vladimir 02 апреля 2019, 18:08 # 0
      В pdoTools ни когда не было (давно?) в системных настройках вынесено регулярное выражение, которое можно было там же и редактировать? Ну что бы, например, вот такое
      {"el": ".swiper-pagination"}
      или, особенно двойные фигурные скобки
      {{firstName}}
      не рушили бы работу фенома…?
      1. Сергей Шлоков 02 апреля 2019, 18:28 # 0
        Я про такое не слышал. А ignore не помогает?
        1. Vladimir 02 апреля 2019, 18:33 # 0
          ignore помогает, просто {" (как первые символы вместе) и {{ не используются для фенома, а ошибки вызывают, если в ignore не убрать
          1. Сергей Шлоков 02 апреля 2019, 19:31 # 0
            Только свой парсер писать.
      2. Кирилл 09 мая 2019, 14:28 # 0
        У меня не работает {ignore}
        Использую шаблон с таким кодом
        <!DOCTYPE html>
        <html class="no-js" lang="ru" dir="ltr">
            
            {include 'templates.default.head'}
        <body>
            <div class="page">
              <div class="page__center">
                {include 'templates.default.header'}
                <div class="page__content">
                {include 'templates.default.content-home'}
                </div>
              </div>
              {include 'templates.default.bottom-navigation'}  
              {include 'templates.default.preloader'}
              {include 'templates.default.form'}
            </div>
            {include 'templates.default.script'}
        </body>
        </html>
        В head прописываю стандартные мета теги используя переменные fenom
        и инлайном вставляю js скрипт в {ignore}{/ignore}, но почему то весь сайт падает(белый экран), если изменить вызов
        {include 'templates.default.head'}
        на
        [[$templates.default.head]]
        то ignore правильно обрабатывается(вырезается)

        pdoTools 2.12.3, modx 2.7.1

        Вы должны авторизоваться, чтобы оставлять комментарии.

        Выделите опечатку и нажмите Ctrl + Enter, чтобы отправить сообщение об ошибке.