Как использовать файл шаблона для темы в форме?
В то время как узлы, комментарии, блоки и многое другое в Drupal тематизируются с использованием файлов шаблонов тем (например, node.tpl.php), формы - это разные истории. Для форм нет шаблонных файлов тем. Как я могу получить конкретную форму для использования настраиваемого шаблона темы?
7 ответов
Вполне разумно, чтобы использовать tpl-файл для отображения формы. Вы можете использовать множество посторонних CSS и #prefix
/#suffix
для достижения аналогичных результатов, но с помощью tpl вам не нужно загромождать разделение вашей логики и уровни представления, и не нужно настраивать уродливые CSS-селектора, такие как #user-login label
. Вот пример в Drupal 7 ...
MyTheme /template.php:
function mytheme_theme($existing, $type, $theme, $path) {
// Ex 1: the "story" node edit form.
$items['story_node_form'] = array(
'render element' => 'form',
'template' => 'node-edit--story',
'path' => drupal_get_path('theme', 'mytheme') . '/template/form',
);
// Ex 2: a custom form that comes from a custom module's "custom_donate_form()" function.
$items['custom_donate_form'] = array(
'render element' => 'form',
'template' => 'donate',
'path' => drupal_get_path('theme', 'mytheme') . '/template/form',
);
return $items;
}
custom_donate_form ():
function custom_donate_form($form, &$form_state) {
$form['first_name'] = array(
'#type' => 'textfield',
'#attributes' => array('placeholder' => t('First name')),
);
$form['last_name'] = array(
'#type' => 'textfield',
'#attributes' => array('placeholder' => t('Last name')),
);
$form['address'] = array(
'#type' => 'textfield',
'#attributes' => array('placeholder' => t('Address')),
);
$form['city'] = array(
'#type' => 'textfield',
'#attributes' => array('placeholder' => t('City')),
);
$form['state'] = array(
'#type' => 'select',
'#options' => array(
'default' => 'State',
'...' => '...',
),
);
$form['zip'] = array(
'#type' => 'textfield',
'#attributes' => array('placeholder' => t('Zip')),
);
$form['email'] = array(
'#type' => 'textfield',
'#attributes' => array('placeholder' => t('Email')),
);
$form['phone'] = array(
'#type' => 'textfield',
'#attributes' => array('placeholder' => t('Phone')),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Submit',
);
return $form;
}
MyTheme /шаблон /форма /donate.tpl.php:
<div class="row">
<div class="small-12 medium-12 large-8 columns">
<div class="row">
<div class="small-12 columns">
<h5>Contact Information</h5>
</div>
</div>
<div class="row">
<div class="small-12 large-6 medium-6 columns">
<?php print render($form['first_name']); ?>
</div>
<div class="small-12 large-6 medium-6 columns">
<?php print render($form['last_name']); ?>
</div>
</div>
<div class="row">
<div class="small-12 medium-6 large-6 columns">
<?php print render($form['address']); ?>
</div>
<div class="small-12 medium-6 large-6 columns">
<?php print render($form['city']); ?>
</div>
</div>
<div class="row">
<div class="small-12 medium-3 large-3 columns">
<?php print render($form['state']); ?>
</div>
<div class="small-12 medium-3 large-3 columns">
<?php print render($form['zip']); ?>
</div>
<div class="medium-6 large-6 columns"></div>
</div>
<div class="row">
<div class="small-12 medium-6 large-6 columns">
<?php print render($form['email']); ?>
</div>
<div class="small-12 medium-6 large-6 columns">
<?php print render($form['phone']); ?>
</div>
</div>
</div>
<div class="row">
<div class="small-12 medium-12 large-8 large-offset-2 columns">
<?php print render($form['submit']); ?>
</div>
</div>
</div>
<!-- Render any remaining elements, such as hidden inputs (token, form_id, etc). -->
<?php print drupal_render_children($form); ?>
Это использует Foundation , который дает нам такую форму:
Вы должны реализовать hook_form_alter () в модуле или template.php и установить свойство #theme формы:
/**
* Implements hook_form_alter().
*/
function hook_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'user_login') {
$form['#theme'] = array('overwrite_user_login');
}
}
Затем создайте новую тему:
/**
* Implements hook_theme().
*/
function hook_theme($existing, $type, $theme, $path){
return array(
'overwrite_user_login' => array(
'render element' => 'form',
'template' => 'form--user_login',
'path' => $path . '/templates',
),
);
}
И затем добавьте шаблон формы - user_login.tpl.php с последующим кодом для визуализации формы:
<?php print drupal_render_children($form) ?>
Несмотря на то, что вы можете использовать решение kiamlaluno, я лично этого не сделал.
В чем причина использования файла шаблона для формы? Если это потому, что вы хотите немного другую разметку для существующей формы? Если это так, вы можете использовать hook_form_alter()
, чтобы изменить форму перед ее визуализацией. Используя API форм, вы можете изменить все поля формы, введя html-элементы и т. Д.
Вот пример hook_form_alter()
, который я создал, который изменяет стандартный блок формы входа в drupal:
/**
* Implements hook_form_alter().
*/
function MYMODULE_form_alter(&$form, &$form_state, $form_id) {
switch ($form_id) {
case 'user_login_block':
// Form modification code goes here.
$form['divstart'] = array(
'#value' => '<div style="background-color: red;">',
'#weight' => -1,
);
$form['instruct'] = array(
'#value' => '<p>Enter your username and password to login</p>',
'#weight' => 0,
);
$form['divend'] = array(
'#value' => '</div>',
'#weight' => 4,
);
break;
}
}
В приведенном выше примере обертывается вся форма внутри DIV, которая имеет встроенный стиль, чтобы цвет фона был красным. Он также добавляет абзац текста справки к началу формы.
Вот как выглядит моя пользовательская форма входа, как только загружен приведенный выше код:
Для получения дополнительной информации см. ссылку API API: Форма Справочник API
Мне никогда не нужно было использовать файл шаблона для формы.
Насколько я вижу, основной код Drupal использует функции темы, когда форма или часть формы должны отображаться определенным образом; функция темы, которая вызывает drupal_render () , как правило, достаточно для любого целей.
Чтобы ответить на вопрос, создание файла шаблона для формы не отличается от создания файла шаблона, который не для формы.
Определите функцию темы, используя в качестве функции темы имя обратного вызова построителя формы. Код должен быть похож на следующий:
/**
* Implementation of hook_theme().
*/
function mymodule_theme() {
return array(
'mymodule_form' => array(
'template' => 'mymodule-form',
'file' => 'mymodule.admin.inc',
'arguments' => array('form' => NULL),
),
);
}
Если форма содержит значение $form['field_1']
, его значение будет доступно в файле шаблона как $field_1
. Файл шаблона также сможет использовать любые значения, переданные из template_preprocess_mymodule_form()
.
Я бы всегда стилизовал, добавив в свой CSS-файл с помощью селекторов, чтобы идентифицировать элемент, который будет выглядеть следующим образом для основной формы входа
#user-login
{
border:1px solid #888;
padding-left:10px;
padding-right:10px;
background-image: url(http://www.zaretto.com/images/zlogo_s.png);
background-repeat:no-repeat;
background-position:right;
}
#user-login label
{
display: inline-block;
}
Выше я просто добавляю к sites/all/themes/theme-name/css/theme-name.css
Если то, что вам нужно для стиля, не имеет идентификатора или достаточно точного селектора, тогда необходимо использовать подход hook
, чтобы изменить HTML, также добавляя идентификаторы.
IMO, использующий встроенный стиль для элементов, - это очень плохая практика , которая должна быть устаревшей и заменена с помощью class
и id
Для темы формы вы можете использовать пользовательский css, как описано в Тема Drupal 7 Forms (включая CSS и JS) .
В основном вам необходимо выполнить следующие действия:
- Зарегистрируйте путь к форме, используя hook_menu ()
- Определите форму
- Зарегистрировать функцию темы с помощью hook_theme ()
- Введите функцию темы
- Создайте файлы CSS и JavaScript
Я уверен, что вы можете использовать шаблон для форм, но вы должны использовать hook_theme для регистрации шаблона в первую очередь. У меня была ситуация, когда форма действительно должна была быть основанной на таблицах, а не на основе div, а простые изменения #prefix и #suffix на самом деле не разрезали ее. Если интересно, я мог бы, вероятно, попытаться выкопать пример.