Свойства страницы - заголовок, метатеги и свои свойства
Заголовок вкладки, метатеги и переключатели блоков в шаблоне - это всё свойства страницы. Разбираем, где они задаются, кто кого перебивает и как вывести значение в шаблоне сайта.
Решение
Что задано у страницы сейчас
Смотрим значения, когда страница собрана:
// в подвале шаблона сайта: компоненты уже отработалиprintf("<!-- вкладка=%s | h1=%s | описание=%s -->", $APPLICATION->GetPageProperty('title', '-'), // только своя страница $APPLICATION->GetTitle(false), // основной заголовок $APPLICATION->GetProperty('description', '-')); // с наследованием разделовСвойство страницы - это пара из кода и значения, а не поле в таблице. Метод
GetPageProperty отдаёт значение самой страницы, а GetProperty дополнительно
поднимается по разделам до корня сайта.
Установка со страницы и с раздела
Задаём свойства в коде страницы:
require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/header.php');$APPLICATION->SetTitle('О магазине'); // основной заголовок$APPLICATION->SetPageProperty('title', 'Магазин Твой стиль'); // заголовок вкладки$APPLICATION->SetPageProperty('keywords', 'кресла, стулья, столы');$APPLICATION->SetPageProperty('description', 'Мебель для дома с доставкой');Форма свойств страницы в админке пишет эти же строки в сам файл страницы. Код
title сильнее вызова SetTitle, но только в заголовке вкладки: видимый
заголовок остаётся тем, что задал SetTitle.
Задаём свойства сразу на весь раздел:
// /catalog/.section.php - значения наследуют все страницы раздела$arDirProperties = [ 'description' => 'Мебель для дома и офиса', 'BODY_CLASS' => 'catalog',];// то же самое из кода: $APPLICATION->SetDirProperty('description', 'Мебель');Значения ищутся по цепочке: страница, её раздел, вышестоящие разделы до корня. Значение страницы перебивает значение раздела целиком, а не дополняет его.
Установка из компонента
Ставим заголовок по данным элемента:
// component_epilog.php шаблона компонента: выполняется на каждом запросе$APPLICATION->SetTitle($arResult['NAME']);$APPLICATION->SetPageProperty('title', $arResult['NAME'] . ' - купить');$APPLICATION->SetPageProperty('description', $arResult['PREVIEW_TEXT']);// в result_modifier.php эти строки исчезнут вместе с собранным кэшемПовторная установка не складывается со старой, а затирает её. Побеждает последний вызов до эпилога страницы, поэтому компонент каталога с включённой установкой заголовка перебивает значение самой страницы.
Вывод заголовка и метатегов
Выводим значения в шапке шаблона:
<head><meta http-equiv="Content-Type" content="text/html; charset=<?=LANG_CHARSET?>"><?$APPLICATION->ShowMeta('keywords')?> <!-- имя тега = код свойства --><?$APPLICATION->ShowMeta('description')?> <!-- пустое значение - тега нет --><title><?$APPLICATION->ShowTitle()?></title> <!-- сначала свойство title --><?$APPLICATION->ShowHead()?></head><body class="<?$APPLICATION->ShowProperty('BODY_CLASS', 'inner')?>">Все эти вызовы отложенные: платформа оставляет в буфере метку и подставляет значение перед самой отправкой ответа. Поэтому шапка выводит то, что компонент установит заметно ниже по коду страницы.
Ставим видимый заголовок в разметке:
<h1><?$APPLICATION->ShowTitle(false)?></h1><!-- вызов без аргумента подставил бы сюда заголовок вкладки -->Свои свойства и переключение блоков
Прячем обёртку контента своим свойством:
// в коде страницы или в .section.php раздела$APPLICATION->SetPageProperty('HIDE_CONTAINER', 'Y');
// в шаблоне сайта: немедленное чтение, потому что решается разметка<?if ($APPLICATION->GetProperty('HIDE_CONTAINER') != 'Y'):?> <div class="container"><!-- обычная обёртка контента --></div><?endif?>Код своего свойства произвольный, а вот keywords и description обязаны
совпадать с именами метатегов. Условие читается немедленно, поэтому в шапке оно
видит только значения страницы и разделов, но не будущий вызов из компонента.
Проверка результата
Смотрим готовый ответ, а не админку:
curl -s https://example.com/catalog/ | grep -oE '<title>[^<]*|<meta name="[^"]+" content="[^"]*'# метатега нет вовсе - значение пустое либо код свойства не совпал с именем тегаgrep -rn 'SetTitle\|SetPageProperty' /home/bitrix/www/local/templates/ | headФорма свойств в админке показывает заданное, а не победившее значение. Установок на странице обычно несколько, и разметка ответа - единственное место, где видно итог.
Типичные проблемы
Свойство заполнено, а метатега в разметке нет.
Код свойства не совпал с именем HTML-метатега, и вызов ShowMeta молча пропустил значение. Метатегами выходят только свойства с кодами keywords и description.
В заголовке h1 оказался заголовок вкладки браузера.
Вызов ShowTitle() без аргумента сначала берёт свойство title, а основной заголовок только потом. Для видимого заголовка страницы нужен строго ShowTitle(false).
Заголовок карточки товара пропал после включения кэша.
Установка стоит в файле правки результата, а он выполняется только при сборке кэша компонента. Заголовок и метатеги из компонента задают в его эпилоге, который работает всегда.
Компонент задал заголовок, а на странице другой.
Ниже по коду стоит ещё одна установка заголовка, и побеждает именно она. Ищем все вызовы в шаблоне сайта и на странице, оставляем одно место установки.
Подмена метатега из своего кода не срабатывает.
Код выполняется после закрытия буфера страницы, и подставлять значение в шапку уже некуда. Свойства задают до эпилога страницы, пока буфер вывода ещё открыт.
Частые вопросы
Почему GetProperty в шапке возвращает пустоту?
Шапка выполняется раньше компонентов, и в момент вызова значение ещё никто не задал. Немедленное чтение видит только свойства страницы и разделов, а отложенные ShowProperty, ShowMeta и ShowTitle дожидаются конца сборки страницы.
Как поставить свойство раздела заголовком страницы?
В эпилоге шаблона компонента читаем нужное значение и вызываем SetTitle. Делать это в шаблоне сайта бесполезно: там данных раздела ещё нет, а отложенный вывод заголовка их дождётся.
Как скрыть заголовок на одной странице?
Заводим своё свойство страницы и оборачиваем вывод ShowTitle(false) условием по нему. Так обходятся без второго шаблона сайта и без правки самого шаблона под одну страницу.
Где хранятся свойства, заданные менеджером в админке?
Свойства страницы - в самом файле страницы вызовами SetPageProperty, свойства раздела - в файле .section.php массивом $arDirProperties. Поэтому они лежат рядом с контентом и переезжают вместе с файлами сайта.
Можно ли завести своё свойство с любым кодом?
Да, код произвольный, и такие свойства удобны для класса на теге body и переключения блоков шаблона. Ограничение одно: метатегом значение выйдет только при совпадении кода с именем тега.
Смежное
- Шаблон сайта на практике - оглавление подтемы
- Шаблоны сайта и компонентов - устройство шаблонов целиком
- Натяжка вёрстки на шаблон сайта: разрез, пути, компоненты - куда встают служебные вызовы шапки
- Путь запроса на витрине: пролог, компоненты, буфер, эпилог - почему отложенный вывод вообще работает
- Заголовки и метатеги каталога: шаблоны для разделов и товаров - откуда значения берутся на страницах каталога
- Заголовок и метатеги не те: разбор причин - когда подставилось чужое значение
- Включаемые области: файлы, области шаблона, правка менеджером - другой способ менять шапку по разделам
- Шаблон под раздел и по условию: правила показа, приоритет, печать - когда свойства мало и нужен свой шаблон
- Шаблон чужого компонента: копия, доработка результата, эпилог - где в компоненте ставить заголовок