Làm thế nào để sử dụng một tệp mẫu để tạo chủ đề cho một biểu mẫu?


50

Trong khi các nút, bình luận, khối và nhiều thứ khác trong Drupal được theo chủ đề bằng cách sử dụng các tệp mẫu chủ đề (như node.tpl.php), các biểu mẫu là một câu chuyện khác nhau. Không có tệp mẫu chủ đề cho các biểu mẫu. Làm cách nào tôi có thể nhận được một biểu mẫu cụ thể để sử dụng mẫu chủ đề tùy chỉnh?

Câu trả lời:


73

Hoàn toàn hợp lý khi muốn sử dụng tệp tpl để hiển thị biểu mẫu. Bạn có thể sử dụng nhiều thuộc tính và #prefix/ CSS ngoại lai #suffixđể đạt được kết quả tương tự, nhưng bằng cách sử dụng tpl, bạn không phải làm lộn xộn sự phân tách logic và các lớp trình bày của mình và không phải nhắm mục tiêu các bộ chọn CSS xấu như thế nào #user-login label. Đây là một ví dụ trong Drupal 7 ...

huyền thoại / 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;
}

huyền thoại / mẫu / hình thức / 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); ?>

Đây là sử dụng Foundation , cung cấp cho chúng ta một hình thức như thế này:

nhập mô tả hình ảnh ở đây


có vẻ như bạn đã quên một trạng thái trả về trên hàm mysteme_theme ()
sel_space

Bạn nói đúng, tôi đã thêm nó.
Charlie Schliesser

5
Lưu ý rất quan trọng là, ở dưới cùng của đoạn mã, là print drupal_render_children($form)biểu mẫu thực sự làm công cụ :).
Chris Rockwell

Câu trả lời tốt. Tôi có thể thêm rằng bạn cần chỉ định bổ sung engine, nếu bạn đang sử dụng một cái gì đó không mặc định. Ví dụ 'engine' => 'twig'.
milkovsky

1
Câu trả lời tốt đẹp. Ghi nhớ nếu bạn muốn chủ đề một hình thức quản trị như user_profile_formhay user_register_form. Trong kịch bản đó, bạn sẽ cần phải a) thực hiện chủ đề của mình trong chủ đề quản trị viên (hoặc loại bỏ nó nếu bạn không thể thay đổi chủ đề quản trị cơ sở) hoặc b) đưa chủ đề của bạn vào mô-đun tùy chỉnh. Nếu không, chủ đề của bạn sẽ không được nhìn thấy.
trị liệu

18

Bạn phải triển khai hook_form_alter () trong một mô-đun hoặc template.php và đặt thuộc tính #theme của biểu mẫu :

/**
 * Implements hook_form_alter().
 */
function hook_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'user_login') {
    $form['#theme'] = array('overwrite_user_login');
  }
}

Sau đó thực hiện chủ đề mới:

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

Và sau đó thêm biểu mẫu - user_login.tpl.php với mã theo dõi để hiển thị biểu mẫu:

<?php print drupal_render_children($form) ?> 

1
Các #themetài sản là rất đơn giản và lần đầu tiên được đề cập thực sự thấp trong các câu trả lời, siêu kỳ lạ. Đây chắc chắn là phương pháp yêu thích của tôi.
Matt Fletcher

1
Tôi đã thử nghiệm mã này và nó hoạt động như mong đợi.
VladSavitsky

14

Mặc dù cá nhân bạn có thể sử dụng giải pháp của kiamlaluno.

Lý do của bạn để cần một tệp mẫu cho một biểu mẫu là gì? Nếu đó là vì bạn muốn đánh dấu hơi khác nhau cho một hình thức hiện có? Nếu vậy thì bạn có thể sử dụng hook_form_alter()để sửa đổi biểu mẫu trước khi nó được hiển thị. Sử dụng API biểu mẫu, bạn có thể sửa đổi tất cả các trường biểu mẫu tiêm các phần tử html, v.v.

Dưới đây là một ví dụ về hook_form_alter()điều mà tôi đã tạo để sửa đổi khối biểu mẫu đăng nhập drupal tiêu chuẩn:

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

Ví dụ trên bao bọc toàn bộ biểu mẫu trong DIV có kiểu nội tuyến để chuyển màu nền thành màu đỏ. Nó cũng thêm một đoạn văn bản trợ giúp vào đầu mẫu.

Đây là mẫu đăng nhập người dùng của tôi trông giống như bây giờ khi mã ở trên được tải:

Hình thức đăng nhập tùy chỉnh

Xem tham chiếu API biểu mẫu để biết thêm thông tin: Tham chiếu API biểu mẫu


1
Chỉ cần làm rõ việc sử dụng các kiểu nội tuyến trong ví dụ này là để đơn giản hóa ví dụ. Tôi không khuyên bạn nên sử dụng kiểu nội tuyến và bạn nên sử dụng các lớp.
Camsoft

Tôi không hỗ trợ sử dụng tệp mẫu để hiển thị biểu mẫu; như một vấn đề thực tế, tôi cũng nói rằng tôi chưa bao giờ sử dụng tệp mẫu để hiển thị biểu mẫu (tôi thực sự đã thay đổi mã của mô-đun đang sử dụng tệp mẫu cho biểu mẫu) và Drupal không sử dụng mẫu tập tin để kết xuất các hình thức.
kiamlaluno

5
Điều gì nếu bạn muốn thay đổi hoàn toàn đánh dấu? Đôi khi một tệp mẫu là một lựa chọn tốt hơn.
cossovich

6
Markup trong một hình thức xây dựng logic mùi.
Charlie Schliesser

1
Mặc dù giải pháp này hoạt động trong hầu hết các trường hợp, nhưng nó thực sự có thể bị
hỏng

13

Tôi thực sự chưa bao giờ cần sử dụng tệp mẫu cho biểu mẫu.
Theo như tôi có thể thấy, mã lõi Drupal sử dụng các hàm chủ đề, khi một biểu mẫu hoặc một phần của biểu mẫu cần được hiển thị theo một cách cụ thể; một hàm chủ đề gọi drupal numnder () thường đủ cho mọi mục đích.

Để trả lời câu hỏi, việc tạo tệp mẫu cho biểu mẫu không khác với việc tạo tệp mẫu không dành cho biểu mẫu.

Xác định chức năng chủ đề, sử dụng làm chức năng chủ đề tên của hàm gọi lại trình tạo biểu mẫu. Mã phải tương tự như sau:

/**
 * Implementation of hook_theme().
 */

 function mymodule_theme() {
   return array(
     'mymodule_form' => array(
       'template' => 'mymodule-form',
       'file' => 'mymodule.admin.inc',
       'arguments' => array('form' => NULL),
     ),
   );
 }

Nếu biểu mẫu chứa giá trị $form['field_1'], giá trị của nó sẽ có sẵn trong tệp mẫu dưới dạng $field_1. Tệp mẫu cũng sẽ có thể sử dụng bất kỳ giá trị nào được truyền từ đó template_preprocess_mymodule_form().


Làm cách nào để đề xuất một biểu mẫu được xác định bởi một số mô-đun khác, có thể là các mô-đun cốt lõi để sử dụng chức năng / mẫu chủ đề của tôi?
Shafiul

Đặt $form['#theme'].
kiamlaluno

1
Không hoạt động, khi tôi gửi biểu mẫu, nó sẽ không chuyển đến hàm
form_submit

1

Tôi sẽ luôn tạo kiểu bằng cách thêm vào tệp CSS của mình bằng các bộ chọn để xác định thành phần được tạo kiểu như sau cho biểu mẫu đăng nhập lõi

#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;
}

Ở trên tôi chỉ cần thêm vào sites/all/themes/theme-name/css/theme-name.css

Nếu những gì bạn cần tạo kiểu không có ID hoặc bộ chọn đủ chính xác thì cần phải sử dụng hookcách tiếp cận để sửa đổi HTML quá thêm số nhận dạng.

IMO sử dụng kiểu nội tuyến trên các phần tử là một thực tiễn rất xấu cần được loại bỏ và thay thế bằng cách sử dụng classid


0

Để tạo chủ đề cho một biểu mẫu, bạn có thể sử dụng một css tùy chỉnh, như được giải thích trong Themeing Drupal 7 Forms (Bao gồm CSS và JS) .

Về cơ bản bạn cần thực hiện các bước sau:

  1. Đăng ký đường dẫn đến biểu mẫu bằng hook_menu ()
  2. Xác định mẫu
  3. Đăng ký một chức năng chủ đề với hook_theme ()
  4. Viết chức năng chủ đề
  5. Tạo các tệp CSS và JavaScript

-2

Tôi khá chắc chắn rằng bạn có thể sử dụng một mẫu cho các biểu mẫu, nhưng bạn phải sử dụng hook_theme để đăng ký mẫu ở vị trí đầu tiên. Tôi đã có một tình huống trong đó biểu mẫu thực sự cần phải dựa trên bảng thay vì dựa trên div và các thay đổi #prefix và #suffix đơn giản không thực sự cắt giảm. Nếu quan tâm tôi có thể thử và đào một ví dụ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.