logo

パレット - カラフルに🎨

Palette — ビジュアルページビルダー、デザインの専門知識は不要です。

ライブデモ パレットをダウンロード

Scroll

Twigのベストプラクティス - 前処理関数とテンプレート

04/05/2020, by maria

Menu

Drupal 8のテーマ設定を可能な限り効率的にし、Twigテンプレートでより多くのカスタマイズオプションを提供するには、次の推奨事項に従ってください:

このガイドは、Drupal 7の経験があり、Drupal 8以降で使用すべきでなくなったtheme()やdrupal_render()などの関数を削除しようとしているDrupal開発者を支援するために書かれています。ここでの「Before」の例は、一般的にDrupal 7のコードスタイルで書かれています。

前処理関数からレンダリング配列を返す

前処理関数でtheme()やdrupal_render()を呼び出す代わりに、常にレンダリング配列を返します。

Twigはすべてを自動的にレンダリングするため、前処理関数内でdrupal_render()やtheme()を呼び出す必要はありません。代わりに、レンダリング配列をテンプレートに渡す必要があります。これにより、すでにレンダリングされたHTML文字列よりもはるかに多くのカスタマイズが可能になります。

前処理関数からのtheme()の削除:

// Before - passing a string of rendered HTML to the template.
$variables['table'] = theme('table', ['header' => $header, 'rows' => $rows]);

// After - passing a render array to the template.
$variables['table'] = [
  '#theme' => 'table',
  '#header' => $header,
  '#rows' => $rows,
];

前処理関数からdrupal_render()を削除するのは、呼び出しを削除するだけの問題です:

// Before, unnecessary call to drupal_render().
$variables['teaser'] = drupal_render($node_teaser);

// After, with drupal_render() removed.
$variables['teaser'] = $node_teaser;

drupal_render()がテーブルデータに追加されたときに呼び出されることは一般的です。

// Before, unnecessary call to drupal_render().
$row[] = drupal_render($display['title']);

// After, with drupal_render() removed.  
$row[]['data'] = $display['title'];

テンプレートでフィルターとユーティリティ関数を呼び出す

レンダリング配列はテンプレートまでのデータのアドレス指定可能で変更可能な構造を提供しますが、すべての変数にレンダリング配列が必要なわけではありません。生データをできるだけ長くテンプレートに提供するために、テーマ開発者はフィルター(tなど)やurl()などのユーティリティ関数をTwigテンプレートから呼び出す必要があります。前処理関数ではなくTwigテンプレートでこれらの関数を呼び出すと、テンプレートに渡される変数がテンプレートで出力されない可能性があるため、関数呼び出しを減らすことができます。

Before:

前処理関数内:

$variables['no_content_text'] = t('You have not created any content types yet. Go to the <a href="@create-content">content type creation page</a> to add a new content type.', array('@create-content' => url('admin/structure/types/add')));

テンプレート内:

<p>{{ no_content_text }}</p>

After:

テンプレート内:

<p>{{ 'You have not created any content types yet. Go to the <a href="@create-content">content type creation page</a> to add a new content type.'|t({'@create-content': url('admin/structure/types/add')}) }}</p>

表示/非表示、drupal_render_childrenとelement_childrenの削除

元のテンプレートでhide()が呼び出され、drupal_render_childrenがデータの「残り」のレンダリングに使用されていた場合、前処理中にこれらすべてを個別の変数に分割する必要があります。

Before(PHPTemplateファイル):

<?php
hide($form['advanced']);
hide($form['actions']);
?>
<div class="layout-node-form clearfix">
<div class="layout-region layout-region-node-main">
<?php print drupal_render_children($form); ?>
</div>
<div class="layout-region layout-region-node-secondary">
<?php print render($form['advanced']); ?>
</div>
<div class="layout-region layout-region-node-footer">
<?php print render($form['actions']); ?>
</div>
</div> 

特定の要素を非表示にするには、「without」と呼ばれるTwigフィルターを使用します。必要に応じて、それらを通常どおりレンダリングできます。

After:(Twigテンプレート)

<div class="layout-node-form clearfix">
  <div class="layout-region layout-region-node-main">
    {{ form|without('advanced', 'actions') }}
  </div>
  <div class="layout-region layout-region-node-secondary">
    {{ form.advanced }}
  </div>
  <div class="layout-region layout-region-node-footer">
    {{ form.actions }}
  </div>
</div>

代替方法(もう必要ありません):

すべてを個別の変数に前処理してテンプレートに渡します。残りをレンダリングする前に、レンダリングするものを要素全体(この場合はフォーム)から変数に分割する必要があるかもしれません。コンテンツをテンプレートで意図されたとおりに正確に出力します。

Before:(前処理)

function template_preprocess_node_edit_form(&$variables) {
  $form = $variables['form'];
  
  // @todo Update this once drupal.org/node/1920886 is resolved.
  $variables['advanced'] = $form['advanced'];
  $variables['actions'] = $form['actions'];
  unset($form['advanced'], $form['actions']);
  $variables['form'] = drupal_render_children($form);
}

After:(Twigテンプレート)

<div class="layout-node-form clearfix">
  <div class="layout-region layout-region-node-main">
    {{ form }}
  </div>
  <div class="layout-region layout-region-node-secondary">
    {{ advanced }}
  </div>
  <div class="layout-region layout-region-node-footer">
    {{ actions }}
  </div>
</div>