Важное при обновлении с 2.2.x
Обновление не требует пересохранения настроек и не ломает публичный API: все методы, существовавшие ранее, работают с прежними сигнатурами. Но вывод разметки изменится — все изменения в сторону валидности:
Появится поле inLanguage у WebSite, WebPage и статей — Раньше язык не выводился вообще
В хлебных крошках добавится последний пункт — текущая страница — Раньше он молча терялся
@id товара и статьи получат якорь #product / #article — Раньше @id товара совпадал с URL страницы
ИНН переедет из vatID в taxID, ОГРН — в identifier — По schema.org taxID — это и есть ИНН
publisher у WebSite исчезнет, если не заполнено название организации — Раньше ссылка вела на несуществующий узел
og:locale пропадёт для языков, где регион неизвестен — Раньше выводилось невалидное значение вида sv_SV
Товар без числовой цены останется без блока offers — Раньше в разметку уходил текст вместо числа
Что сделать после обновления:
Открыть любую страницу с ?microdata_debug=Y под администратором — новая панель покажет состояние графа и подскажет, чего не хватает.
Проверить блок «Базовый URL» в панели. Если сайт за обратным прокси и в разметке http:// — поставить base_scheme = https в настройках.
Зайти в настройки модуля хотя бы раз: там догоняется миграция настроек и регистрация кнопки в админ-панели для сайтов, обновлённых копированием файлов.
Прогнать одну товарную и одну новостную страницу через Google Rich Results Test.
Если сайт за обратным прокси и в разметке http:// — включить опцию «Сайт за обратным прокси» либо задать base_scheme = https.
Если логотип был в формате SVG — заменить на PNG или WebP.
2.7.0
Устранение замечаний аудита безопасности Маркетплейса.
Разметка больше не может закрыть тег <script>. JSON-LD кодируется с флагами JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT: < и > превращаются в \u003C / \u003E. Раньше значение с </script> — из свойства инфоблока, отзыва или выгрузки 1С — закрывало тег, и браузер исполнял остаток строки как JavaScript на публичной странице. Для поисковых роботов JSON остаётся валидным, URL по-прежнему читаемы.
Точка вставки страхуется отдельно: GraphRegistry::render() дополнительно заменяет </ на <\/.
Ответы FAQ чистятся выборочно. Новый Normalizer::safeHtml() оставляет разметку, разрешённую Google для acceptedAnswer.text (заголовки, списки, ссылки, выделение), и удаляет script, iframe, form, svg, событийные атрибуты on* и схемы javascript: / vbscript: / data:. Вопрос теперь всегда очищается от тегов.
Тело отзыва и название бренда нормализуются — Review::setBody() и HasBrand::setBrand() прогоняют текст через Normalizer::text(), как это давно делали setName() и setHeadline().
Заголовок Host больше не принимается без белого списка. Раньше при незаполненных настройках он использовался как есть, и запрос с чужим Host мог отравить кеш страницы разметкой с чужим доменом. Теперь хост принимается только при совпадении с доверенным источником; в их число добавлен SERVER_NAME из конфигурации веб-сервера, чтобы типовые сайты не остались без разметки.
Заголовки прокси — только по явной настройке. X-Forwarded-Proto и X-Forwarded-Ssl присылает клиент, и без прокси их может подделать кто угодно, навязав http:// в канонических ссылках. Появилась опция «Сайт за обратным прокси», по умолчанию выключенная.
SVG исключён из форматов логотипа. Такой файл исполняет вложенный скрипт при открытии по прямой ссылке из /upload/. Для Organization.logo Google и так требует растр.
Дебаг-панель предупреждает, если базовый URL не определён и разметка поэтому не выводится.
2.6.2
Предрелизный аудит. Исправлены ошибки, часть из которых существовала с ранних версий.
Некорректная UTF-8 в данных инфоблока больше не приводит к потере текста. Раньше очистка строки возвращала пустое значение и писала deprecation в лог PHP: название и описание товара исчезали из разметки целиком. Битые байты типичны для выгрузок 1С и импортов.
Цена проверяется на числовой формат. Нечисловое значение больше не попадает в offers.price — такой товар выводится без блока offers. Отформатированные строки вида 1 990,00 разбираются в число. Обычные числовые цены не изменились.
Убрана висячая ссылка: WebSite.publisher указывал на организацию даже тогда, когда сама организация в граф не добавлялась (не заполнено название).
Дебаг-панель больше не пишет в журнал событий. Раньше каждое открытие панели дублировало предупреждения валидатора в b_event_log.
Устранена коллизия идентификаторов автора: автор с именем «123» получал тот же @id, что и пользователь с ID 123.
Идентификатор автора больше не зависит от наличия расширения mbstring на сервере.
Нераспознанный автор (например, ID несуществующего пользователя) больше не порождает пустой узел Person в разметке.
Параметр ?microdata_debug, переданный массивом, не вызывает предупреждение PHP.
2.6.1
Мультиязычность.
Поле inLanguage больше не достраивает регион самостоятельно. Раньше запасной вариант давал невалидные теги для многих языков: sv-SV вместо sv-SE, cs-CS вместо cs-CZ, da-DA вместо da-DK. По BCP 47 голое de — валидный тег, а угаданный регион был бы неверным для австрийского или швейцарского сайта.
Новая опция «Язык контента» (language_tag) — задаёт тег явно: ru-RU, en-GB, de-AT, zh-Hans-CN. Хранится отдельно для каждого сайта, что и нужно мультиязычному порталу.
Нормализация языковых тегов: pt_br → pt-BR, EN-gb → en-GB, поддержка письменности и макрорегионов (zh-Hans-CN, es-419).
Идентификаторы языков Битрикса, которые на самом деле коды стран, переводятся корректно: ua → uk-UA, by → be-BY, kz → kk-KZ, br → pt-BR, la → es-419.
og:locale вынесен в отдельную логику: там регион обязателен по спецификации Open Graph, поэтому подставляется по таблице из 50 языков. Если язык неизвестен, тег не выводится вовсе — это лучше невалидного значения.
2.6.0
Связывание сущностей, авторы, классификация, диагностика.
Связывание организации. Поле «Профили и справочники (sameAs)» дополнено, добавлено поле «Темы компании» (knowsAbout). Позволяет привязать сайт к карточке в Wikidata и статье в Википедии, чтобы поисковик понимал, о какой именно компании речь. Пошаговая инструкция — в руководстве.
Автор как связанная сущность. Новый метод Schema::author() создаёт автора отдельным узлом графа с постоянным @id и регистрирует его; статьи ссылаются на него по идентификатору, а не копируют данные на каждой странице. Принимает ID пользователя Битрикса (подтягивает ФИО, фото, должность), массив полей или имя. Добавлены Person::setWorksFor() и Person::setKnowsAbout().
Поля классификации у статьи: setSection(), setKeywords(), setWordCount(), setWordCountFromText(), setTimeRequired(), setArticleBody(). Автоматически заполняются из $arResult: количество слов из DETAIL_TEXT, рубрика из раздела, ключевые слова из TAGS.
Вкладка «Предупреждения» в настройках модуля: последние 50 записей валидатора из журнала событий с датой, текстом и адресом страницы.
Новое событие OnBeforeMicrodataBuild — срабатывает до генерации Open Graph, поэтому обработчик может подменить сущность так, чтобы это отразилось и на мета-тегах.
Удаление сущностей из графа: GraphRegistry::remove() по @id или по объекту и removeByType(). Раньше документация обещала такую возможность, но API её не давал.
Автоматический inLanguage в WebSite, WebPage и статьях — берётся из языка сайта.
Кнопка «Микроразметка» в админ-панели на публичной части: открывает текущую страницу с дебаг-панелью.
2.5.2
Доступ к дебаг-панели ужесточён до администратора. Раньше учитывались также права на модуль через GetGroupRight, а уровень по умолчанию для модуля с ненастроенными правами зависит от версии и настроек портала.
Страница с открытой панелью отдаётся с заголовком Cache-Control: no-store, чтобы не осесть в кеше и не уехать посетителю.
2.5.1
Исправлен разбор свойств инфоблока. Списочные свойства читались из VALUE вместо VALUE_ENUM: если бренд оформлен списком, в разметку уходил числовой идентификатор вместо названия. HTML-свойства сплющивались в строку вида «Текст, HTML» — слово HTML попадало прямо в разметку.
Поддержаны множественные свойства и вложенные HTML-значения.
2.5.0
Дебаг-панель.
Параметр ?microdata_debug=Y на публичной странице под администратором показывает: состав графа с типами и @id, список незаполненных обязательных полей, разбор определения базового URL (схема, хост, доверенные хосты), значения основных настроек, готовый JSON-LD и ссылки на валидаторы Google и Яндекса.
Панель работает и при выключенном модуле, и при пустом графе, и в ручном режиме вывода — то есть именно тогда, когда диагностика нужнее всего.
Внешних стилей и скриптов не подключает, в REST-ответы не попадает, при любой внутренней ошибке молча отключается.
Validator научился отдавать находки структурой, а не только писать в журнал.
2.4.0
Восемь новых типов Schema.org.
VideoObject — Видео-сниппет, вкладка «Видео», главы ролика
Recipe — Карточка рецепта: время, калорийность, рейтинг
JobPosting — Блок вакансий Google Jobs
Course — Карточка учебного курса
QAPage — Блок «вопрос — ответ»
SoftwareApplication — Рейтинг и цена приложения
Service — Страницы услуг
HowTo — Пошаговые инструкции
Общий разбор продолжительности: методы принимают секунды, строку «01:30:00» или готовый ISO 8601.
Стратегия Open Graph для видео: og:type = video.other, теги плеера, длительность в секундах.
Валидатор проверяет обязательные поля всех новых типов.
Константы VideoObject и Service присутствовали в словаре типов с ранних версий, но классов под них не было.
2.3.0
Исправления логики и приведение в порядок.
Хлебные крошки перестали терять последний пункт. Битрикс отдаёт текущую страницу с пустой ссылкой, и она молча отбрасывалась — цепочка в разметке всегда была короче реальной.
Повторный вызов setMainEntity() больше не затирает страницу. Раньше вторая сущность (например, от другого компонента) стирала первую вместе с её данными.
Событие OnAfterMicrodataBuild работает в ручном режиме. Раньше в этом режиме обработчики срабатывали уже после вывода JSON, то есть впустую.
Исправлен маппинг реквизитов: ИНН уходит в taxID (по schema.org это и есть ИНН), ОГРН — в identifier через PropertyValue. Ключи настроек сохранены.
@id товара и статьи получили якоря #product и #article: раньше идентификатор товара совпадал с адресом страницы.
og:locale для языков кроме русского больше не выводит невалидный голый код языка.
Маски исключений сверяются и с путём без query-строки: маска /search/ теперь исключает и /search/?q=....
Убраны короткие теги <? в форме настроек — она больше не зависит от директивы short_open_tag.
Тексты валидатора вынесены в языковые файлы.
Снят лишний слой файлового кеша расписания работы (данные и так кешируются ядром, а суточный TTL мог отдавать устаревшее расписание).
Добавлены тесты без внешних зависимостей: php tests/run.php.
2.2.2
Критические исправления.
Списки в JSON больше не превращаются в объекты. При очистке пустых значений в массивах оставались дырки в индексах, и json_encode отдавал {"0":...,"2":...} вместо [...]. Такие значения sameAs, image и itemListElement валидаторы Schema.org отклоняют.
Корректное определение протокола за обратным прокси. За nginx, Cloudflare или балансировщиком весь граф уезжал на http:// при канонической https://. Добавлена опция «Протокол в абсолютных ссылках» (base_scheme) и учёт заголовков X-Forwarded-Proto / X-Forwarded-Ssl.
Защита от подмены заголовка Host. Хост запроса попадает в разметку, только если совпадает с доверенным источником (org_url, server_name сайта, SITE_SERVER_NAME). Без проверки запрос с чужим Host мог отравить кеш страницы разметкой с чужим доменом.
Починена миграция настроек при обновлении. Битрикс не вызывает CModule::DoUpdate(), поэтому перенос настроек в per-site записи не выполнялся. Добавлен шаблон install/updater.php и идемпотентный запуск при открытии формы настроек.
Восстановлена совместимость с PHP 7.4. Одна конструкция требовала PHP 8.0: на 7.4 модуль устанавливался, но падал при первом обращении.
Базовый URL вычисляется один раз за запрос вместо пересчёта при каждом обращении.