Наверняка вы слыхали о подходе MVC (model-view-controller) в веб-программировании. В Drupal для реализации данного подхода есть все необходимые инструменты. При этом уровень контроллера по большей части уже реализован, т.к. движок предлагает вам реализовать логику приложения в виде написания кода «зацепок» (hooks). Вам остается отделить логику (модель) от шаблона (представления).
Давайте рассмотрим этапы объявления и использования шаблонов в модуле Drupal.
Сформулируем учебную задачу.
На отдельной странице сайта выведем таблицу квадратов чисел из какого то диапазона внутри [0 … 1000]. Оформим это как модуль mymodule.
Создаём раздел и пишем логику
Во-первых, нам нужно объявить раздел, для чего мы используем hook_menu.
1 2 3 4 5 6 7 8 9 10 |
<?php function mymodule_menu() { //раздел сайта, на котором будет таблица с квадратами чисел $items['page-with-table'] = array( 'page callback' => '_mymodule_page', 'access arguments' => array('access content'), 'type' => MENU_NORMAL_ITEM, ); return $items; } |
Для данного раздела, который находится по адресу — mysite.ru/page-with-table, мы сопоставили функцию _mymodule_page. Эта функция будет отвечать за логику данной страницы и должна вернуть её содержимое.
Чтобы управлять диапазоном чисел, для которого будет выводится таблица, мы воспользуемся неявной передачей параметров. Если мы введем адрес вроде:
1 |
mysite.ru/page-with-table/1/20 |
то в функцию-обработчик раздела будут переданы части строки «1» и «20» как входные параметры.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
//по умолчанию, т.е. когда мы не передаём параметры, диапазон будет от 1 до 10 function _mymodule_page($from = 1, $to = 10) { //приведение к числовому типу :) $from += 0; $to += 0; if ($from > $to) { //переставим входные параметры местами, если пользователь их перепутал $_buf = $to; $to = $from; $from = $_buf; } if ($from < 0) { drupal_message('Начало последовательности должно быть >= 0.', 'error'); return ''; } if ($to > 1000) { drupal_message('Окончание последовательности должно быть <= 1000.', 'error'); return ''; } return theme('my-table', $from, $to); } |
В функции мы реализовали всю логику: проверили входные параметры, и передали их в шаблон. Но где брать этот шаблон, какие у него параметры — Drupal не знает. Расскажем Drupal, где находятся шаблоны. Эти сведения предоставляются через hook_theme.
После изменений в hook_menu и hook_theme следует сбрасывать кеш, чтобы новые настройки были прочитаны Drupal. В 6-й версии эти настройки находятся в разделе админки — производительность -/admin/settings/performance.
Объявим шаблоны в модуле, создадим файлы шаблонов
Я хочу разместить файлы шаблонов в отдельной папке активной темы оформления. Шаблонов будет два : общий шаблон HTML таблицы, который мы уже задействовали в _mymodule_page(), и шаблон строк таблицы, который будет вызывать из первого шаблона для каждой строки данных при составлении таблицы.
В документации hook_theme имеет ряд параметров, которые мы не используем. Потому я их на стал перечислять.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
function mymodule_theme() { return array( //аргументы, это параметры функции theme(), //следующие после имени шаблона. //общий шаблон таблицы 'my-table' => array( 'arguments' => array('from' => NULL, 'to' => NULL), 'path' => path_to_theme() . '/table', 'template' => 'table', ), //шаблон строки 'my-table-row' => array( 'arguments' => array('number' => NULL), 'path' => path_to_theme() . '/table', 'template' => 'table-row', ) ); } |
Чтобы указать местоположение файла, я использую параметр path со ссылкой на активную тему path_to_theme(). К нему я прибавляю имя подкаталога. Имена файлов (параметр template) указываются без расширения, т.е. вместо «table-row.tpl.php», я указываю просто «table-row».
Осталось создать шаблоны.
Это шаблон таблицы. Можно использовать специальный php-синтаксис для оформления шаблонов, но я оставляю это на ваше усмотрение.
1 2 3 4 5 6 7 8 9 10 11 |
<!-- /sites/all/themes/gp/table/table.tpl.php --> <table border=1> <tr> <th>Число</th> <th>Квадрат числа</th> </tr> <? for($k = $from; $k <= $to; $k ++) echo theme('my-table-row', $k); ?> </table> |
Шаблон строки таблицы ещё короче.
1 2 3 4 5 |
<!-- /sites/all/themes/gp/table/table-row.tpl.php --> <tr> <td><?=$number?></td> <td><?=$number * $number?></td> </tr> |
В данном примере, где мы вычисляем квадрат числа, функция слишком простая, чтобы передавать расчетные значения в шаблон. Их можно посчитать прямо в шаблоне.
Переносим шаблоны в модуль.
Вообще-то можно было разместить шаблоны прямо в папке нашего модуля mymodule. Это будет логично, если шаблоны необходимы только этому модулю.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
function mymodule_theme() { return array( 'my-table' => array( 'arguments' => array('from' => NULL, 'to' => NULL), 'path' => drupal_get_path('module', 'mymodule') . '/table', 'template' => 'table', ), 'my-table-row' => array( 'arguments' => array('number' => NULL), 'path' => drupal_get_path('module', 'mymodule') . '/table', 'template' => 'table-row', ) ); } |