news.detail

Детальная страница новости или статьи. Здесь же живёт основная работа с SEO.

Что добавить

result_modifier.php шаблона:

use mrLexndr\Translate\IblockHelper;

IblockHelper::substituteStandardFields($arResult);
IblockHelper::substituteSeo($arResult);

Порядок важен. substituteSeo() читает уже подставленные поля: макрос {=this.name} должен подставить переведённое название, а не исходное. Поменяете строки местами — получите перевод текста с русскими мета-тегами.

Что делает substituteSeo

Переписывает оба ключа — IPROPERTY_VALUES и META_TAGS. Это не перестраховка: news.detail собирает второй из первого ещё до шаблона, и подстановка только в один из них ничего не изменит.

Заодно подставляются alt и title картинок: компонент кладёт их туда же.

Почему без этого вызова не обойтись

Ядро Битрикса считает мета-теги по базовому шаблону и кладёт результат в кеш без привязки к языку. Переведённый шаблон оно не увидит никогда — не потому, что перевод плохой, а потому что ядро о нём не спрашивает.

Значения на языке считает модуль, и происходит это в момент вызова хелпера.

Подробнее про хранилище шаблонов и очередь — Как это устроено внутри.

Что нужно, чтобы SEO переводилось

  1. Шаблоны переведены — SEO-шаблоны на языке;
  2. Переводятся только собственные шаблоны сущности. Унаследованные от раздела или инфоблока наследуются на языке так же, как в ядре, — переводить их надо там, где они заданы;
  3. Макросы вида {=this.name} должны вернуться из перевода целыми. Если модель их потеряла, перевод не записывается, а в журнале появляется отметка.

Отдельно: {=iblock.name} тоже подставляет переведённое название — у инфоблока перевод живёт в словаре, а не в поле ядра. А {=sections.*} остаётся базовым: цепочка разделов у ядра своя.

Предпросмотр в админке показывает русский

Это не ошибка. Предпросмотр на SEO-вкладке считает базовые значения, а не перевод. Проверять результат надо на самой странице.