УрокФункции предобработки переменных перед выводом в шаблон
Все мы знакомы с обычными файлами шаблонов, выглядящими по принципу файл.tpl.php. И все привыкли, что в этом шаблоне откуда-то (магия?) появляются переменные с даннами. Сегодня я приоткрою эту тайну: для того, чтобы попасть в шаблон, была придумана функция предобработки переменных. Обычно она выглядит вот таким образом:
function template_preprocess_что_обрабатываем(&$variables) { //код }
где
- template- это имя темы или модуля (в зависимости от того, где реализуем функцию)
- $variables - массив с доступными переменными
- preprocess_что_обрабатываем - собственно, название функции с говорящим названием :)
Как пример - в каждой теме присутствует файл page.tpl.php. Функция, которой можно обработать этот файл - template_preprocess_page.
Давайте посмотрим небольшой кусок этой функции (ссылка api.drupal.ru):
$variables['head_title'] = implode(' | ', $head_title); $variables['base_path'] = base_path(); $variables['front_page'] = url(); $variables['breadcrumb'] = theme('breadcrumb', drupal_get_breadcrumb()); $variables['feed_icons'] = drupal_get_feeds(); $variables['footer_message'] = filter_xss_admin(variable_get('site_footer', FALSE)); $variables['head'] = drupal_get_html_head(); $variables['help'] = theme('help'); $variables['language'] = $GLOBALS['language']; $variables['language']->dir = $GLOBALS['language']->direction ? 'rtl' : 'ltr'; $variables['logo'] = theme_get_setting('logo');
Здесь генерируются переменные. Откуда они берутся - ну, собственно, кто откуда :) Главная идея в том, что в итоге получается массив $variables, элементы которого передаются в шаблон page.tpl.php. Это именно те переменные, с которых у многих людей начиналась работа со своими темами. Теперь вы знаете, откуда они взялись!
Основную идею, которую я хотел донести - это то, что эти переменные можно менять, или добавлять свои. Давайте рассмотрим несколько примеров, наглядно показывающие работу с функцией template_preprocess_page:
Пример 1
Например, работаем мы со стандартной темой Garland. И допустим, я захотел, чтобы во всех нодах типа news заголовком страницы ($title) являлся текст "Новости". В template.php пишем такой код:
// заменяем в template_preprocess_page слово // template на название нашей темы function garland_preprocess_page(&$variables) { // теперь проверяем, если в массиве переменных // была передана переменная node (а она появляется только // на страницах, содержащих материал), и тип материала - новость, // то переменной заголовка присваиваем новое значение - 'Новость' if (isset($variables['node'])) { if ($variables['node']->type == 'news') { $variables['title'] = 'Новости'; } } }
Теперь на всех страницах нод новостей, в переменной $title шаблона page.tpl.php будет красоваться надпись "Новости".
Пример 2
Пусть мы работаем всё с той же старой и надёжной темой Garland. Но теперь у меня задача - вывести в блок дополнительные классы для css, характеризующие этот блок. За предобработку переменных для блока отвечает функция template_preprocess_block:
function garland_preprocess_block(&$variables) { // получаю данные о блоке $block = $variables['block']; // инициализирую массив будующих классов $block_classes = array(); // в первую ячейку массива пишу строку, со значением модуля, которым // был создан блок $block_classes[] = 'block-'. $block->module; // во вторую ячейку отправилась "четность" блока, // тоесть odd или even $block_classes[] = $variables['zebra']; // третья ячейка - порядковый номер блока в регионе $block_classes[] = 'block-'. $variables['block_id']; // теперь делаем из нашего массива одну строку, // предварительно разделив бывшие ячейки массива пробелами, // и создаём в файле block.tpl.php новую переменную $classes $variables['classes'] = implode(' ', $block_classes); }
Теперь в block.tpl.php стала доступна переменная $classes, которую можно использовать, например, вот так (содержимое файла block.tpl.php):
<div id="block-<?php print $block->module .'-'. $block->delta; ?>" class="block <?php print $classes; ?>"> <?php if ($block->subject): ?> <h2 class="block-title"><?php print $block->subject; ?></h2> <?php endif; ?> <div class="block-content"> <?php print $block->content; ?> </div> </div>
Вот и вся хитрость. Просто, не так ли?
Кстати, с помощью функций предобработки можно создавать кастомные (свои) файлы шаблонов. Как пример - создание отдельного шаблона страницы для разных типов ноды
- Spleshka
- 16.02.2011
- 31892
Комментарии
Супер, спасибо за статью.
ПС
user warning: Unknown column 'captcha_type' in 'field list' query: SELECT module, captcha_type FROM captcha_points WHERE form_id = 'comment_form' in /home/u3146/domains/drupalace.ru/sites/all/modules/captcha/captcha.inc on line 60.
user warning: Unknown column 'captcha_type' in 'field list' query: SELECT module, captcha_type FROM captcha_points WHERE form_id = 'user_login_block' in /home/u3146/domains/drupalace.ru/sites/all/modules/captcha/captcha.inc on line 60.
user warning: Unknown column 'captcha_type' in 'field list' query: SELECT module, captcha_type FROM captcha_points WHERE form_id = 'comment_form' in /home/u3146/domains/drupalace.ru/sites/all/modules/captcha/captcha.inc on line 60.
update.php забыл, штоли? =D
Ага)) Когда заканчиваешь работу над сайтом в 4 утра, всегда есть шанс что-то упустить ))
SplasH, Спасибо ! Как всегда о непонятном, простым языком :)
Спасибо, стараюсь :)
а как получить все переменные пользователя, включая аватар и поля профиля?
хорошо, перефразирую: куда вставить sql запрос для формирования переменных и последующей вставки их в шаблон темы?
Мне тоже интересен этот вопрос. Автор напишите ответ, пожалуйста.
а возможно ли следующее: создана "запись в блоге" и выводятся ссылки "блог !username" "комментировать" "читать далее". Так вот, мне нужно что бы слово блог было одного цвета, а слово !username другого цвета, но из - за того что это одна ссылка нет возможности этого реализовать, как можно !username обернуть в div?
Как минимум 2 варианта:
Создать файлы bloglink.info и bloglink.module. Положить их в папку /sites/all/modules/blogapi на вашем сервере.
Содержимое bloglink.info:
Содержимое файла bloglink.module:
Я конечно модуль не тестировал - если будут ошибки пишите :) Но по идее не должны возникнуть. После включения модуля имя пользователя будет обёрнуто в <span>
Код опять же не тестировался, но теоретически должно работать :) Если будут проблемы - пишите, разберёмся.
Выбрал второй варинт, но возникла проблема: вставил вашу функцию, переменовал на моё имя темы, очистил кэш, и ссылки вообще пропали
Сори, забыл переменную скопировать :) Теперь код проверил и исправил. Теперь работает.
Здрасте.
Я очень новичок в drupale.
Видимо, это статья для d6 написана? Потому что в d7 переменной
$variables['title']
или$vars['title']
в template.php нету. Есть$vars['node']->title
, однако если её изменять в template.php (равно как и в page.tpl.php или в node.tpl.php) не происходит смены содержимого тега title. Можно было бы подумать, что есть$vars['page']->title
но такой нет..Не могли бы вы разъяснить как в d7 поменять содержимое тега title?
В D7 тайтл появляется не на этапе предварительной обработки, а в функции обработки - http://api.drupal.org/api/drupal/includes--theme.inc/function/template_process_page/7
простите, я ответил в общую ветку
я наверное дико туплю, но функция garland_process_page(&$vars) в template.php не подхватывается (в page.tpl.php тоже). куда её вставлять-то? или может её место в page.tpl.php и надо как-то её вызвать?
Вы редактируете тему гарланд? Если да, то garland_process_page(&$vars) должна в template.php подхватываться. Если же другая тема - то не garland_process_page, а ИМЯТЕМЫ_process_page
Лучше бы конечно написать не «ложу строку», а «кладу строку» :-)
а еще лучше в тэгах писать к какой версии друпала относится. так будет понятнее
Тогда уже "пишу строку". Про версию Друпала давно думал, всё нет времени сделать.
Попробовал данный пример - в итоге заголовок поменялся только на страницах редактирования нод. В чем может быть проблема?
Возможно, заголовок ещё где-то перекрывается?
Можно ли в файлах node.tpl.php, page и т.д руками писать теги, а внутрь вставлять переменные со значениями полей? Или нужно обязательно создавать новые переменные с тегами через template_process_ ?
Подскажите, а зачем использовано 2 массива в данном случае?
function theme_preprocess_page(&$vars, &$variables)
Комментировать