Drupal: Как добавить произвольные meta-теги и другие теги в head-область HTML-страницы

Изображение пользователя andyceo.

Дорогие друзья-друпаловоды, вы наверняка знаете, что иногда бывает необходимо прописать для страницы нужные мета-теги. Создать произвольный meta-тег нам может понадобиться, когда мы будем подключать и настраивать библиотеку phpMyID к Drupal, или, например, когда нам нужно будет подтвердить своё право владения веб-сайтом для некоторых сервисов, разместив на главной странице проверочный мета-тег.

Сформулируем задачу: необходимо вывести проверочные теги сервисов Яндекс.Вебмастер, Инструменты для веб-мастеров от Google, Yahoo! Site Explorer и Webmaster Tools от Microsoft Live Search (MSN) на главной странице сайта. Нужно нам это для того, чтобы вышеописанные сервисы могли подтвердить моё владение сайтом. (Ну а для тех кто совсем ничего не знает и не понимает, поясню, что вышеописанные сервисы предоставляют владельцам сайтов интересную информацию о проиндексированности сайта, количестве поисковых запросов, по которым находится ваш сайт, количество ссылок на ваш сайт и другую подобную и очень интересную инфу. Для того, чтобы получить её, вам необходимо зарегистрироваться на вышеописанных сервисах и подтвердить право владения своим сайтом, разместив проверочные мета-теги на главной странице, или разместить предложенный файл на сайте. Я выбрал метод с мета-тегами, т.к. на мой взгляд, он удобнее.)

Сформулируем задачу в общем виде (мало ли какие теги нам понадобиться выводить в head-области), и мы получим заголовок этого поста: Как добавить произвольные meta-теги и другие теги в head-область HTML-страницы:

<html>
  <head>
    <title>Тестовая страница</title>
    <meta name="robots" content="index,follow" />
    <meta name="verify-v1" content="ApEbWaOK3CfB1B0vwz1aXiPM4AyF25WXJcivNFmEKtQ=" />
    <meta name="ПРОИЗВОЛЬНАЯ_МЕТА" content="ПРОИЗВОЛЬНЫЙ_КОНТЕНТ_МЕТЫ">
    <ПРОИЗВОЛЬНЫЙ_ТЕГ>КОНТЕНТ_ПРОИЗВОЛЬНОГО_ТЕГА</ПРОИЗВОЛЬНЫЙ_ТЕГ>
  </head>
  <body>
ВСЯКАЯ ВСЯЧИНА
  </body>
</html>

Теперь задумаемся о решениях. Скажу сразу, что решения разрабатывались для ветки Drupal 5.x, но я думаю, что их можно использовать практически в неизменном виде и для других версий.

Самый очевидный путь - это прописать эти теги в файле page.tpl.php вашей темы. Этот путь имеет тот недостаток, что в будущем вы, возможно, захотите использовать файл page-front.tpl.php для главной страницы, или предпочтёте использовать тему, которая написана на другом движке шаблонов (например на Smarty), и вообще, у вас может быть мультисайтинг, и вы используете одну и ту же тему для совершенно разных сайтов, тогда как мета-теги должны быть заданы для каждого сайта строго свои. Конечно, мы можем в файле page.tpl.php или page-front.tpl.php поставить условие, которое будет проверять домен сайта и в зависимости от него выдавать нужные теги, но это всё чересчур сложно. Нас же интересует метод типа "сделал и забыл".

Второй, менее очевидный путь - это написать свой .inc-файл для модуля Meta Tags (он же в прошлом NodeWords). Этот путь нам посоветовал уважаемый andypost@drupal.org. Цитирую:

Модуль nodewords имеет свой API и свои хуки
расширяется элементарно - созданием .inc файлика с парой функций в папке tags
весь функционал реализован именно таким образом - разобраться совсем не сложно - достаточно посмотреть текущую реализацию

Минусы этого подхода - вам надо скачивать, устанавливать и настраивать этот модуль, плюс ещё писать нужный .inc-файл для него и положить его в соответствующую папку модуля (папку tags). Однако этот метод уже лучше, чем редактирование темы, т.к. даёт большую гибкость. Я пытался разобраться в формате .inc-файлов для модуля Meta Tags, но что-то неудачно, и написать собственный файл мне не удалось. Обращаюсь с просьбой ко всем, кто знает как написать .inc-файл для поддержки нужного тега этим модулем, отпишитесь в комментах с текстом этого файла.

Третий путь был какой-то замутный, с использованием CCK. Я нашёл его на русскоязычном портале drupal.ru: META-теги (Есть ли решение?). Цитирую уважаемого edhel:

Можно без доп. модуля ручками запрограммить такое: с помощью CCK добавить поле "ключевые слова" и модулек свой из ~4 строчек с хуком nodeapi. Если $op=='view' && $page, то добавить в заголовок <meta>...

Этот вариант, опять же, не прокатывает - слишком громоздкий, требует огромного стороннего модуля CCK и программирования. Но идея интересная, из-за идеи и включил этот вариант в статью. Может кто загориться и реализует :)

Четвёртый вариант, предложил уважаемый marazmus:

Сделайте область (регион) там, где нужно расположить метатеги - оформите ее в template.php и пропишите ее вывод в page.tpl.php.

Затем достаточно будет сделать блок, ввести туда нужные метатеги (не забыв использовать фильтр Full HTML или PHP), и включить этот блок в нужное время в нужном месте - положив блок в свежеоформленную область.

Правда, при этом нужно будет помнить, что в этот блок нельзя пихать "визуальные" теги, но это уже издержки гибкости. Зато мы можем описать (запрограммировать или прописать через пути друпала), когда и где должен появляться этот блок. Еще плюс - блоков можно насоздавать много, для разных случаев.

Кроме того, по умолчанию блоки оборачиваются в тег div с CSS-классами и id, что недопустимо в head-области документа по стандарту HTML. Поэтому, чтобы обойти это, придётся в теме писать файл block-...tpl.php для того блока, который будем выводить.

Тоже решение, однако опять же, несколько замутное. Городить такой огород, да ещё и помнить потом про него... Не наш метод! :)

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

  1. Создаём PHP-блок на странице управления блоками (/admin/build/block). PHP-блок это такой блок, в котором в качестве фильтра указывается обработчик PHP. Лучше всего его создавать из-под учётной записи администратора.
  2. Вводим в тело блока следующий код:

    <?php
    drupal_set_html_head
    ('<meta name="verify-v1" content="fmX1YhAzQ20sKTBkoEAa3W+h432WiBjtbyM78gi0V/o=" />'); //for Google
    drupal_set_html_head('<meta name="y_key" content="ec64d4a23b420294" />'); //for Yahoo
    drupal_set_html_head('<meta name="yandex-verification" content="6dcc2d578ba99b72" />'); //for Yandex
    ?>

    Разумеется, вместо моих тегов в функцию drupal_set_html_head() Вы должны вставить свои теги.

    Функция API Drupal drupal_set_html_head(), делает как раз то, что нам надо - отсылает любой переданный с её помощью HTML-код в head-область формируемой странички.

  3. Сохраняем наш блок.
  4. Идём в настройки этого только что созданного блока и выставляем там следующие значения:

    Название: Оставляем название пустым обязательно!, чтобы Drupal не отображал его. (то самое название, что должно было бы показываться пользователю)

    Описание блока: посылаем произвольные теги в head-область, или любое другое описание, что вы хотите

    Настройки видимости для пользователя: Пользователи не могут управлять видимостью блока - ставим галочку тут

    Настройки видимости для ролей: anonymous user - ставим галочку тут

    Установки видимости для страницы: Показывать только на перечисленных страницах: <front> (т.е. показываем блок только на главной странице)

  5. Сохраняем блок.
  6. На странице списка блоков (/admin/build/block) нашему блоку выставляем следующие параметры:

    Область сайта, в которой будет отображаться блок: Заголовок (Header)
    Вес: самый минимальный -10

  7. И после этого наживаем Сохранить блоки.

На этом всё - наша задача решена. Если Вы всё сделали правильно, то после сохранения, спустя некоторое время, когда у вас на сайте обновится кеш для анонимных посетителей (если Вы используете кеширование для своего сайта), введённые Вами мета-теги отобразятся на сайте, и Вы сможете подтвердить права владения Вашим сайтом для Google или Yandex, например. Эти теги будут отображаться только на главной странице и только незарегистрированным пользователям, в соответствии с нашими настройками.

Почему это работает? Если блок не генерирует никакого содержимого, то Drupal не отображает его. Наш блок не генерирует вообще ничего. Он просто выполняет PHP-код, который работает с API Drupal, обеспечивая модификацию head-области страницы до её отсылки в браузер пользователя, в результате же выполнения кода никакого контента не генерируется, и следовательно, блок не будет отображён и не будет портить нам дизайн.

Благодарности:
Благодарю всех откликнувшихся в этой теме пользователей Drupal.ru
Спасибо этому посту, за то, что навёл меня на идею использовать функцию drupal_set_html_head().

PS: Столько способов сделать одно и то же! На мой взгляд, всё это показывает, насколько система Drupal гибкая. Когда я искал собирал инфу о проблеме, набрёл на статью на официальном сайте о том, как один чел сделал это всё через редирект, а точнее через модуль path_redirect - он как бы создал проверочный файл (центр вебмастеров Google требует для подтверждения собственности на сайт вставить в него определённую мету, или создать файл в корневой директории на сервере) и редиректился с него на главную страницу своего сайта с кодом 302. Пишет, что сделал он это "элегантно, всё в друпале, никакого фтп, никаких закачек файлов на сервер". Так что нам ещё один метод в копилку...

PPS: Сервисы для вебмастеров:

PPPS: Важная информация для всех пользователей предложенного решения и Drupal 5.8!!!
Ввиду бага - regression in 5.8 from 5.7 theme(blocks,all) broken - so no header alteration possible в Drupal 5.8, решение НЕ РАБОТАЕТ! Чтобы оно заработало, необходимо скачать обновлённую dev-версию Drupal 5-й ветки (я брал версию от 17 июля 2008 г.), в которой сделаны патчи, закрывающие данный баг, и обновить следующие файлы:

  • modules/block/block.module
  • modules/block/block.info
  • themes/engines/phptemplate/phptemplate.engine

Тогда всё заработает как и прежде.

Комментарии

Изображение пользователя andyceo.

Использование подобного метода для темизации (подключаем *.css)

Сегодня, помогая одному доброму человеку, нашёл интересное применение подобного метода.

Задача заключалась в том, что нужно было сделать небольшую темизацию на всех сайтах в мультисайтовой связке. Для каждого сайта использовался свой дизайн. Конкретно засада заключалась в том, что при использовании модуля ImageField для CCK, ImageField выводил название поля для изображения, тогда этого делать было не нужно. По умолчанию, ImageField форматирует вывод документа очень просто: выводит одно поле, следом за ним следующее, потом контент (ну или в том порядке, в котором настроишь в админке). А надо было, чтобы выводилось изображение (поле модуля ImageField), его справа обтекал текст (содержимое документа). CSS-код для этого очень простой:

div.field-field-pix {
  float: left;
  margin-right: 5px;
}
 
div.field-field-pix div.field-label{
  display:none;
}

Поле типа "Image" ("Изображение"), созданное с помощью модуля ImageField, называлось у нас pix, поэтому контейнер div имеет класс "field-field-pix".

Итак, начальные условия я вроде описал. Задача, повторюсь ещё раз, заключалась в том, чтобы этот css-код внедрить в каждую тему на заданных сайтах (на каждом сайте поле, созданное с помощью модуля ImageField, называлось одинаково - pix).

Решение же заключается в следующем. Сначала мы создаём css-файл, например с именем image-style.css, и с таким содержанием, как было показано выше, и кладём его куда-либо на сервер, куда-нибудь внутрь инсталляционной директории Drupal. Мы положили его в одну из тем, в директорию sites/all/themes/moleskine/

Затем, точно также, как и описано в статье, мы создаём PHP-блок в админке каждого сайта. (В нашей задаче, мы делали это вручную, но вообще можно и скрипт написать, который автоматизирует нашу работу). В этот блок (в поле "Содержание") пишем следующий код:

<?php
drupal_add_css('sites/all/themes/moleskine/image-style.css','theme');
?>

Разумеется, в функции drupal_add_css() вы должны передать путь к вашему css-файлу. Эта функция включает ваш css-файл в список отдаваемых вашим сайтом css-ок. Соответственно, к вашей теме оформления он применится, и будет оформляться всё как положено.

Один из плюсов такого подхода - скорость реализации, универсальность, а также то, что используется стандартная функция Drupal для обработки css-файлов, а это значит, что если у вас в админке сайта включен режим кеширования, сбора css-ок в один большой файл + его сжатие при отдаче, то для вашего маленького файлика всё это будет работать, и дополнительного запроса к серверу за ним не будет. Тем не менее, сохраняется раздельность вашего кода и кода темы оформления (повторюсь, мы имели дело с темами, предоставляемыми с сайта Drupal.org, и потому хотели иметь возможность свободно обновлять их, если они вдруг обновились, не вспоминая, какой же хак мы поставили на эту тему, и при обновлении файлов он отвалился).

Из минусов... ну пожалуй, на мой взгляд, плюсы перевешивают возможные минусы, поэтому минусы, дорогие читатели, я предлагаю вам определить самим и отписать в комментариях. Разумеется, комментарии по основному посту также приветствуются.

Добавьте страницу в закладки. Перейти к верху страницы
Синдикация материалов