Як використовувати файл шаблону для тематизації форми?


50

Хоча вузли, коментарі, блоки та багато іншого в Drupal тематизовані за допомогою файлів шаблонів тем (наприклад, node.tpl.php), форми - це інша історія. Файли шаблонів тем для форм немає. Як я можу отримати конкретну форму для використання користувацького шаблону теми?

Відповіді:


73

Цілком розумно хотіти використовувати файл 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 / 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); ?>

Для цього використовується Foundation , який надає нам таку форму:

введіть тут опис зображення


схоже, ви забули стан повернення функції mytheme_theme ()
sel_space

Ти маєш рацію, я додав.
Charlie Schliesser

5
Дуже важливо зауважити, що внизу фрагмента коду є те, print drupal_render_children($form)що змушує форму насправді робити речі :).
Кріс Роквелл

Хороша відповідь. Можу додати, що вам потрібно вказати додатково engine, якщо ви використовуєте щось не за замовчуванням. Напр 'engine' => 'twig'.
мілковський

1
Гарна відповідь. Майте на увазі, якщо ви хочете надати тему формі адміністратора, наприклад, user_profile_formабо user_register_form. У цьому сценарії вам потрібно буде: а) виконати тематизацію в темі адміністратора (або відключити її підтему, якщо ви не можете змінити базову тему адміністратора), або b) помістити тематизацію в спеціальний модуль. Інакше ваші теми не будуть помічені.
therobyouknow

18

Ви повинні реалізувати mock_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) ?> 

1
#themeВластивість так дуже просто і згадується в перший раз дійсно низько у відповідях, супер дивно. Це, безумовно, мій улюблений метод.
Метт Флетчер

1
Я перевірив цей код, і він працює як слід.
ВладСавицький

14

Хоча ви, можливо, зможете використовувати рішення kiamlaluno, я особисто не хотів.

Яка ваша причина необхідності файлу шаблону для форми? Якщо це потрібно тому, що ви хочете дещо іншу розмітку для існуючої форми? Якщо так, то ви можете використовувати hook_form_alter()для зміни форми до її надання. Використовуючи API форми, ви можете змінювати всі форми форми, вводити елементи html тощо.

Ось приклад того, hook_form_alter()що я створив, що змінює стандартний блок форми для входу в друпал:

/**
 * 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 форми


1
Просто для уточнення використання стилів вбудованого в цьому прикладі просто спростити приклад. Я не рекомендую використовувати вбудовані стилі, і ви повинні використовувати класи.
Camsoft

Я не підтримую використання шаблонного файлу для надання форми; насправді я також сказав, що я ніколи не використовував файл шаблону для надання форми (я фактично змінив код модуля, який використовував файл шаблону для форми), і що Drupal не використовує шаблон файли для надання форм.
kiamlaluno

5
Що робити, якщо ви хочете кардинально змінити розмітку? Іноді файл шаблону є кращим варіантом.
косович

6
Розмітка у формі логіки будівельника пахне.
Чарлі Шліссер

1
Хоча це рішення працює в більшості випадків, воно може справді зламатися, коли візуалізація форми буде оновлена ​​в зворотному
звороті

13

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


Як запропонувати форму, визначену деякими іншими модулями, можливо основними модулями, щоб використовувати мою тематичну функцію / шаблон?
Шафіул

Встановити $form['#theme'].
kiamlaluno

1
Не працює, коли я надсилаю форму, вона не перейде до функції form_submit
gbstack

1

Я завжди стилю, додаючи до свого 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


0

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

В основному вам потрібно виконати наступні дії:

  1. Зареєструйте шлях до форми, використовуючи mook_menu ()
  2. Визначте форму
  3. Зареєструйте функцію теми за допомогою ho_theme ()
  4. Напишіть функцію теми
  5. Створіть файли CSS та JavaScript

-2

Я впевнений, що ви можете використовувати шаблон для форм, але вам доведеться в першу чергу використовувати шаблон_теми для реєстрації шаблону. У мене виникла ситуація, коли форму справді потрібно було грунтуватись на таблиці, а не на основі div, а прості зміни #prefix та #suffix насправді не скоротили її. Якщо цікаво, я, мабуть, спробую викопати приклад.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.