Twig Template Engine
Einleitung
Twig ist eine Template-Sprache, die eng an das Symfony Framework gekoppelt ist. Es ist aber auch möglich diese allein stehend zu verwenden. Sie erlaubt uns HTML Markup zu schreiben und durch eine eigene Syntax einzelne Bereiche dynamisch zu gestalten.
Verwendung von Twig
Für Twig Templates gibt es ein extra Verzeichnis, in dem alle Templates liegen: <customer-project>/<customer>-module/src/publish/php/templates
(Für neue Module, bei denen PHP Code in einem eigenen GIT Projekt liegt, ist es php/templates
).
In diesem Ordner können nach Belieben, weitere Unterordner und Strukturen erstellt werden. Für Twig Templates muss
immer die Dateiendung .twig
verwendet werden.
Wie im folgenden Beispiel zu sehen, ist Twig für Web Entwickler einfach zu lesen und bietet gleichzeitig mehr flexibilität:
<!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>
{{ a_variable }}
</body>
</html>
Weitere Informationen über die Syntax, Funktionen und Filter, gibt es in der offiziellen Twig Dokumentation.
Integration in Kundenmodulen
Twig kann optional in einem Modul verwendet werden und ist in wenigen Schritten einsatzbereit. Da die Basis schon im SiteKit integriert ist, muss in einem (Kunden)Modul nur der Ordner mit den Templates bekannt gemacht werden:
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services
https://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="twig.loader.bonn.filesystem" class="Twig\Loader\FilesystemLoader" autoconfigure="false" autowire="false">
<tag name="twig.loader"/>
<call method="addPath">
<argument>%sitekit.module_source%/../bonn-module/php/templates</argument>
<argument>bonn-module</argument>
</call>
</service>
</services>
</container>
Dieses Beispiel zeigt die Integration für das Bonn Modul. Daher müssen die Argumente entsprechend angepasst werden.
Erstes Argument: Dies ist der Pfad zu dem Ordner, in dem alle Templates enthalten sind. das %sitekit.module_source%
ist eine Variable, die auf den SiteKit Ordner verweist. Ausgehend von diesem Ordner muss der Pfad auf den Templates Ordner
verwiesen werden.
Zweites Argument: Dies ist ein Namensraum für die Templates. Damit ist es möglich, auch auf andere Templates zu
verweisen. Mit dem Template Pfad @sitekit/html.twig
würde bspw. ein Template aus dem SiteKit Modul gerendert werden.
Allerdings muss dafür gesorgt sein, dass dieses auch existiert. Wird ein Template nicht gefunden, gibt es eine Exception.
Damit wir in einem Renderer auch auf Twig zugreifen können, muss noch ein Service im Dependency Injection Container eingetragen werden:
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services
https://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<defaults autowire="true" autoconfigure="true"/>
<service id="renderer.bonn.audio" class="SP\Bonn\Renderer\Audio" public="true">
<factory class="SP\SiteKit\Renderer\TemplateFactory" method="createTemplate"/>
<argument type="string">\SP\Bonn\Renderer\Audio</argument>
<argument type="service" id="twig"/>
<argument type="service" id="sp.sitekit.renderer.renderer_context.html"/>
<argument type="service" id="component_model.html"/>
</service>
</service>
</container>
Damit wird der Renderer aus dem Symfony Dependency Injection Container geholt und in der Factory wird Twig über
setEnvironment
an den Renderer übergeben.
Somit kann die Template Engine verwendet werden:
<?php declare(strict_types=1);
namespace SP\Bonn\Renderer;
use SP\SiteKit\Renderer\Renderer;
use Twig\Environment;
/**
* @method \SP\SiteKit\Model\Audio\Audio getModel()
*/
class Audio extends Renderer {
public const TYPE = 'html.arvedui.content.audio.audio';
private const TEMPLATE = '@bonn-module/audio.twig';
/** @var Environment */
private $engine;
public function setEnvironment(Environment $environment) {
$this->engine = $environment;
}
public function render(): void {
$this->engine->display(self::TEMPLATE, ['model' => $this->getModel()]);
}
}