移至主內容
首頁  >  Drupal目錄  >  Twig 最佳實踐 - 預處理函數和模板

Twig 最佳實踐 - 預處理函數和模板

Tag :
twig, preprocess_functions, templates
Written by Shiuan on 20 December 2023

為了使 Drupal 8 的主題設計盡可能地維持高效率,並在 Twig 模板中允許進行更多自定義,請遵循以下最佳實踐:

本指南旨在協助具有 Drupal 7 經驗的 Drupal 開發人員,他們正試圖移除在 Drupal 8+ 中不再使用的 theme() drupal_render() 等函數。這裡的 “Before” 示例通常以 Drupal 7 的代碼風格為例。

如果希望透過 Twig 進行更多可呈現的其他選擇,請考慮使用 twig_tweak 貢獻模組。詳情請見:consider the twig_tweak 

從預處理函數返回渲染陣列

在預處理函數中,請始終返回渲染陣列,而不是調用 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'];


在模板中調用過濾器和實用函數

雖然渲染陣列透過模板為數據提供了一個可訪問且可修改的結構,但並非所有變數都需要渲染陣列。為了在模板中盡可能地長時間提供原始數據,主題開發人員應該在 Twig 模板內調用過濾器 filters,如 t,以及實用函數 utility functions,如 url()。在 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')));
In the template:

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

After:

在 Twig 模板中:

<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 file):

<?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(預處理):

<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>

返回Drupal
首頁  >  Drupal  >  Twig 最佳實踐 - 預處理函數和模板

Twig 最佳實踐 - 預處理函數和模板

Tag :
twig, preprocess_functions, templates
Written by Shiuan on 20 December 2023

為了使 Drupal 8 的主題設計盡可能地維持高效率,並在 Twig 模板中允許進行更多自定義,請遵循以下最佳實踐:

本指南旨在協助具有 Drupal 7 經驗的 Drupal 開發人員,他們正試圖移除在 Drupal 8+ 中不再使用的 theme() drupal_render() 等函數。這裡的 “Before” 示例通常以 Drupal 7 的代碼風格為例。

如果希望透過 Twig 進行更多可呈現的其他選擇,請考慮使用 twig_tweak 貢獻模組。詳情請見:consider the twig_tweak 

從預處理函數返回渲染陣列

在預處理函數中,請始終返回渲染陣列,而不是調用 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'];


在模板中調用過濾器和實用函數

雖然渲染陣列透過模板為數據提供了一個可訪問且可修改的結構,但並非所有變數都需要渲染陣列。為了在模板中盡可能地長時間提供原始數據,主題開發人員應該在 Twig 模板內調用過濾器 filters,如 t,以及實用函數 utility functions,如 url()。在 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')));
In the template:

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

After:

在 Twig 模板中:

<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 file):

<?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(預處理):

<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>