(phptemplate) Перекрытие стандартных шаблонов своими

Главные вкладки

Аватар пользователя marazmus marazmus 20 января 2007 в 10:35

Введение

По умолчанию, система шаблонов дает возможность работать с шаблонами page (общий шаблон сайта), node (шаблон документа), comment (шаблон комментария), block (шаблон блока) и box (шаблон общего контейнера). Эти шаблоны находятся в файлах page.tpl.php, node.tpl.php, comment.tpl.php, block.tpl.php и box.tpl.php, соответственно.

Суть в том, что система шаблонов уже сформировала для этих шаблонов все необходимые переменные, и нам остается только разместить с помощью операторов php значения этих переменных в нужных нам местах (внутри тегов html).

Пример: Кусок кода из page.tpl.php

      <?php if ($sidebar_left): ?>
        <div id="sidebar-left" class="sidebar">
          <?php if ($search_box): ?><div class="block block-theme"><?php print $search_box ?></div><?php endif; ?>
          <?php print $sidebar_left ?>
        </div>
      <?php endif; ?>

Но часто требуется определить свою структуру отображения с помощью html не только для вышеприведенных структур, но и для более мелких блоков информации. К примеру, мы хотим переопределить отображение “хлебных крошек” (breadcrumbs) на что-то более подходящее нам по дизайну html-кода. Или переопределить вывод массива $links на более подходящий нам по структуре html-тегов. В итоге, нужно получить файл .tpl.php, в котором мы можем определить нужные нам html-теги, и заполнить их информацией из переменных php (аналогично page.tpl.php, node.tpl.php и т.д.). То есть, нам нужно отделить html-код от логики работы приложения (для тех структур данных, которым не предусмотрен “свой” файл .tpl.php).

Перекрытие функции

Для этого нам потребуется файл template.php. Если его нет в каталоге темы, нужно его создать.

Теперь определимся с функцией, что формирует тот “кусок” html-кода, который мы хотим переопределить на свой. Возьмем, к примеру, функцию theme_breadcrumb(). Вот ее код (находится в файле /includes/theme.inc):

function theme_breadcrumb($breadcrumb) {
  if (!empty($breadcrumb)) {
    return '<div class="breadcrumb">'. implode(' » ', $breadcrumb) .'</div>';
  }
}

Можно, конечно, поправить код вывода прямо здесь, в файле theme.inc - но это будет, во-первых, вмешательством в код “ядра” Друпала - что повлечет за собой проблемы при последующих обновлениях (придется следить за каждым файлом ядра, в который вы внесли свои изменения). Во-вторых, это противоречит нашей задаче - получить конкретный файл .tpl.php в пределах нашей темы, который можно будет менять, как нам будет необходимо.

Здесь нам поможет система “ловушек” Друпала, суть которой в том, что она использует определенным образом имена функций в логике своей работы. Поясним сразу на примере. Если наша тема называется, к примеру, bluebox, то вышеприведенную функцию theme_breadcrumb() достаточно “перекрыть по имени” - назвать ее bluebox_breadcrumb().

Система шаблонов построена таким образом, что взаимодействует с системой ловушек, и перед окончательным формированием шаблона ищет функции, которые могут быть перекрыты создателем этой темы. “Сигналом” того, что данная функция перекрыта, и нужно использовать ее (функцию темы), а не функцию ядра (из theme.inc), служит как раз имя этой функции. Последняя часть имени должна соответствовать какому-либо из имен функций ядра, которые можно переопределять. Первая часть имени при перекрытии должна заменять слово theme и должна быть равна названию темы (к примеру, bluebox). В итоге, назвав нашу функцию bluebox_breadcrumb(), мы добьемся того, что система шаблонов будет использовать именно ее при построении html-кода окончательного вывода страницы.

Перекрытую функцию нужно внести в файл template.php. К примеру, наша функция bluebox_breadcrumb() будет выглядеть так:

function bluebox_breadcrumb($breadcrumb) {
  if (!empty($breadcrumb)) {
    return '<div class="breadcrumb">'. implode(' / ', $breadcrumb) .'</div>';
  }
}

Переменная $breadcrumb - это массив, в котором содержатся все ссылки, формирующие список “хлебных крошек”. Этот массив формируется ядром Друпала, и как именно происходит это формирование - тема для более глубокого исследования. Сейчас же просто используем этот массив для оформления его html-тегами.

В вышеприведенном коде мы поместили “хлебные крошки” в контейнер div, и заменили знак разделения ссылок на свой - “/”. В принципе, можно ограничиться и этим решением, но мы пойдем дальше. Ведь в итоге нам нужно получить файл .tpl.php, который будет не программой php, которая выдает html-код, а именно html-шаблоном, в котором будут “вкрапления” php. Все, что нужно будет нам в этом файле - переменная (набор переменных), содержимое которых мы используем для работы шаблона.

Шаблон .tpl.php

Первый шаг - изменение кода нашей перекрытой функции. Вместо генерации всего нужного html-кода с помощью php, мы просто “отдадим” информацию нашему html-шаблону - обеспечив четкое отделение php-кода от тегов html.

Суть метода - использование функции _phptemplate_callback(). Первый аргумент этой функции - строка, которая задает имя шаблона .tpl.php. Этому шаблону будет доступна вся информация, которая содержится в массиве переменных, заданных во втором аргументе. Вот как будет выглядеть вызов функции в нашем случае:

function bluebox_breadcrumb($breadcrumb) {
  if (!empty($breadcrumb)) {
    $content = _phptemplate_callback('breadcrumb', array('breadcrumb' => $breadcrumb));
    return $content;  
  }
}

Второй шаг - создание и заполнение файла .tpl.php. Его имя должно быть равно содержимому первого аргумента функции _phptemplate_callback(). В нашем случае, это будет файл breadcrumb.tpl.php. А код его будет таким:

<div class="breadcrumb"><?php print implode(' / ', $breadcrumb); ?></div>

Как видим, код просто перенесен из функции в шаблон. Но сейчас нам гораздо удобнее работать с html-кодом (так как нам нужен именно он). Раньше, в функции, нам приходилось следить за синтаксисом php, обходиться без подсветки html-кода - так как вывод html формировался в строках типа
$bla_bla = ‘

Примечание по нашему случаю: Так как переменная, содержащая список ссылок, доступна нам в виде массива, опытный верстальщик, который знает php, может легко изменить конечный html-код, сформировав, к примеру, список “хлебных крошек” не в виде “плоской” строки, а в виде неупорядоченного списка (ul), обрамив каждую ссылку тегами li. И для этого ему не придется “лезть” в файл template.php (который может содержать большое количество других функций), опасаясь повредить другие функции. Все необходимое будет сделано только в файле breadcrumb.tpl.php.

Эта заметка писалась довольно рано, поэтому в ней м.б. многовато бреда. Но надеюсь а) почистим; б) это не запутает читателя.

Комментарии

Аватар пользователя marazmus marazmus 30 марта 2007 в 17:32

Это вполне можно воспринимать как руководство к действию. Код рабочий Smile

Бред там может быть не в коде, а в моей отсебятине (по сравнению с наработками и знаниями более опытных друпаллеров).

Поможет вам материал - вот и хорошо Smile

Аватар пользователя jason32 jason32 30 марта 2007 в 18:15

вообще хотелось бы почаще ваших исследований по phptemplate - статьи про блоки и пути для меня были открытием, причём приятным...

Аватар пользователя marazmus marazmus 30 марта 2007 в 18:31

Да я бы и сам рад, но в последнее время организационные вопросы доминируют над технологиями Sad
Хорошо бы, если кто еще подключился, из сугубых практиков - один пример из жизни лучше тыщи высосанных из пальца придумок.

Аватар пользователя marazmus marazmus 30 марта 2007 в 20:57

Я лично не забыл, Semen, не обижайтесь, пожалуйста Smile
Просто немного торможу, из-за незапланированной резвости жизни в оффлайне Smile
К тому же была надежда на спецов, которых пока не видать Smile

Аватар пользователя B.X B.X 31 марта 2007 в 3:37

эх... жаль, что в Друпале до сих пор многое надо делать ручками... был бы модуль редактор, который создавал бы всё это сам... то есть кусок оттуда, он сам создает кусок .tpl.php и так далее...

а то ищи в коде эти строки... для нужного тебе изменения... где вообще названия всего, что можно переопределить в template.php есть вообще такой материал?

Аватар пользователя Dan Dan 31 марта 2007 в 7:25

Переопределить можно все функции, название которых начинается с theme_.
Можно, в принципе и другие переопределить, но это сложнее.

Аватар пользователя Natalie Natalie 31 марта 2007 в 8:12

Там какие-то хитрые действия в темах... Точно не помню, надо поискать пример. Сейчас новая книжка выходит, как раз по программированию для Друпала, может там что будет...
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
Переводы некоторых модулей.
All content management systems suck, Drupal just happens to suck less. -- Boris Mann at DrupalCON Amsterdam, August 2005.

Аватар пользователя B.X B.X 31 марта 2007 в 8:13

ну, меня больше беспокоит то, что не везде используются классы и идентификаторы...
например на странице node/add никак не создать таблицу с границами вокруг документа, так как там контент начинается просто с текста...

Аватар пользователя Dan Dan 31 марта 2007 в 9:02

Список всех темовых функций ядра и установленных (и включенных) модулей, можно получить следующим кодом:

<?php
$functions = get_defined_functions();
$theme_functions = array();
foreach ($functions['user'] as $function)
if (strpos($function, 'theme_') === 0)
$theme_functions[] = $function;
print_r($theme_functions);
?>

Аватар пользователя Dan Dan 31 марта 2007 в 9:04

> например на странице node/add никак не создать таблицу с границами вокруг документа, так как там контент начинается просто с текста...
перегрузи theme_node_form и будет тебе счастье

Аватар пользователя kiev1 kiev1 31 марта 2008 в 10:26

подскажите - а поля в CCK - может уже они готовые есть и им можно шаблон настраивать в виде имя_поля.tpl.php ?
и еще - как эти поля прописывать в виде переменных типа $имя_поля node.tpl.php ?

Аватар пользователя Химический Али Химический Али 31 марта 2008 в 10:53

kiev1 wrote:
подскажите - а поля в CCK - может уже они готовые есть и им можно шаблон настраивать в виде имя_поля.tpl.php ?
и еще - как эти поля прописывать в виде переменных типа $имя_поля node.tpl.php ?

http://www.google.ru/search?hl=ru&q=theming%20cck%20fields&lr=&aq=f

Аватар пользователя kiev1 kiev1 14 мая 2008 в 8:07

спасибо, еле нашел
не все так просто:

-----------------------------
Итак, находим в папке modules/cck/theme/ файл template.php. Как видите, он содержит единственную функцию phptemplate_field:

function phptemplate_field(&$node, &$field, &$items, $teaser, $page) {
$variables = array(
'node' => $node,
'field' => $field,
'field_type' => $field['type'],
'field_name' => $field['field_name'],
'label' => $field['widget']['label'],
'items' => $items,
'teaser' => $teaser,
'page' => $page,
);
}

Аккуратно копируем весь код функции и вставляем в конец файла template.php текущей темы оформления. Сохраняем файл. Добавленная функция переопределяет стандартную процедуру вывода полей CCK и «сообщает» модулю CCK, что забота о выводе полей теперь ложится на пользователя.

В соответствии с описанием, в папке текущей темы также нужно создать файл field-field_myurl.tpl.php (помните, что поле в моём примере выше называется field_myurl?). Этот файл - просто шаблон, в котором можно определить, как именно поле CCK будет отображаться в браузере, то есть, HTML-обвязку выводимых данных поля. Поскольку нам ничего не нужно выводить (мы хотим скрыть поле), то создаём пустой файл, а лучше - вообще ничего не создаём (ничего страшного не произойдёт). Для интереса можете посмотреть как может выглядеть шаблон вывода поля, открыв файл modules/cck/theme/field-field_body.tpl.php.
-----------------------------
http://www.drupal.ru/node/4980

Аватар пользователя avers_inc avers_inc 3 ноября 2010 в 17:21

хорошая статья...
только в 6-м друпале, судя по всему, функции _phptemplate_callback нет.
где бы найти такое же описание только для 6-го?

Аватар пользователя specialist-seo specialist-seo 3 февраля 2011 в 18:28

Ничего никто не портил в 6 версии, если не перекрывается функция в шаблоне, то значит друпал ещё не переопределил функции для темы.

Для переопределения функций нужно (актуально для версии 6.20):

  1. Очистить кеш браузера
  2. Если включен кеш drupal, перейти на страницу /admin/settings/performance (установки - производительность) и очистить кеш
  3. Перейти на страницу /admin/build/themes (управление темами), чтобы друпал считал новые пользовательские функции из файла Вашей темы template.php
  4. Если не помогает, то на этой же странице отключить тему. Сохранить. Включить тему заново. Сохранить. После этого точно переопределятся все функции.

На сколько понял, по умолчанию принято, что крон уже настроен, а чаще всего его никто из новичков не трогает. На практике влияние крона еще не проверял.