…is gone!
…are being converted to Twig templates…
(and other formats).
Drupal 7:
<?php
/**
* Implements hook_preprocess_HOOK() for node templates.
*/
function MYTHEME_preprocess_node(&$variables) {
$variables['theme_hook_suggestions'][] = 'node__' . 'my_first_suggestion';
$variables['theme_hook_suggestions'][] = 'node__' . 'my_second_more_specific_suggestion';
}
Drupal 8:
<?php
/**
* Implements hook_theme_suggestions_HOOK_alter() for node templates.
*/
function MYTHEME_theme_suggestions_node_alter(array &$suggestions, array $variables) {
$suggestions[] = 'node__' . 'my_first_suggestion';
$suggestions[] = 'node__' . 'my_second_suggestion';
}
<?php
$variables['list'] = theme('item_list', array(
'items' => $items,
));
<?php
$variables['list'] = array(
'#theme' => 'item_list',
'#items' => $items,
);
<div{{ attributes }}>
<div {{ attributes }}>
<div✖{{ attributes }}>
<div class="myclass {{ attributes.class }}"{{ attributes|without('class') }}>
<div{{ attributes.addClass('hello').removeClass('goodbye') }}>
{% if attributes.hasClass('field-label-inline') %}
{# Do something special here. #}
{% endif %}
<?php
// We hide the comments and links now so that we can render them later.
hide($content['comments']);
hide($content['links']);
print render($content);
?>
{# We give you what you ask for. #}
{{ content|without('comments', 'links') }}
services.yml:
parameters:
twig.config:
debug: true
Example output:
<!-- THEME DEBUG -->
<!-- CALL: _theme('block') -->
<!-- FILE NAME SUGGESTIONS:
* block--bartik-powered.html.twig
* block--system-powered-by-block.html.twig
* block--system.html.twig
x block.html.twig
-->
<!-- BEGIN OUTPUT from 'core/modules/block/templates/block.html.twig' -->
<div class="block block-system contextual-region" id="block-bartik-powered" role="complementary">
<div data-contextual-id="block:block=bartik_powered:"></div>
<div class="content">
<span>Powered by <a href="http://drupal.org">Drupal</a></span>
</div>
</div>
<!-- END OUTPUT from 'core/modules/block/templates/block.html.twig' -->
settings.php:
$conf['theme_debug'] = TRUE;
Example output:
<!-- THEME DEBUG -->
<!-- CALL: theme('block') -->
<!-- FILE NAME SUGGESTIONS:
* block--system--powered-by.tpl.php
* block--system.tpl.php
* block--footer.tpl.php
x block.tpl.php
-->
<!-- BEGIN OUTPUT from 'modules/block/block.tpl.php' -->
<div id="block-system-powered-by" class="block block-system">
<div class="content">
<span>Powered by <a href="https://www.drupal.org">Drupal</a></span> </div>
</div>
<!-- END OUTPUT from 'modules/block/block.tpl.php' -->
hook_theme()
<?php
/**
* Implements hook_theme().
*/
function sandwich_theme() {
return array(
'sandwich' => array(
'variables' => array(
'attributes' => array(),
'name' => '',
'bread' => '',
'cheese' => '',
'veggies' => array(),
'protein' => '',
'condiments' => array(),
),
// 'template' is the default in Drupal 8!
'template' => 'sandwich',
),
);
}
<?php
/**
* Implements hook_theme().
*/
function sandwich_theme() {
return [
'sandwich' => [
'variables' => [
'attributes' => [],
'name' => '',
'bread' => '',
'cheese' => '',
'veggies' => [],
'protein' => '',
'condiments' => [],
],
],
];
}
<?php
/**
* Builds a sandwich.
*/
public function build() {
return [
'#theme' => 'sandwich',
'#name' => $this->t('Chickado'),
'#attributes' => [
'id' => 'best-sandwich',
'style' => 'float: left;',
'class' => ['left', 'clearfix'],
],
'#bread' => $this->t('Sourdough'),
'#cheese' => $this->t('Gruyère'),
'#veggies' => [$this->t('Avocado'), $this->t('Red onion'), $this->t('Romaine')],
'#protein' => $this->t('Chicken'),
'#condiments' => [$this->t('Mayo'), $this->t('Dijon')],
];
}
Pass in variables using #-prefixed keys.
<section{{ attributes }}>
<h2>{{ name }}</h2>
{% if bread %}
<p><strong>Bread:</strong> {{ bread }}</p>
{% endif %}
{% if protein %}
<p><strong>Protein:</strong> {{ protein }}</p>
{% endif %}
{% if cheese %}
<p><strong>Cheese:</strong> {{ cheese }}</p>
{% endif %}
{% if veggies %}
<strong>Vegetables:</strong>
<ul>
{% for veg in veggies %}
<li>{{ veg }}</li>
{% endfor %}
</ul>
{% endif %}
{% if condiments %}
<strong>Condiments:</strong>
<ul>
{% for condiment in condiments %}
<li>{{ condiment }}</li>
{% endfor %}
</ul>
{% endif %}
</section>
drupal_render()
#pre_render
_theme()
#post_render
{{ sandwich.cheese }}
// Array key.
$sandwich['cheese'];
// Object property.
$sandwich->cheese;
// Also works for magic get (provided you implement magic isset).
$sandwich->__isset('cheese'); && $sandwich->__get('cheese');
// Object method.
$sandwich->cheese();
// Object get method convention.
$sandwich->getCheese();
// Object is method convention.
$sandwich->isCheese();
// Method doesn't exist/dynamic method.
$sandwich->__call('cheese');
@Cottser
@joelpittet
IRC: #drupal-twig
Twitter: #drupaltwig