web-dev-qa-db-ja.com

テンプレートファイルを使用してフォームのテーマを設定する方法

Drupalのノード、コメント、ブロック、その他の多くはテーマテンプレートファイル(node.tpl.phpなど)を使用してテーマ化されていますが、フォームは別のストーリーです。フォーム用のテーマテンプレートファイルはありません。 。特定のフォームでカスタムテーマテンプレートを使用するにはどうすればよいですか?

49
Chaulky

フォームを表示するためにtplファイルを使用することは完全に合理的です。多くの無関係なCSSと#prefix/#suffixプロパティを使用して同様の結果を得ることができますが、tplを使用することで、ロジックレイヤーとプレゼンテーションレイヤーの分離を混乱させる必要がなく、 #user-login labelのような醜いCSSセレクタをターゲットにする。 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 を使用しており、次のような形式になります。

enter image description here

73

モジュールまたはtemplate.phpにhook_form_alter()を実装し、フォームの#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',
    ),
  );
}

次に、フォームを追加するために、次のコードを含むform--user_login.tpl.phpテンプレートを追加します。

<?php print drupal_render_children($form) ?> 
17
mrded

あなたがkiamlalunoのソリューションを使用できるかもしれませんが、私は個人的にはしません。

フォームのテンプレートファイルが必要な理由は何ですか。既存のフォームにわずかに異なるマークアップが必要な場合ですか?その場合は、hook_form_alter()を使用して、レンダリングされる前にフォームを変更できます。 Form APIを使用すると、HTML要素などを挿入するすべてのフォームフィールドを変更できます。

これは、標準のdrupalログインフォームブロックを変更するために作成した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内のフォーム全体をラップします。また、フォームの先頭にヘルプテキストの段落を追加します。

上記のコードがロードされると、ユーザーログインフォームは次のようになります。

Customised login form

詳細については、フォームAPIリファレンスを参照してください。 フォームAPIリファレンス

13
Camsoft

フォームにテンプレートファイルを使用する必要はまったくありませんでした。
私が見る限り、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
kiamlaluno

セレクターを使用して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に追加します

スタイルを設定する必要があるものがIDまたは十分に正確なセレクターを持たない場合、hookアプローチを使用してHTMLを変更し、識別子を追加する必要があります。

要素にインラインスタイルを使用するIMOは非常に悪い習慣であり、非推奨にして、classおよびidの使用に置き換える必要があります

1

Themeing Drupal 7フォーム(CSSとJSを含む)) で説明されているように、フォームにテーマを設定するには、カスタムCSSを使用できます。

基本的に、次の手順を実行する必要があります。

  1. Hook_menu()を使用してフォームへのパスを登録します
  2. フォームを定義する
  3. Hook_theme()でテーマ関数を登録する
  4. テーマ関数を書く
  5. CSSおよびJavaScriptファイルを作成する
0
shasi kanth