วิธีใช้เทมเพลตไฟล์เพื่อจัดทำธีมของฟอร์ม


50

ในขณะที่โหนดความคิดเห็นบล็อกและสิ่งอื่น ๆ อีกมากมายใน Drupal ได้รับการจัดแนวโดยใช้ไฟล์เทมเพลตธีม (เช่น node.tpl.php) รูปแบบเป็นเรื่องที่แตกต่าง ไม่มีไฟล์เท็มเพลตธีมสำหรับแบบฟอร์ม ฉันจะขอรับฟอร์มเฉพาะเพื่อใช้เท็มเพลตธีมที่กำหนดเองได้อย่างไร?

คำตอบ:


73

มีเหตุผลอย่างสมบูรณ์ที่ต้องการใช้ไฟล์ tpl เพื่อแสดงฟอร์ม คุณสามารถใช้ CSS และ#prefix/ #suffixคุณสมบัติที่ไม่เกี่ยวข้องมากมายเพื่อให้ได้ผลลัพธ์ที่คล้ายกัน แต่ด้วยการใช้ tpl คุณไม่ต้องวุ่นวายกับการแยกตรรกะและเลเยอร์การนำเสนอของคุณและไม่ต้องกำหนดเป้าหมาย CSS selector ที่น่าเกลียดเช่น#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); ?>

นี่คือการใช้รากฐานซึ่งทำให้เรามีรูปแบบเช่นนี้:

ป้อนคำอธิบายรูปภาพที่นี่


ดูเหมือนว่าคุณลืมสถานะส่งคืนในฟังก์ชั่น mytheme_theme ()
sel_space

คุณพูดถูกฉันได้เพิ่มมันแล้ว
Charlie Schliesser

5
หมายเหตุที่สำคัญมากคือที่ด้านล่างของโค้ดคือprint drupal_render_children($form)สิ่งที่ทำให้รูปแบบทำสิ่งจริง :)
Chris Rockwell

คำตอบที่ดี. ฉันสามารถเพิ่มที่คุณต้องระบุเพิ่มเติมengineหากคุณกำลังใช้บางอย่างที่ไม่ใช่ค่าเริ่มต้น 'engine' => 'twig'เช่น
milkovsky

1
คำตอบที่ดี จำไว้ถ้าคุณต้องการรูปแบบรูปแบบที่ผู้ดูแลระบบเช่นหรือuser_profile_form user_register_formในสถานการณ์สมมตินั้นคุณจะต้อง a) ทำชุดรูปแบบของคุณในธีมผู้ดูแลระบบ (หรือหัวข้อย่อยหากคุณไม่สามารถเปลี่ยนชุดรูปแบบผู้ดูแลระบบพื้นฐาน) หรือ b) ทำให้ชุดรูปแบบของคุณอยู่ในโมดูลที่กำหนดเอง ไม่เช่นนั้นจะไม่สามารถมองเห็นได้
therobyouknow

18

คุณต้องใช้ 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) ?> 

1
#themeคุณสมบัติเพื่อให้ง่ายมากและเป็นที่กล่าวถึงเป็นครั้งแรกจริงๆต่ำลงในคำตอบสุดแปลก นี่เป็นวิธีที่ฉันชอบแน่นอน
Matt Fletcher

1
ฉันทดสอบโค้ดนี้และทำงานตามที่คาดไว้
VladSavitsky

14

แม้ว่าคุณจะสามารถใช้วิธีแก้ปัญหาของ 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 ซึ่งมีรูปแบบอินไลน์เพื่อเปลี่ยนสีพื้นหลังเป็นสีแดง นอกจากนี้ยังเพิ่มข้อความช่วยเหลือในย่อหน้าไว้ที่จุดเริ่มต้นของแบบฟอร์ม

นี่คือรูปแบบการเข้าสู่ระบบผู้ใช้ของฉันที่ดูเหมือนตอนนี้เมื่อโหลดโค้ดด้านบน:

แบบฟอร์มเข้าสู่ระบบที่กำหนดเอง

ดูการอ้างอิง Form API สำหรับข้อมูลเพิ่มเติม: การอ้างอิง Form API


1
เพียงชี้แจงให้ชัดเจนถึงการใช้รูปแบบอินไลน์ในตัวอย่างนี้ก็เพื่อทำให้ตัวอย่างง่ายขึ้น ฉันไม่แนะนำให้ใช้สไตล์อินไลน์และคุณควรใช้คลาส
Camsoft

ฉันไม่สนับสนุนการใช้ไฟล์เทมเพลตสำหรับการแสดงผลแบบฟอร์ม ตามความเป็นจริงฉันยังบอกด้วยว่าฉันไม่เคยใช้ไฟล์เทมเพลตเพื่อสร้างแบบฟอร์ม (จริง ๆ แล้วฉันได้เปลี่ยนรหัสของโมดูลที่ใช้ไฟล์เทมเพลตสำหรับแบบฟอร์ม) และ Drupal ไม่ได้ใช้แม่แบบ ไฟล์เพื่อแสดงผลแบบฟอร์ม
kiamlaluno

5
ถ้าคุณต้องการแก้ไขมาร์กอัพอย่างรุนแรงล่ะ บางครั้งไฟล์เทมเพลตเป็นตัวเลือกที่ดีกว่า
cossovich

6
มาร์กอัปในตัวสร้างตรรกะของฟอร์มมีกลิ่น
Charlie Schliesser

1
แม้ว่าวิธีนี้จะใช้งานได้ในกรณีส่วนใหญ่ แต่จริง ๆ แล้วมันอาจจะแตกเมื่อการเรนเดอร์ฟอร์มถูกรีเฟรชในการโทรกลับ ajax
PatrickS

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()ที่ส่งผ่านจาก


ฉันจะแนะนำรูปแบบที่กำหนดโดยโมดูลอื่นบางโมดูลหลักอาจจะใช้ฟังก์ชั่น / แม่แบบธีมของฉันได้อย่างไร
Shafiul

$form['#theme']ตั้งค่า
kiamlaluno

1
ไม่ทำงานเมื่อฉันส่งแบบฟอร์มมันจะไม่ไปที่ฟังก์ชัน
form_submit

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 เพิ่มตัวระบุเช่นกัน

IMO ที่ใช้รูปแบบอินไลน์กับองค์ประกอบเป็นแนวปฏิบัติที่ไม่ดีมากซึ่งควรเลิกใช้และแทนที่ด้วยการใช้classและid


0

กับรูปแบบรูปแบบที่คุณสามารถใช้ CSS ที่กำหนดเองตามที่อธิบายไว้ในThemeing Drupal 7 รูปแบบ (รวม CSS และ JS)

โดยทั่วไปคุณต้องทำตามขั้นตอนเหล่านี้:

  1. ลงทะเบียนพา ธ ไปยังแบบฟอร์มโดยใช้ hook_menu ()
  2. กำหนดแบบฟอร์ม
  3. ลงทะเบียนฟังก์ชั่นชุดรูปแบบด้วย hook_theme ()
  4. เขียนฟังก์ชั่นชุดรูปแบบ
  5. สร้างไฟล์ CSS และ JavaScript

-2

ฉันค่อนข้างมั่นใจว่าคุณสามารถใช้เทมเพลตสำหรับฟอร์มได้ แต่คุณต้องใช้ hook_theme เพื่อลงทะเบียนเทมเพลตตั้งแต่แรก ฉันมีสถานการณ์ที่ฟอร์มจริงๆจำเป็นที่จะตามตารางมากกว่า DIV และง่าย #prefix และ #suffix การเปลี่ยนแปลงไม่ได้จริงๆตัดมัน หากสนใจฉันอาจลองขุดตัวอย่าง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.