eZ Publish 5 Templating – Teil 1: Basics

Avatar von Andreas Haberberger

Das eZ Publish Content Management System hat sich mit dem Umbau auf Basis des Symfony2 Frameworks stark verändert. Eine der wesentlichsten Änderungen liegt im Templating für das Frontend. Bauten die pre-Symfony-Versionen bis 4 auf einen Mix aus Smarty mit PHP-Code, lassen sich eZ Publish 5 Templates in der Symfony2-eigenen Templatesprache Twig entwickeln.

Voraussetzungen

In diesem Tutorial soll es speziell um die Eigenarten von eZ Publish beim erstellen von Templates gehen. Eine grundsätzliche Einführung in Twig oder das Templating mit Symfony2 möchte ich hier nicht geben. Dazu sind aber ausreichend Ressourcen im Web verfügbar (z.B. hier). Ebenfalls vorausgesetzt wird eine gewisse Erfahrung mit den Konzepten von Symfony2 wie BundlesController und Services. Weiterhin benötigen wir eine funktionsfähige Installation von eZ Publish in aktueller Version. Grundlage dieses Tutorials ist die Community Version 2013.11 Der Code zum Tutorial findet sich bei github. Die Endergebnisse der einzelnen Entwicklungsstufen sind im Repo als Branches („stage_x“) angelegt.

Als Grundlage für unser Templating soll der Beispieldatenbestand nach der Neuinstallation von eZ Publish dienen. Namentlich die Content-Klassen „article“ und „landing_page“ werden wir heranziehen. Die Hinweise zum Templating lassen sich aber problemlos auf selbst definierte Content-Klassen anwenden.

Die Entwicklung unserer eZ Publish Templates findet in einem eigenen Symfony2 Bundle statt. Ziel soll hier sein, möglichst alle Konfigurationen, Templates und Code in unserem Bundle zu behalten, um Wartbarkeit, Mobilität und Deploybarkeit zu gewährleisten. Dazu legen wir zuerst Bundle Skeleton an, indem wir im Wurzelverzeichnis unserer eZ Publish Installation (im weiteren <docroot> genannt) den Generator bemühen:

php ezpublish/console generate:bundle --namespace=Mayflower/TemplateTutorialBundle

Die Defaultvorgaben des Generators sind für unsere Zwecke ausreichend, die Fragen, ob die gesamte Verzeichnisstruktur angelegt werden und das Bundle im Kernel aktiviert werden soll, bejahen wir allerdings. Als Konfigurationsformat wählen wir „yml“. Der Generator liefert uns so die Grundstruktur eines Symfony2-Bundles inklusive der wesentlichen Konfigurationseinstellungen und Klassen in einem neu angelegten Verzeichnisbaum unter <docroot>/src (im Fall unseres Beispiels <docroot>/src/Mayflower/TemplateTutorialBundle/ was ich im Weiteren gerne als <BundleDir> bezeichnen möchte). Das Ergebins als Dateibaum sollte dann in etwa so aussehen.

stage_0

Vorarbeiten (stage_1)

Generell besitzt jedes Symfony2-Bundle seine eigenen Konfigurationsdateien unter <BundleDir>/Resources/config, die Symfony2 über die in <BundleDir>/DependencyInjection befindlichen Klassen in die Gesamtkonfiguration von Symfony injiziert. Die Konfigurationseinstellungen allerdings, die das Rendering von EZ Publish Content Klassen in einzelnen Templates oder ähnliches bestimmen, gehören global zu den eZ Publish eigenen Bundles, so dass wir diese nicht einfach per regulärer Konfiguration überschreiben können. Um das Problem zu umgehen, könnten wir unsere dahingehenden Einstellungen direkt in <docroot>/ezpublish/config/ezpublish.yml vornehmen, was allerdings die Wartbarkeit und Deploybarkeit usereres Codes reduziert. Symfony2 bietet uns allerdings die Möglichkeit, aus unserem Bundle auch Parameter im Namespace eines anderen Bundles zu überschreiben, indem wir in der Extension-Klasse unseres Bundles („MayflowerTemplateTutorialExtension.php“) das „PrependExtensionInterface“ implementieren. In der Methode MayflowerTemplateTutorialExtension::prepend() hängen wir damit den Inhalt von <BundleDir>/Resources/config/ezpublish.yml unterhalb des „ezpublish“-Namespace der Gesamtkonfiguration ein. Zu beachten ist, dass daher der „ezpublish“-Namespace in unserer Konfigurationsdatei nicht mehr vorhanden sein darf.

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\Yaml\Yaml;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;

class MayflowerTemplateTutorialExtension extends Extension implements PrependExtensionInterface
{
    /**
     * @param array $configs
     * @param ContainerBuilder $container
     */
    public function load(array $configs, ContainerBuilder $container)
    {
        $configuration = new Configuration();
        $config = $this->processConfiguration($configuration, $configs);
        $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
        $loader->load('services.yml');
    }
    /**
     * @param ContainerBuilder $container
     */
    public function prepend(ContainerBuilder $container)
    {
        $config = Yaml::parse( __DIR__ . '/../Resources/config/ezpublish.yml' );
        $container->prependExtensionConfig('ezpublish', $config);
    }
}

Unser selbstgebautes eZ Publish Template soll der hergebrachten Logik der Template Extension in Symfony2 folgen, weshalb wir zuerst ein Template für das Rahmenlayout („<BundleDir>/Resources/views/pagelayout.html.twig“) definieren, das alle Detailseiten erweitern sollen. (Ein sehr simples Stylesheet für das Template findet sich im Repository. Jede Art gestalterischer Feinheiten überlasse ich hier den Leuten, die sowas können (Zwinkern) Um das Stylesheet einzubinden müssen ggf. noch die Assets neu verlinkt werden)

<!DOCTYPE html>
<html>
<head>
    <title>Basic Page Layout</title>
    <link rel="stylesheet" href="/bundles/mayflowertemplatetutorial/css/styles.css">
</head>
<body>
    <div id="header">The Navigation goes here</div>
    <div id="content">
        {% block content %}{% endblock %}
    </div>
    <div id="footer">The Footer goes here</div>
</body>
</html>

Als erstes wirkliches eZ Publish Template soll eines entstehen, das für die eZ Publish-eigene Content-Klasse „article“ Verwendung findet und das oben angelegte Pagelayout erweitert. Fürs Erste setzen wir in allen Landingpages einen statischen Text an die Stelle des „content“-Blocks unseres Pagelayouts. Der Code für dieses Kapitel findet sich im Branch „stage_1“ im Repository.

{% extends "MayflowerTemplateTutorialBundle::pagelayout.html.twig" %}
{% block content %}
    <h1>Neues Template!</h1>
{% endblock %}

Verdrahtet wird das Ganze dann über die oben eingebundene „ezpublish.yml“ Konfigurationsdatei.

# Konstante
system:
    # Der eZ Publish site access auf den sich die Konfiguration bezieht.
    ezdemo_site_user:
        # Konstante für die View-Definition
        location_view:
            # view type: Die Form der Darstellung des Content Objekts
            full:
                # Der Bezeichner für die Regel
                article:
                    # Das zu rendernde Template
                    template: MayflowerTemplateTutorialBundle:full:article.html.twig
                    # Ein oder mehrere Matcher
                    match:
                        Identifier\ContentType: article

„Identifier\ContentType“ ist einer von verschiedenen Matchers, die es ermöglichen, die Gültigkeit der Regel entsprechend feinkörnig zu definieren. Durch diese Regel wird das neu generierte Template als Standard für die vollständige Ausgabe der „article“ Content-Klasse festgelegt.   Wird in eZ Publish ein Content-Objekt in einem Template gerendert, so ist dafür – im Regelfall – die Klasse eZ\Publish\Core\MVC\Symfony\Controller\Content\ViewController zuständig. Sie bringt zusätzlich zu den Funktionalitäten der Symfony2-Controller-Basisklasse noch eZ Publish-spezifische Methoden mit, ist in das eZ Publish Routing eingebunden ist und regelt – wie eben geschehen – die konfigurierbare Templatezurodnung. Der Dateibaum unseres Bundles hat dadurch etwas zugenommen:

stage_2

Inhalt einfügen (stage_2)

Bislang hat unser neues Template noch nicht viel Funktionalität und auch seine eZ Publish-typischen Eigenschaften beschränken sich auf die Zuordnung zu einer Content-Klasse. Doch das soll sich im Folgenden ändern. Ergänzen wir die eZ Publish-eigenen Template-Helper vom Typ „ez_render_field“ im „article“-Template, erscheinen darin auch die aktuellen Inhalte des Content Objekts:

{% extends "MayflowerTemplateTutorialBundle::pagelayout.html.twig" %}
{% block content %}
    <h1>{{ ez_render_field( content, "title" ) }}</h1>
    <h2>[{{ ez_render_field( content, "short_title" ) }}]</h2>
    {{ ez_render_field( content, "author" ) }}
    <div>
        {{ ez_render_field( content, "body" ) }}
    </div>
{% endblock %}

Die Helperfunktion erhält als Parameter ein eZ Publish Content-Objekt, den Bezeichner des gewünschten Felds sowie – optional und in unserem Fall nicht benötigt – Parameter zum Finetuning der Ausgabe.

Im ersten Teil des Tutorials haben wir nun ein einzelnes Template für eine Content-Klasse definiert. In Teil zwei wird es darum gehen, einen eigenen Controller zu definieren, der es ermöglicht weiterführende Informationen aus eZ Publish zu gewinnen, zusammenzustellen und in einem Template zu rendern.

Weiter geht es mit der Einbindung von Logik in einem eigenen Controller in Teil 2.

Avatar von Andreas Haberberger

Kommentare

Eine Antwort zu „eZ Publish 5 Templating – Teil 1: Basics“

  1. eZ Publish 5 Templating – Teil 1: Basics http://t.co/SBhTAmIJ92 via @mayflowerphp

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert


Für das Handling unseres Newsletters nutzen wir den Dienst HubSpot. Mehr Informationen, insbesondere auch zu Deinem Widerrufsrecht, kannst Du jederzeit unserer Datenschutzerklärung entnehmen.