Перейти к содержимому

Различия сервера и браузера

Один и тот же шаблон в PageCraft выполняется дважды разными движками:

Предпросмотр в редакторе Публикация страницы
Движок LiquidJS (JavaScript) keepsuit/liquid (PHP)
Где считается в вашем браузере на сервере PageCraft
Когда на каждое нажатие клавиши при публикации

Так сделано ради отзывчивости редактора: ходить на сервер за каждым символом нельзя, а отдавать витрине результат из браузера — тем более. Цена — расхождения. Все они проявляются одинаково неприятно: в редакторе выглядело иначе, чем на сайте, без единой ошибки.

Ниже — полный список расхождений, которые ловятся на практике. Держитесь общего подмножества, и предпросмотр будет честным.

LiquidJS богаче: у него есть фильтры, которых в серверном движке не существует. Незнакомый фильтр сервер не считает ошибкой — он возвращает значение без преобразования.

{{ props.title | slugify }}
Результат
Предпросмотр hello-world
Опубликованная страница Hello World

Фильтры, работающие только в предпросмотре:

array_to_sentence_string · base64_decode · base64_encode · cgi_escape · date_to_long_string · date_to_rfc822 · date_to_string · date_to_xmlschema · find_exp · find_index_exp · group_by · group_by_exp · has_exp · inspect · json · jsonify · normalize_whitespace · number_of_words · pop · push · raw · reject_exp · sample · shift · slugify · to_integer · unshift · uri_escape · where_exp · xml_escape

Обратного списка нет: фильтров, которые есть на сервере и отсутствуют в браузере, не существует. Безопасный набор из 55 фильтров — в Liquid: основы.

Тег Предпросмотр Публикация
assign capture if unless case for tablerow cycle increment decrement raw comment echo liquid работает работает
{% ifchanged %} ошибка работает
{% doc %} ошибка работает
{% include %} {% render %} {% layout %} {% block %} ошибка ошибка

Практический вывод: ifchanged и doc в шаблоне блока не используйте — предпросмотр на них ломается целиком. Подключение внешних шаблонов не работает нигде.

В шаблоне блока это синтаксическая ошибка везде — и в браузере, и на сервере.

В шаблоне макета сервер перед рендерингом молча переписывает ||or, &&and, а {{ a || b }}{{ a | default: b }}. В предпросмотре макета такой замены нет.

Где написан || Предпросмотр Публикация
Шаблон блока ошибка ошибка
Шаблон макета ошибка работает

Пишите or, and и default: — они ведут себя одинаково во всех четырёх клетках.

{% if props.title == blank %}пусто{% endif %}

В браузере условие истинно для пустой строки, на сервере blank не существует и условие всегда ложно. Сравнивайте с пустой строкой: props.title == ''.

Markdown-блок конвертируется двумя разными библиотеками, и синтаксис GitHub-стиля поддерживает только браузерная. Полная таблица и что с этим делать — Markdown в блоках.

Мелочь, о которую спотыкаются CSS-селекторы вроде td + td: {% tablerow %} на сервере ставит переносы строк между ячейками, в браузере — нет. Если вёрстка зависит от отсутствия пробельных узлов, не полагайтесь на предпросмотр.

7. Блоки с живыми данными вообще не рендерятся на сервере

Заголовок раздела «7. Блоки с живыми данными вообще не рендерятся на сервере»

Блок, объявивший bindingSlots, PageCraft при публикации не выполняет: на витрину уезжает исходный шаблон, а данные подставляет магазин своим движком Liquid — уже третьим. В редакторе слоты заполнены заглушкой типа результата.

Значит, у такого блока предпросмотр не проверяет ни фильтры, ни теги на реальном движке витрины, а данные в нём всегда «идеальные»: без пустых списков, длинных названий и отсутствующих картинок. Проверяйте шаблон на краевых случаях руками — пустой список, одна позиция, очень длинная строка.

Старый тип блока html Liquid не использует вовсе: в нём {{ ключ }} заменяется простой текстовой подстановкой, и правила этой страницы к нему не относятся. Новые блоки делайте типа «schema» или «markdown».

  1. Ограничьтесь общим набором фильтров и тегов.
  2. Никаких ||, &&, blank — только or, and, default:, == ''.
  3. После первой публикации посмотрите на страницу на витрине, а не только в предпросмотр.
  4. Блока не видно на опубликованной странице — ищите в её исходном коде <!-- Liquid render error: … -->: ошибка шаблона блока не отменяет публикацию и никак не сигнализируется.
  5. Ошибка в шаблоне макета, наоборот, останавливает публикацию с текстом ошибки — тут молчания не будет.

Источники: backend/src/Publishing/BlockRenderer.php, backend/src/Publishing/LayoutRenderer.php (normalizeOperators), backend/src/Publishing/BlockAssembler.php, front/src/lib/liquid.ts, front/src/lib/placeholder.ts, front/src/components/PageEditor/PageEditor.tsx, keepsuit/liquid 0.9 против liquidjs 10.25 — списки фильтров и тегов сверены прогоном обоих движков.