Файл page.tpl.php при использовании приведенного выше *.info-файла может иметь структуру подобную приведенной в листинге 2. Это очень простой пример, призванный продемонстрировать общую логику разработки темы оформления для Drupal, поэтому здесь опущено много деталей. Лучший способ научиться темизировать Drupal – изучить существующую тему оформления, например тему Zen. Она содержит детальное описание всех используемых стилей и переменных.
Переменные $header, $left и $footer в нашем примере будут заполнены HTML-кодом блоков, которые администратор сайта разместит в соответсвующих регионах. В переменной $head_title будет находиться загловок страницы, «склеенный» Drupal из имени сайта и заголовка текущей страницы, а переменные $head, $styles и $scripts будут заменены соответственно метатегами, ссылками на файлы стилей и JavaScript.
Переменная $content в шаблоне page.tpl.php заменится на содержимое текущей страницы, например на тело документа (шаблон node.tpl.php) или содержимое, генерируемое каким-либо модулем. Если в текущей теме оформления нет файла node.tpl.php, то используется одноименный файл из ядра Drupal, находящийся в папке modules/node.
Views – один из самых востребованных модулей для Drupal – позволяет создавать списки документов (представления, view), отфильтрованные по любому сложному алгоритму. На выходе модуль возвращает массив данных, который выводится в шаблоне, соответствующем выбранному администратором типу отображения (display) данных. Каждое представление может быть отображено в виде таблицы, маркированного списка, решетки (grid) и т. п. Чтобы переопределить используемый для отображения представления шаблон, нужно в свойствах представления в блоке Basic settings найти параметр Theme information и посмотреть в нем имена шаблонов, которые могут быть использованы модулем для отображения текущего представления. Затем нужно в подпапке theme модуля Views найти шаблон, соответствующий выбранному типу отображения (например, views-view-table.tpl.php для табличного варианта отображения или views-view-list.tpl.php для списка), скопировать его в папку с текущей темой оформления и присвоить ему одно из имен, перечисленных в Theme information. Теперь созданный шаблон можно настроить для своих нужд.
В шаблоне node.tplp.php доступно несколько переменных, самые важные из них: $title – заголовок документа, $node – объект, содержащий полную информацию о текущем документе, $submitted – HTML-код, содержащий информацию об авторе документа, $content – основное содержимое (тело) текущего документа. Не путайте переменную $content из шаблона node.tpl.php с одноименной переменной из шаблона page.tpl.php. В первой есть только «тело» текущего документа без дополнительной информации (автор, дата публикации и т. д.), а во второй – полный HTML-код, который будет показан пользователю в регионе content. Например, при просмотре ленты последних новостей переменная $content каждой новости будет содержать текст одной новости, а переменная $content в шаблоне page.tpl.php – HTML-код всех выводимых новостей (см. врезку «Описание схемы страницы»).
Самый простой пример шаблона node.tpl.php см. в листинге 3. Все переменные, которые выводятся в шаблоне page.tpl.php, могут быть переопределены в функции phptemplate_preprocess_page(), размещенные в файле template.php текущей темы оформления. Аналогично все переменные шаблона node.tpl.php могут быть переопределены в функции phptemplate_preprocess_node(). Кроме того, в этих функциях могут быть определены дополнительные переменные, которые станут доступны в соответствующих шаблонах. Пример практического использования данных функций можно найти в документации (http://api.drupal.ru) или в одной из существующих тем оформления – например, приведенных во врезке «На заметку: готовые решения».
} ?>
print " node-unpublished";
} ?>">
Прежде чем говорить об изменении внешнего вида форм, ознакомимся с основами Drupal Forms API – программного интерфейса, используемого для генерации форм. Применение Forms API несколько сложнее создания HTML-форм вручную, так как требует изучения логики его работы, однако его использование обязательно, поскольку Forms API решает ряд важных задач:
• любой разработчик может добавить или удалить элементы в форме, созданной другим разработчиком, не меняя ее исходного кода;
• любой разработчик может добавить дополнительные функции проверки и обработки введенных пользователем данных без изменения исходной формы;
• формы, созданные с использованием Forms API, защищены от атак, связанных с отправкой пользователем модифицированной формы;
• любой разработчик может изменить внешний вид формы, не изменяя ее исходного кода.
Каждая форма в Drupal представляет собой функцию, возвращающую ассоциативный массив. Этот массив должен содержать информацию обо всех элементах формы, функциях проверки (валидаторы, validators) и обработки (сабмиттеры, submitters) введенных данных. Данная функция должна быть расположена в файле модуля, о разработке модуля говорилось в статье, опубликованной в PC Magazine/RE, 9/2009.
Рассмотрим простой пример.
function test_form($form_state) {
$form["example_text_field"] = array(
'#type' => 'textfield',
'#title' => 'Example text field',
);
$options = array(
0 => 'zero',
1 => 'one',
2 => 'two',
);
$form["example_select"] = array(
'#type' => 'select',
'#title' => 'Example select list',
'#options' => $options,
'#description' => t('You can select only value "one" in this
form'),
);
$form["submit"] = array(
'#type' => 'submit',
'#value' => t('Submit'),
);
return $form;
}
Приведенная выше функция генерирует форму, состоящую из текстового поля, выпадающего списка с тремя элементами и кнопкой для отправки данных. Имя этой функции – ее уникальный идентификатор ($form_id), который будет использоваться для отображения и изменения данной формы сторонними модулями. Чтобы вывести форму на экран, нужно через hook_menu создать страницу, где будет вызвана функция drupal_get_form, принимающая в качестве параметра $form_id формы, которая должна быть отображена на экране:
function имя_модуля_menu() {
$items = array();
$items['test-form'] = array(
'title' => 'Test form',
'page callback' => 'test_form_page',
'access arguments' => array('access content'),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
function test_form_page() {
return drupal_get_form('test_form');
}
В массиве, возвращаемом функцией test_form($form_state), не определены процедуры проверки значений и заполнения полей (структур), поэтому ядро Drupal после нажатия на форме кнопки Submit попробует найти и выполнить функции form_id_validate и form_id_submit. В нашем случае, как легко догадаться, это будут функции с именами test_form_validate и test_form_submit:
function test_form_validate($form, &$form_state) {
if($form_state['values']['example_select'] != 1) {
form_set_error('example_select', t('You must select value
"one" in select list :)'));
}
}
function test_form_submit($form, &$form_state) {
drupal_set_message('Form sumitted! Values:');
drupal_set_message("textbox: " .
$form_state['values']['example_text']);
drupal_set_message("selectlist: " .
$form_state['values']['example_select']);
}
Функция-валидатор проверяет выбранное в выпадающем списке значение и, если оно не one, посылает сообщение об ошибке с указанием, какой элемент формы вызвал ошибку. Функция-сабмиттер выводит на экран введенные пользователем значения. В реальном случае эта функция должна будет сохранить данные в базе данных.
При желании программист может в массиве $form функции test_form задать свойство #submit, содержащее массив обработчиков значений и свойство #validate с массивом валидаторов (см. листинг 4). Зеленым цветом выделены строки, добавленные к ранее описанным функциям. Код модуля также дополнится функциями из листинга 5.
function test_form($form_state) {
$form["example_text_field"] = array(
'#type' => 'textfield',
'#title' => 'Example text field',
'#description' => 'Text must contain more then
3 symbols',
);
$options = array(
0 => 'zero',
1 => 'one',
2 => 'two',
);
$form["example_select"] = array(
'#type' => 'select',
'#title' => 'Example select list',
'#options' => $options,
'#description' => t('You can select only value "one"
in this form'),