Как использовать файл шаблона для оформления формы?


В то время как узлы, комментарии, блоки и многое другое в Drupal тематизируются с использованием файлов шаблонов тем (например node.tpl.php), формы - это совсем другая история. Для форм нет файлов шаблонов тем. Как я могу заставить конкретную форму использовать пользовательский шаблон темы?

Author: Chaulky, 2011-03-04

7 answers

Вполне разумно использовать файл 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;
}

Пользовательская_донате_форма():

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/template/form/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); ?>

Это использование Основы , которая дает нам такую форму:

enter image description here

 74
Author: Charlie Schliesser, 2016-07-21 16:51:59

Вы должны реализовать функцию hook_form_alter() в модуле или template.php и установите свойство формы #тема:

/**
 * 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',
    ),
  );
}

А затем добавьте form--user_login.tpl.php шаблон с последующим кодом для отображения формы:

<?php print drupal_render_children($form) ?> 
 18
Author: mrded, 2013-01-02 16:11:58

Даже если вы сможете использовать решение киамлалуно, я лично не стал бы этого делать.

По какой причине вам нужен файл шаблона для формы? Если это потому, что вам нужна немного другая разметка для существующей формы? Если это так, то вы можете использовать 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, который имеет встроенный стиль, чтобы изменить цвет фона на красный. Он также добавляет абзац текста справки в начало формы.

Вот как теперь выглядит моя форма входа пользователя после загрузки приведенного выше кода:

Customised login form

Дополнительную информацию смотрите в справочнике по API форм: Справочник по API форм

 13
Author: Camsoft, 2011-03-04 10:17:53

На самом деле мне никогда не приходилось использовать файл шаблона для формы.
Насколько я могу видеть, основной код 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().

 12
Author: kiamlaluno, 2011-03-05 15:18:26

Я бы всегда стилизовал, добавляя в свой 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 и добавления идентификаторов.

ИМО, использующий встроенный стиль для элементов, является очень плохой практикой, которую следует исключить и заменить на использование class и id

 1
Author: Richard Harrison, 2011-03-04 13:01:22

Для оформления формы вы можете использовать пользовательский css, как описано в Тематизация форм Drupal 7 (включая CSS и JS).

В основном вам нужно выполнить следующие действия:

  1. Зарегистрируйте путь к форме с помощью функции hook_menu()
  2. Определите форму
  3. Зарегистрируйте функцию темы с помощью функции hook_theme()
  4. Напишите функцию темы
  5. Создайте файлы CSS и JavaScript
 0
Author: shasi kanth, 2016-06-16 08:10:14

Я почти уверен, что вы можете использовать шаблон для форм, но вы должны использовать hook_theme, чтобы зарегистрировать шаблон в первую очередь. У меня была ситуация, когда форма действительно должна была основываться на таблице, а не на div, и простые изменения #префикса и #суффикса на самом деле не сокращали ее. Если бы мне было интересно, я, вероятно, мог бы попытаться найти пример.

 -2
Author: Malks, 2011-12-02 00:57:08