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

Свойства страницы - заголовок, метатеги и свои свойства

Заголовок вкладки, метатеги и переключатели блоков в шаблоне - это всё свойства страницы. Разбираем, где они задаются, кто кого перебивает и как вывести значение в шаблоне сайта.

Решение

Что задано у страницы сейчас

Смотрим значения, когда страница собрана:

// в подвале шаблона сайта: компоненты уже отработали
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 и переключения блоков шаблона. Ограничение одно: метатегом значение выйдет только при совпадении кода с именем тега.

Смежное

Первоисточник