Form API в Drupal позволяет очень гибко работать с формами. Не важно где и в каком модуле была создана форма, вы всегда можете подключить собственный файл-шаблон или функцию темизации для модификации вывода этой формы.
Как это сделать читайте далее.
Чтобы нам подключить собственное оформление уже существующей формы, нужно выполнить следующие действия:
- Объявить шаблон в hook_theme.
- Зацепиться за нужную форму с помощью hook_form_alter или hook_form_FORM_ID_alter. Установить для формы или её элемента имя объявленного в п1. шаблона.
- Реализовать функцию темизации или файл-шаблон.
Эти этапы актуальны для Drupal любой версии (hook_form_FORM_ID_alter появляется начиная с 6й версии, тогда как hook_form_alter есть и в более ранних).
Разберем каждый из этапов. Наш модуль будет называться — mymodule.
Объявление шаблона в модуле.
Темизация в функции.
Шаблон должен принимать единственный аргумент — объект form API Drupal. Если вы собираетесь использовать не шаблон в отдельном файле, а функцию, которая и вернет HTML код, то минимальное объявление выглядит вот так:
1 2 3 4 5 6 7 |
function mymodule_theme($existing, $type, $theme, $path) { return array( 'some_kind_of_template_name' => array( 'arguments' => array('form' => NULL), ), ); } |
Функция-обработчик должна быть названа следующим образом:
1 2 3 4 5 6 |
function theme_some_kind_of_template_nam($form) { $output = ''; $output .= drupal_render($form['element']); ... return $output . drupal_render($form); } |
Самый простой вариант реализации — использование drupal_render(). Вы скорее всего будете применять данную функцию к каждому элементу формы, вставляя их в нужные места шаблона.
При рендере отдельных элементов, Drupal помечает их специальным флагом. Поэтому, когда вы в конце примените drupal_render ко всему объекту, функция соберет все то, что вы пропустили.
Отдельный файл-шаблон.
Если темизация будет выполнена в отдельном файле-шаблоне, то его имя нужно указать в параметре template, но без указания расширения файла (без tpl.php):
1 2 3 4 5 6 7 8 |
function mymodule_theme($existing, $type, $theme, $path) { return array( 'some_kind_of_template_name' => array( 'arguments' => array('form' => NULL), 'template' => 'my_template_filename', ), ); } |
Файл будет разыскиваться в папке модуля или в папке активной темы. Можно также задать и произвольный путь к файлу шаблона, об этом читайте в описании hook_theme().
Шаблон получит локальную переменную — form, объявленную в hook_theme(). На что стоит обратить внимание при работе с шаблонами?
Аккуратно выбирайте имена файлов и имена ключей для массива в hook_theme. Файлы могут перекрыть известные схемы «suggestions» drupal и ваш шаблон будет использован не по назначению :). Так шаблон form.tpl.php будет использоваться всеми формами проекта.
Здесь мы рассмотрели сразу первый и третий пункты. Осталось лишь сказать пару слов о зацепке к форме.
Подключение шаблона к выбранной форме.
Если вы решили реализовать зацепку hook_form_alter(), то вам будет необходимо отфильтровать нужную вам форму по её ID:
1 2 3 4 5 |
function mymodule_form_alter(&$form, &$form_state, $form_id) { if ($form_id == 'some_form_id') { $form['#theme'] = 'some_kind_of_template_name'; } } |
Начиная с 6-й версии Drupal можно зацепиться сразу к произвольной форме. Для того же some_form_id, как в примере выше, это будет:
1 2 3 |
function mymodule_form_some_form_id_alter(&$form, &$form_state) { $form['#theme'] = 'some_kind_of_template_name'; } |
Объявление хука отличается для разных версий Drupal, этот пример для 6й версии.
Как определить FORM_ID?
Как узнать идентификатор формы? Это просто. Любая форма, сгенерированная form API Drupal, рендерится с соответствующим HTML идентификатором формы. Например, если вы посмотрите форму авторизации на странице /user, то увидите следующий HTML код:
1 |
<form action="/user" accept-charset="UTF-8" method="post" id="user-login"> |
Символ «подчеркивания» идентификатора был преобразован в «минус», а в остальном это искомый form_id — user_login.
Если одна и та же форма была отрендерена несколько раз при создании страницы, то к id будет добавлен порядковый номер. Например:
1 |
<form action="/user" accept-charset="UTF-8" method="post" id="user-login-5"> |