Роман Архаров
Drupal часто ругают за однообразность и узнаваемость дизайна, используемого на Drupal-сайтах. То, что за определенным сайтом стоит CMS Drupal, можно определить не только по URL-адресам специфического вида, узнаваемым путям к папкам модулей и главной странице в виде списка последних опубликованных документов, но и по стандартной двух-трехколоночной структуре сайта, наличию стандартных форм авторизации и поиска, облаков тегов, списков новых документов и других часто используемых блоков.
Однако все эти упреки несправедливы. Здесь можно процитировать старый анекдот: «Вы просто не умеете его готовить». На самом деле к Drupal при должном умении можно «прикрутить» дизайн и верстку любой сложности. Можно до неузнаваемости «темизировать», т. е. изменять внешний вид любого HTML-кода, создаваемого Drupal, – все стандартные формы, блоки, документы и списки. Просто для этого нужно понимать, как Drupal генерирует выходные данные (информация об этом была опубликована в PC Magazine/RE, 9/2009), и уметь переопределять этот вывод. Примеров таких детально темизированных сайтов много, в одной из врезок вы можете найти ссылки на некоторые из них.
В этой статье я расскажу о трех этапах темизации, охватывающих практически 100% задач, связанных с изменением внешнего вида сайта: разработка общего шаблона для всех страниц сайта и «кастомных» шаблонов для избранных страниц; разработка шаблонов для разных типов документов и списков; изменение внешнего вида форм (поиск, авторизация и любые другие стандартные и создаваемые внешними модулями формы).
Но прежде чем переходить к решению задач, познакомимся с основными используемыми терминами и структурой любой «темы оформления».
Тема оформления – это набор файлов, отвечающих за внешний вид сайта. Тема оформления определяет HTML-макет страницы, используемые на ней CSS-файлы и JavaScript. Несмотря на то что шаблоны, используемые в темах оформления, позволяют исполнять PHP-код, в них не должно быть кода, не связанного с отображением информации. Тема оформления должна на входе получать готовые массивы данных, а на выходе создавать из них HTML-код. Логика программы реализуется в модулях.
Для создания тем оформления можно использовать различные шаблонные «движки» (шаблонизаторы), такие как Smarty, PHPTAL и др., однако по умолчанию в системе может быть применен только PHPTemplate – шаблонный «движок», специально разработанный для Drupal. Если надо разработать тему оформления для Drupal с нуля, то рекомендуется использовать именно его, но если на Drupal переносится существующий сайт, для которого уже разработан шаблон на основе одного из альтернативных шаблонизаторов, то можно добавить его, разместив соответствующий «движок» в папке sites/all/themes/engines вашей инсталляции Drupal. Скачать модули, интегрирующие Drupal с внешними шаблонизаторами, можно по ссылке http://drupal.org/project/Theme+engines.
Все страницы разделяются на регионы – области страницы, каждая из которых может содержать один или несколько блоков с данными. Например, по умолчанию большинство стандартных тем оформления состоит из пяти регионов: левая и правая колонка, шапка, подвал сайта и регион с основным его содержимым. Такой макет страницы наиболее популярен, поскольку удовлетворяет требованиям большинства пользователей; с его помощью удобно строить новостные сайты и блоги. Однако это не означает, что все сайты, использующие Drupal, должны иметь такую структуру. Разработчик может определять в макете страницы любое количество дополнительных регионов и размещать их в любых самых неожиданных местах.
Блок – это набор особым образом сформатированных данных. Внешний вид и содержимое блока определяются создающим его модулем и функциями темизации (подробнее об этих функциях см. PC Magazine/RE, 9/2009), а расположение – администратором сайта. Используя специальный графический интерфейс, администратор может методом буксировки (drag-and-drop) разместить любой блок системы в любом из доступных регионов. Примером блока может служить форма входа в систему или облако тегов.
Вместо разработки собственной темы оформления можно скачать и установить на своем сайте одну из готовых тем. Многие темы могут быть детально настроены через интерфейс администратора: вы сможете изменить цветовую гамму, число колонок, ширину колонки с основным контентом и логотип сайта, не изменяя код шаблона. Кроме того, всегда можно доработать для себя любую из существующих тем оформления.
Если вас устраивает такой вариант, то вы можете дальше не читать этот текст, а поэкспериментировать с темами оформления, ссылки на которые приведены во врезке. Дальше рассказ пойдет об анатомии темы оформления для «движка» PHPTemplate.
• http://blogroll.pcmag.ru – система мониторинга ИТ-блогов, специальный проект PC Magazine/RE
• http://zerut.ru – сборник карикатур лучших зарубежных авторов. Здесь темизировано все: списки документов, форма входа, облако тегов и т. д.
• http://www.chopped-tomatoes.com – Интернет-магазин на Drupal.
• http://www.csspig.com – галерея сайтов.
• http://designslices.com – еще один красивый Drupal-сайт.
• Список 70 самых красивых Drupal-сайтов можно найти на http://mogdesign.eu/blog/70-beautiful-drupal-sites/.
• В блоге Дриса Байтаерта, создателя Drupal, публикуются самые интересные, причем не только с точки зрения дизайна, Drupal-сайты (см. http://buytaert.net/tag/drupal-sites).
Как и в случае с модулем, разработка которого рассматривалась в предыдущей статье, тема оформления должна иметь уникальное имя, состоящее из строчных латинских букв, цифр и знаков подчеркивания, и это имя должно начинаться с буквы. Тема оформления – это несколько файлов, которые располагаются в папке sites/all/themes/имя_темы относительно корня Drupal.
PHPTemplate при сборке страницы берет информацию из пяти основных файлов: имя_темы.info, page.tpl.php, node.tpl.php, block.tpl.php, template.php. Если же включен модуль comment, для вывода комментариев используется шаблон comment.tpl.php.
Файл имя_темы.info содержит служебную информацию: название и описание темы оформления, список используемых в ней *.css– и *.js-файлов и список регионов (ссылку на подробное описание всех параметров, используемых в *.info-файле темы, можно найти во врезке в конце статьи). Данные, находящиеся в этом файле, кэшируются в базе данных, и чтобы внесенные в него изменения вступили в силу, нужно этот кэш сбросить. Самый простой способ сделать это – просто зайти на страницу со списком тем и нажать кнопку Save configuration; при этом сбросится только закэшированная информация из *.info-файла, но не весь кэш сайта.
Page.tpl.php – это основной шаблон, в нем размещается HTML-код всей страницы, которая позже будет выведена пользователю. В частях страницы, где будет выводиться содержимое регионов и основной текст, должны располагаться соответствующие переменные. Например, если в *.info-файле не указано иное, то в каждой теме оформления присутствует пять основных регионов (их описание я давал выше), которые представлены переменными $left, $right, $header, $footer, $content. В первых четырех переменных выводятся блоки, размещенные в соответствующих регионах, в переменной $content находится основное содержимое страницы, а это или шаблон node.tpl.php (если просматривается документ, – например, новость или запись в блоге) с выведенными в нем данными, или страница, созданная каким-либо модулем, – например, список, генерируемый модулем Views.
1 – основной шаблон страницы, определяется в файле page.tpl.php;
2-1 – регион «левая колонка» (определяется переменной $left в шаблоне page.tpl.php);
2-2 – регион «основное содержимое страницы» ($content),
2-3 – регион «подвал сайта» ($footer);
3 – блоки, размещенные в левой колонке, определяются шаблонами block.tpl.php или его модификациями (block-region.tpl.php и др.);
4 – документы из «ленты новостей», определяются шаблоном node.tpl.php или его модификациями (например, node-имя_типа_контента.tpl.php).
Кроме переменных, содержащих видимые пользователю данные, в шаблоне page.tpl.php должно размещаться несколько служебных переменных. Скажем, между тегами
страницы располагаются переменные $head, $styles, $scripts. В этих переменных Drupal собирает HTML-код, добавляющий к странице мета-теги, файлы стилей и java-скрипты соответственно. Наличие этих трех переменных позволяет программистам в своих модулях, используя API-функции drupal_add_css(), drupal_add_js() и некоторые другие, добавлять к странице свои стили или другие файлы, не изменяя файлов темы оформления.В файле page.tpl.php, кроме перечисленных выше, может находиться еще десяток переменных, выполняющих разные функции: $primary_links, $secondary_links, $search_box, $tabs, $messages, $breadcrumbs, $closure и т. д. Все они важны. При необходимости описание всех доступных в page.tpl.php переменных можно найти по ссылке, размещенной во врезке в конце статьи.
• Темы оформления, позволяющие менять цветовую схему через интерфейс администратора: Pixture Reloaded (http://drupal.org/project/pixture_reloaded), Dropshadow (http://drupal.org/project/dropshadow), Wabi (http://drupal.org/project/wabi), Garland (стандартная тема Drupal).
• Темы оформления, обладающие множеством настроек и регионов: Deco (http://drupal.org/project/deco), Acquia Marina (http://drupal.org/project/acquia_marina).
Часто бывает нужно создать разное оформление для страниц сайта. Движок PHPTemplate имеет необходимые для этой задачи возможности. Чтобы задать свой шаблон для определенной страницы, следует в папке с темой оформления создать копию файла page.tpl.php и присвоить ей имя, соответствующее одной из масок: page-front.tpl.php будет использоваться как шаблон для главной страницы сайта; а page-путь_к_внутренней_странице.tpl.php – как шаблон для указанной внутренней страницы; page-node.tpl.php – при просмотре материала; page-node-nid.tpl.php, где nid – id документа – при просмотре документа с указанным id; page-node-edit.tpl.php используется при редактировании документа. Кроме того, вы можете использовать шаблоны maintenance-page.tpl.php и maintenance-page-offline.tpl.php, которые будут выводиться в случае ошибок соединения с базой данных или в случае первода сайта в offline-режим.
Node.tpl.php – шаблон, по умолчанию используемый для вывода содержимого документа. В шаблоне node.tpl.php размещается HTML-код, задающий форматирование документов, таких как Страницы (Page) и Новости (Story); в нем доступны переменные $title, $teaser, $content, содержащие заголовок, анонс и полный текст документа, а также ряд служебных переменных.
При просмотре страницы, скажем, с текстом новости выводится шаблон страницы page.tpl.php, в котором в регионе, отведенном для вывода основного содержимого (переменная $content), размещается содержимое шаблона node.tpl.php. Как и в случае с общим макетом страницы (page.tpl.php), для каждого типа документа может быть определен свой шаблон – так, часто для новостей используется один макет, для статических страниц другой, а для фотографий – третий. Чтобы определить свой шаблон для каждого типа контента, в папке с темой оформления нужно создать копию файла node.tpl.php и дать ей имя node-имя_типа_контента.tpl.php, т. е., например, файл node-blog.tpl.php будет использоваться для отображения записей в блоге, а node-book.tpl.php – для отображения страниц книги.
Block.tpl.php – определяет внешний вид блока; как и в случае с материалами, шаблон блока может быть задан для каждого модуля (блоки, создаваемые модулем user, будут использовать один шаблон, а блоки, создаваемые модулем block, – другой) или для каждого блока в отдельности. Маски имен файлов шаблонов для блоков имеют вид: шаблон block-module_name.tpl.php и используется для всех блоков, создаваемых модулем module_name; шаблон block-module_name-delta.tpl.php может использоваться в случае, если модуль создает несколько блоков и вы хотите каждому из них задать свой шаблон. Параметр delta – это id блока, который задается создающим его модулем. Шаблон block-region.tpl.php служит для отображения блока в определенном регионе.
Каждый модуль, написанный с применением слоя темизации Drupal, должен разделять функции, генерирующие данные, и функции темизации, оформляющие эти данные в виде HTML-кода. Функции темизации регистрируются модулями через специальный хук hook_theme() и имеют имена, начинающиеся с префикса theme_, например, theme_list(). Такие функции не реализуют никакой бизнес-логики, а только получают набор данных на входе и отдают сформированный HTML-код на выходе. Функции темизации могут быть переопределены в файле template.php, т. е. разработчик может заменить стандартное оформление данных, возвращаемых модулем, по своему желанию. Для этого нужно скопировать в него соответствующую функцию темизации, заменить в ней префикс theme_ на имя используемой темы и внести в нее необходимые изменения.
Из всех перечисленных выше файлов обязательный только *.info, в случае отсутствия в папке с темой файлов page.tpl.php, node.tpl.php, block.tpl.php или template.php будут использоваться стандартные шаблоны. Ссылку на список стандартных шаблонов можно найти в конце статьи.
Обычно *.info-файл темы оформления содержит конфигурационные данные (см. листинг 1). В первых двух строчках файла обычно указывается имя и дается описание темы оформления, которое будет выводиться в интерфейсе администратора в списке доступных тем. Далее указываются версия ядра Drupal, для которой написана эта тема, и используемый шаблонизатор.
name = Theme name
description = Theme description.
version = VERSION
core = 6.x
engine = phptemplate
stylesheets[all][] = style.css
stylesheets[print][] = print.css
scripts[] = effects.js
scripts[] = menu.js
regions[left] = Left sidebar
regions[content] = Content
regions[header] = Header
regions[footer] = Footer
Параметры stylesheets определяют список CSS-файлов, которые будут подключены ко всем страницам. В первой паре квадратных скобок через запятую может быть указан список параметров, присваиваемых атрибуту media HTML-тега link (подробную информацию о назначении этого атрибута можно найти по ссылке во врезке в конце статьи). Из перечисленных здесь имен файлов, а также из файлов стилей, которые подключены модулями через функцию drupal_add_css(), будет сформирован HTML-код, подключающий указанные стили и доступный в шаблоне page.tpl.php в переменной $styles. Кроме того, шаблонизатор попытается найти в папке с темой оформления файл style.css; если он есть, то он также будет подключен к странице.
Аналогичное назначение и у параметра scripts. Перечисленные в нем JavaScript, а также сценарии, добавленные модулями через функцию drupal_add_js(), будут подключены ко всем страницам сайта. Если в папке с темой оформления есть файл script.js, он также будет подключен к каждой странице.
Параметры regions определяют список доступных в шаблоне page.tpl.php регионов. Значение в скобках станет PHP-переменной, например $left или $footer (поэтому здесь недопустимо использовать пробелы, дефисы и другие запрещенные в именах PHP-переменных символы), а значение после знака «равно» – именем региона, доступным на странице управления блоками.
Файл 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'),
);
$form["submit"] = array(
'#type' => 'submit',
'#value' => t('Submit'),
);
$form["#validate"] = array('test_validate_first',
'test_validate_second');
$form["#submit"] = array('test_submit_first',
'test_submit_second');
return $form;
}
function test_validate_first($form, &$form_state) {
if(mb_strlen($form_state['values']['example_text_field']) < 3) {
form_set_error('example_text_field', t('Text must contain more then 3 symbols'));
}
}
function test_validate_second($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_submit_first($form, &$form_state) {
drupal_set_message('First submitter');
drupal_set_message("textbox: " . $form_state['values']['example_text']);
}
function test_submit_second($form, &$form_state) {
drupal_set_message('Second submitter');
drupal_set_message("selectlist: " . $form_state['values']['example_select']);
}
Здесь добавлен валидатор, который проверяет текст, введенный в текстовое поле; если его длина оказывается меньше трех символов, то генерируется сообщение об ошибке.
При создании форм всегда рекомендуется использовать не стандартные валидаторы и сабмиттеры, а объявлять их явно, так как в этом случае сторонние программисты смогут дополнить массивы #submit и #validate своими функциями. Если используются стандартные валидаторы и сабмиттеры, то сторонние программисты смогут только заменить существующие функции своими, а это не всегда удобно.
Signwriter. Часто бывает необходимо использовать в заголовке страницы или меню какой-либо экзотический шрифт, отсутствующий у большинства посетителей сайта. Модуль Signwriter генерирует картинки с текстом, написанным заданным шрифтом (шрифт предварительно должен был закачан на сервер). Через меню администратор может включить замену заголовков страниц и блоков созданными картинками, а через специальную функцию и вовсе можно заменить картинками любой текст.
Blocktheme. Не всегда удобно создавать и закачивать на сервер шаблоны под каждый используемый на сайте блок. Кроме того, реализованная в Drupal система масок имен для шаблонов не для всех задач бывает достаточно гибкой. Модуль Blocktheme позволяет через интерфейс управления блоками выбрать для каждого из них один из заранее созданных шаблонов.
Devel. Мощный инструмент в руках Drupal-разработчика. Разработчику тем оформления модуль Devel предоставляет информацию обо всех используемых для генерации страницы шаблонах и функциях темизации.
PNG Fix. Модуль, исправляющий проблему с непрозрачностью PNG-файлов в браузерах IE 5.5 и IE 6. Настраивается работа модуля через интерфейс администратора, изменение файлов темы оформления не требуется.
Теперь вернемся к основной теме статьи – темизации Drupal. Функция drupal_get_form, получив на вход $form_id, идентификатор формы, которую нужно вывести на экран, вызывает функцию form_builder, проверяющую права доступа текущего пользователя к каждому из полей формы, и при наличии этих прав выводит стандартный HTML-код для каждого элемента формы. Каждый созданный элемент формы имеет уникальный атрибут id. Самый простой способ переопределения внешнего вида элементов формы – создание CSS-файла с описанием стилей нужных элементов формы. Если этого недостаточно, элементам формы можно добавить параметры #prefix и #suffix, которые будут содержать HTML-код, выводимый до и после созданного элемента. Если и этого мало, можно определить параметр #theme, который должен содержать используемое имя функции темизации.
Персональные функции темизации можно задать для всей формы целиком или для каждого ее элемента. По умолчанию Drupal для темизации формы пробует найти функцию theme_form_id, поэтому использование параметра #theme не обязательно.
Все функции, определенные параметром #theme, должны быть также объявлены через hook_theme (описание этого хука было дано в предыдущей статье).
Давайте изменим внешний вид созданного текстового поля. Для этого сначала создадим реализацию хука hook_theme:
function название_модуля_theme() {
return array(
'example_text_field_theme_function' => array(
'arguments' => array('form' => NULL),
),
);
}
Затем модифицируем массив $form["example_text_field"], который создается в функции test_form, добавив в него параметр #theme:
$form["example_text_field"] = array(
'#type' => 'textfield',
'#title' => 'Example text field',
'#description' => 'Text must contain more then 3 symbols',
'#theme' => 'example_text_field_theme_function',
);
Теперь мы можем объявить функцию theme_example_text_field_theme_function и задать в ней любой HTML-код для отображения выбранного элемента:
function theme_example_text_field_theme_function($element) {
$class = "";
if(isset($element["#needs_validation"])) {
$class = " error";
}
$output = '
class="form-item">
class="form-text' . $class . '" name="' . $element["#name"]
. '">
return $output;
}
Кроме того, эту функцию можно переопределить, не изменяя кода модуля. Для этого в файле template.php, который находится в папке с текущей темой оформления, нужно создать копию этой функции, заменив в ней префикс theme на имя текущей темы.
Если в реализации hook_theme использовать параметр template, например, так:
function название_модуля_theme() {
return array(
'example_text_field_theme_function' => array(
'arguments' => array('form' => NULL),
'template' => 'example-text-field',
),
);
}
то HTML-код, ответственный за отображение элемента Web-страницы в браузере, можно будет задавать не в исходном тексте функции темизации, а в отдельном файле-шаблоне с соответствующим именем; в нашем примере это example-text-field.tpl.php. Такой подход удобен, если с сайтом должны работать дизайнеры, не имеющие опыта Web-программирования.
Если же возникла необходимость изменить внешний вид всей формы, а не только отдельных ее элементов, нужно проделать то же самое: указать значение параметра #theme формы, объявить в hook_theme функцию темизации и, наконец, реализовать ее. Давайте внесем необходимые изменения в наш код. Функция hook_theme будет выглядеть следующим образом:
function название_модуля_theme() {
return array(
'test_form_theme_function' => array(
'arguments' => array('form' => NULL),
),
'example_text_field_theme_function' => array(
'arguments' => array('form' => NULL),
),
);
}
Исходный текст обновленной функции test_form приводится в листинге 6.
function test_form($form_state) {
$form['#theme'] = 'test_form_theme_function';
$form["example_text_field"] = array(
'#type' => 'textfield',
'#title' => 'Example text field',
'#description' => 'Text must contain more then
3 symbols',
'#theme' => 'example_text_field_theme_function',//*/
);
$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'),
);
$form["#validate"] = array('test_validate_first',
'test_validate_second');
$form["#submit"] = array('test_submit_first',
'test_submit_second');
return $form;
}
Также нам потребуется и сама функция темизации формы. Определим ее:
function theme_test_form_theme_function($form) {
$output = "Some additional text";
// Выводим некоторые элменты отдельно с дополнительным
// форматированием
$output .= '
$output .= drupal_render($form['example_text_field']);
$output .= "
// Выводим остальные элементы, которые не были выведены
// ранее
$output .= drupal_render($form);
return $output;
}
Как и с любой другой функцией темизации, ее содержимое можно вынести во внешний шаблон.
Ну а теперь осталось научиться модифицировать из внешнего модуля существующую форму. Для решения этой задачи нужно воспользоваться одним из двух хуков: или hook_form_alter, через который проходят массивы всех обрабатываемых форм и в котором каждый массив можно отредактировать, или hook_form_form_id_alter, где form_id должен быть заменен на идентификатор нужной формы. Через этот хук проходит только выбранная форма. На вход оба этих хука получают массив формы (в нашем примере это массив, который генерируется функцией test_form), и в этот массив могут быть добавлены или из него могут быть удалены любые параметры: #theme, #prefix, #suffix, #submit, #validate и другие.
Для примера добавим к форме контейнер, который может содержать в себе несколько полей. Переместим в него два поля и сменим заголовок одного из них:
function название_модуля_form_test_form_alter(&$form,
&$form_state) {
$form["example_text_field"]["#title"] = "New title";
$form["example_add_field"] = array(
'#type' => 'fieldset',
'#title' => 'new fieldset',
'#collapsible' => TRUE,
'#collapsed' => FALSE,
'#weight' => 0,
);
foreach ($form as $name => $element) {
if($element["#type"] == "select" || $element["#type"] ==
"textfield") {
$form["example_add_field"][$name] = $element;
unset($form[$name]);
}
}
$form["submit"]["#weight"] = 5;
}
Вот и все. В этой статье я рассказал об основных принципах темизации Drupal, более подробную информацию вы можете найти в документации.
Компьютеры
Компания Dell (www.dell.ru) объявила о выпуске пяти игровых систем под маркой Alienware. Модель Alienware M15x – «самый мощный игровой ноутбук во Вселенной» – выполнен в оригинальном дизайне Alienware, оснащен мобильным процессором Core i7 и графическим процессором NVIDIA GeForce GTX 260M. Ориентировочная цена – 84 990 руб. Alienware Aurora и Aurora ALX – мощные настольные системы форм-фактора MicroATX с процессорами Intel Core i7 (включая модификации Extreme Edition, разогнанные до 3,6 ГГц). Цена в базовой конфигурации – 79 990 руб. Системы Alienware Area-51 и Area-51 ALX разработаны для геймеров-экстремалов и энтузиастов, оснащаются процессорами Intel Core i7, графическими адаптерами с NVIDIA GeForce GTX 295, ОЗУ емкостью до 12 Гбайт. В корпусах предусматриваются шесть легко доступных «бескабельных» отсеков для жестких дисков и возможность организации массивов RAID 0, RAID 1 и RAID 10.
Ноутбуки
Компания ASUS (www.asus.ru) заверяет, что длительное использование аккумуляторной батареи, изготовленной независимым партнером в 2007 г., может представлять опасность лишь в редких случаях. Чтобы гарантировать пользователям своей продукции безопасную работу, компания по своей инициативе объявляет о программе бесплатной замены всех дефектных батарей. Эта программа применяется исключительно к батареям, изготовленным в 2007 г. независимым производителем и входящим в комплект поставки ноутбуков ASUS PRO52 и X51. Батареи, попавшие в список, приведенный в данной программе, будут заменены всем пользователям ноутбуков, независимо от наличия гарантии на ноутбук или батарею на момент обращения в сервисный центр.
Проекты
Компания Cognitive Technologies (www.cognitive.ru) объявила о начале опытной эксплуатации системы массового ввода документов Cognitive Forms в компании «Натали Турс». Цель проекта – автоматизация обработки анкет в ходе исследования мнений потребителей о качестве предоставляемых услуг. Главная особенность системы, внедряемой в «Натали Турс», – ее континентальная распределенность: 20 станций сканирования планируется установить в 11 странах. С их помощью анкеты, собранные гидами во время следования туристов в аэропорт, будут переводиться в электронный вид и отправляться в центральный офис компании.