2. Was ist eine Template Engine?
● Eine Template Engine ersetzt in einer statischen Datei (dem Template) bestimmte Platzhalter
durch variable Inhalte, ähnlich einer Seriendruckfunktion.
● Dadurch soll eine Trennung von Programmlogik (z.B. PHP) und Markup (z.B. HTML) erreicht
werden - zumindest in der Theorie.
Beispiel für ein Template, z.B. als Datei 'kunden.html':
<p>Kundenliste</p>
<ul>
<f:for each="{kunden}" as="eintrag">
<li>{eintrag vorname} {eintrag.nachname}</li>
</f:for>
</ul>
Die Template Engine muss hier nach Platzhaltern suchen und diese durch die eigentlichen Inhalte
ersetzen. PHP kann natürlich selbst als Template-Sprache verwendet werden. Beispiel:
<h1><?php echo $body_text ; ?></h1>
<?php foreach($test_array as $key => $value) : ?>
<p>Schlüssel: <?php echo $key; ?> - Wert: <?php echo $value; ?></p>
<?php endforeach ; ?>
Bekannte Template Engines für PHP sind z.B. Smarty, Fluid (Typo3), PHPTal oder Contemplate.
3. Template Engines für Drupal
Drupal 4.5: erste Template Engine XTemplate
Drupal 4.7: PHPTemplate als beliebteste Engine
Alternative Engines optional auf d.o. verfügbar, z.B.
XTemplate, http://drupal.org/project/xtemplate (bis Drupal 4.7)
Smarty, http://drupal.org/project/smarty (bis Drupal 6)
PHPTAL, http://drupal.org/project/phptal (auch für Drupal 7)
PHPTemplate wurde erst in Drupal 7 endgültig Standard. Vorher musste die verwendete
Template Engine ausdrücklich im .info File des Themes angegeben werden:
name = Garland
description = Tableless, recolorable, multi-column, fluid width theme (default).
version = VERSION
core = 6.x
engine = phptemplate
stylesheets[all][] = style.css
stylesheets[print][] = print.css
Zusätzliche Engines konnten (und können nach wie vor) in das Verzeichnis /themes/engines
installiert werden, für entsprechende Themes die darauf basieren. Das hat sich aber in der Praxis
nicht durchgesetzt.
4. Schwachstellen der PHPTemplate Engine
● Drupal-spezifisch
● PHP erforderlich
● Unsicher (PHP!)
● Umständlich
● Inkonsistent
"We hand themers a loaded gun and
tell them to hammer in a nail with it
Oh, and be careful" - John Albin
Wer will denn so etwas wirklich:
<ul class="views-summary">
<?php foreach ($rows as $id => $row): ?>
<li><a href="<?php print $row->url; ?>"<?php print !empty($row_classes[$id]) ? ' class="'. $row_classes
[$id] .'"' : ''; ?>><?php print $row->link; ?></a>
<?php if (!empty($options['count'])): ?>
(<?php print $row->count?>)
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
5. Zeit für TWIG!
Twig ist eine moderne, schnelle und flexible PHP Template Engine, ganz
zufällig von den Machern von Symfony.
Twig kennt Variablen, Kontrollstrukturen,Vererbung, Funktionen und Filter,
kann gut erweitert werden, bietet Sicherheit und erzeugt schnellen PHP Code.
Beispiel für ein Twig Template:
<!DOCTYPE html>
<html>
<head>
<title>My Webpage</title>
</head>
<body>
<ul id="navigation">
{% for item in navigation %}
<li><a href="{{ item.href }}">{{ item.caption }}</a></li>
{% endfor %}
</ul>
<h1>My Webpage</h1>
{{ main_content }}
{% include 'footer.html' %}
</body>
</html>
6. TWIG für den Drupal Designer
Für den Designer / Themer bedeutet die Einführung von TWIG, dass er es jetzt
anstelle von PHP Templates (.tpl.php) mit TWIG Templates (.twig) zu tun hat.
Dem Themer stehen wie bisher Variablen zur Verfügung, die im Template
verwendet werden können. Statt PHP benötigt er Syntax und Kontroll-
strukturen von TWIG (Anweisungen, Schleifen, Kommentaren, etc.)
region.tpl.php: region.twig:
<?php {#
/** /**
* @file * @file...
*/ */
?> #}
<?php if ($content): ?> {% if content %}
<div <?php print $attributes; ?>> <div {{ attributes }}>
<?php print $content; ?> {{ content }}
</div> </div>
<?php endif; ?> {% endif %}
7. Komplexeres Beispiel: comment.twig
{#
/**
* @file...
*/
#}
<article class="{{ attributes.class }} clearfix" {{ attributes }}>
{{ render(title_prefix) }}
{% if new %}
<mark class="new">{{ new }}</mark>
{% endif %}
<h3 {{ title_attributes }}>{{ title }}</h3>
{{ render(title_suffix) }}
<footer>
{{ user_picture }}
<p class="submitted">by {{ author }} on {{ created }}</p>
{{ permalink }}
</footer>
<div class="{{ attributes.class }}" {{ attributes }}>
{# We hide the links now so that we can render them later. #}
{# @TODO uncomment this when http://drupal.org/node/1753676 is resolved
{% hide(content.links) %} #}
{{ render(content) }}
{% if signature %}
<div class="user-signature">
{{ signature }}
</div>
{% endif %}
</div>
{{ render(content.links) }}
</article>
8. TWIG für den Drupal Modulentwickler
Ganz einfach eigentlich:
Theming Best Practices beachten!
● Templates explizit registrieren
● Theme-Funktionen in Templates verlagern
● PHP- oder Drupal-Logik in Preprocess-Funktionen verlagern
Warum?
Die Templatesprache ist nicht mehr unbedingt PHP, also haben Templates
möglicherweise keinen Zugriff auf PHP- oder Drupal-Funktionen. Einfache
Kontrollstrukturen können aber vorausgesetzt werden.
9. Beispiel: TWIG-unfreundliches Modul
Theme-Funktion registrieren:
function mymodule_theme() {
Keine Parameter? Also muss
return array( die Aufbereitungs- logik im
'permalink' => array() Theme statt finden!
);
}
Themefunktion implementieren:
function theme_permalink() {
$output = '<span class="permalink">'; Redundanter Code, da ja ein
if ((arg(0)=='node') && (is_numeric(arg(1))) && (!arg(2))) {
$output .= l(t('Permalink'), 'node/' . arg(1)); Template gleichen Inhalts
} mitgeliefert wird!
$output .= '</span>';
return $output;
}
PHP Template dazu (permalink.tpl.php):
<span class="permalink">
Jede Menge PHP- und
<?php if ((arg(0)=='node') && (is_numeric(arg(1))) && (!arg(2))): ?> Drupal-Funktionen, die
<?php print l(t('Permalink'), 'node/' . arg(1)); ?> TWIG normalerweise nicht
<?php endif; ?>
</span> zur Verfügung stehen!
10. Besser: TWIG-freundliches Modul
Template registrieren:
function mymodule_theme() {
Hier wird explizit ein
return array( Template registriert, dem
'template' => 'permalink', eine Variable übergeben
'variables' => array('permalink' => NULL),
); wird.
}
Preprocess-Funktion für Programmlogik:
function template_preprocess_permalink(&$variables) { Hier die Programmlogik zur
if ((arg(0)=='node') && (is_numeric(arg(1))) && (!arg(2))) {
$variables['permalink'] = l(t('Permalink'), 'node/' . arg(1)); Aufbereitung der Variablen!
}
}
PHP Template dazu (permalink.tpl.php):
<span class="permalink"> Die Templates sind deutlich
<?php print $permalink; ?> einfacher und sehr ähnlich
</span>
gehalten, das freut den
TWIG Template dazu (permalink.twig): Themer. Programmlogik und
Markup sind getrennt.
<span class="permalink">
{{ permalink }}
</span>
11. Fragen / Diskussion
Zum Weiterlesen:
http://groups.drupal.org/node/219224
http://drupal.org/sandbox/pixelmord/1750250
http://de.slideshare.net/nyccamp/a-new-theme-layer-for-drupal-8
http://twig.sensiolabs.org
Diese Folien als PDF:
http://www.slideshare.net/drubb