Best practices voor Twig – functies en preprocess-sjablonen
Om het themen in Drupal 8 zo efficiënt mogelijk te maken en meer mogelijkheden voor aanpassing in Twig-sjablonen te bieden, volg je deze aanbevelingen:
Deze handleiding is geschreven om Drupal-ontwikkelaars te helpen die ervaring hebben met Drupal 7 en functies zoals theme() of drupal_render() proberen te verwijderen, aangezien deze niet meer gebruikt mogen worden in Drupal 8+. De «voor»-voorbeelden zijn meestal in de Drupal 7-stijl geschreven.
Retourneer render-arrays vanuit preprocess-functies
Retourneer altijd render-arrays in plaats van theme() of drupal_render() aan te roepen in preprocess-functies.
Twig rendert alles automatisch, dus het is niet nodig om drupal_render() of theme() binnen een preprocess-functie aan te roepen. In plaats daarvan moeten render-arrays worden doorgegeven aan het sjabloon, omdat dit veel meer aanpassingen mogelijk maakt dan een al gerenderde HTML-string.
Verwijderen van theme() uit een preprocess-functie:
// Voor - een string van gerenderde HTML doorgeven aan het sjabloon.
$variables['table'] = theme('table', ['header' => $header, 'rows' => $rows]);
// Na - een render-array doorgeven aan het sjabloon.
$variables['table'] = [
'#theme' => 'table',
'#header' => $header,
'#rows' => $rows,
];
Verwijderen van drupal_render() uit een preprocess-functie – dit is eenvoudigweg het weghalen van de aanroep:
// Voor, onnodige aanroep van drupal_render(). $variables['teaser'] = drupal_render($node_teaser); // Na, met drupal_render() verwijderd. $variables['teaser'] = $node_teaser;
Een vaak voorkomend voorbeeld is dat drupal_render() werd aangeroepen bij het toevoegen aan een datarij:
// Voor, onnodige aanroep van drupal_render(). $row[] = drupal_render($display['title']); // Na, met drupal_render() verwijderd. $row[]['data'] = $display['title'];
Filters en hulpfuncties in sjablonen
Hoewel render-arrays een aanspreekbare en aanpasbare datastructuur bieden tot aan het sjabloon, vereisen niet alle variabelen render-arrays. Om ruwe data zo lang mogelijk door te geven aan de sjablonen, moeten themedevelopers filters, zoals t, en hulpfuncties, zoals url(), vanuit Twig-sjablonen aanroepen. Door deze functies in Twig-sjablonen in plaats van in preprocess-functies aan te roepen, worden functieketens verminderd, omdat variabelen die in het sjabloon worden doorgegeven mogelijk helemaal niet geprint worden.
Voor:
In de preprocess-functie:
$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 het sjabloon:
<p>{{ no_content_text }}</p>
Na:
In het sjabloon:
<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>
Toon/verberg en verwijder drupal_render_children en element_children
Als hide() werd aangeroepen in het oorspronkelijke sjabloon en drupal_render_children werd gebruikt om de «rest» van de data te renderen, moeten we dit splitsen in afzonderlijke variabelen tijdens de preprocess-fase.
Voor (PHPTemplate-bestand):
<?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>
Gebruik de Twig-filter «without» om bepaalde elementen te verbergen. Je kunt ze daarna afzonderlijk renderen waar nodig.
Na: (Twig-sjabloon)
<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>
Alternatieve methode (niet meer nodig):
Preprocess alles in aparte variabelen en geef deze door aan het sjabloon. Mogelijk moet je items die je wilt tonen eerst uit de hele array (in dit geval het formulier) halen en toewijzen aan afzonderlijke variabelen, voordat je de rest rendert. Print de inhoud exact zoals het in het sjabloon is bedoeld.
Voor: (preprocess)
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);
}
Na: (Twig-sjabloon)
<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>