eZ Publish 5 Templating, Teil 2: Ein eigener Controller

Avatar von Andreas Haberberger

Eine Übersichtsseite (stage_3)

Nachdem Teil 1 dieses Tutorials grundsätzliche Temen des Templatings für eZPublish 5 behandelt hat,  wollen wir im folgenden Schritt einen eigenen Controller nutzen, um auf einer Seite vom Typ „landing_page“ eine Liste der im ContentTree darunter befindlichen Objekte, die vom Typ „article“ sind, abzubilden.

Dazu erzeugen wir zuerst ein Template für diese Content-Klasse, das wiederum das allgemeine Pagelayout erweitert. Das Template selbst besteht aus einer einzelnen Zeile, die über den Symfony-eigenen Helper „render“ eine Methode in einer Controllerklasse aufruft, die wir gleich im nächsten Schritt definieren werden.

{% extends "MayflowerTemplateTutorialBundle::pagelayout.html.twig" %}
{% block content %}
    {{ render(controller('subtree:getArticles', {'location': location})) }}
{% endblock %}

Im nächsten Schritt deklarieren wir einen gewöhnlichen Symfony2 Controller im Controller-Verzeichnis unseres Bundles. Um später aber auf die eZ Publish-eigenen Content Objekte zugreifen zu können, beerben wir nicht direkt die Symfony2 Controller Klasse, sondern den inzwischen hinlänglich bekannten ViewController aus dem eZ Publish Kernel.

<?php

namespace Mayflower\TemplateTutorialBundle\Controller;

use eZ\Publish\Core\MVC\Symfony\Controller\Content\ViewController;
use eZ\Publish\API\Repository\Values\Content\Query\Criterion;
use eZ\Publish\API\Repository\Values\Content\Query;
use eZ\Publish\API\Repository\Values\Content\Location;

class SubtreeController extends ViewController
{
    /**
     * @param Location $location
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function getArticles($location)
    {
        $searchService = $this->getRepository()->getSearchService();
        $criterion = array(
            new Criterion\ContentTypeIdentifier(['article']),
            new Criterion\Subtree( $location->pathString )
        );
        $query = new Query();
        $query->criterion = new Criterion\LogicalAnd(
            $criterion
        );
        $articleResults = $searchService->findContent( $query );
        $articles = [];
        foreach($articleResults->searchHits as $hit) {
            $articles[] =  $hit->valueObject;
        }
        $response = $this->buildResponse(
            sprintf('%s_%d', __METHOD__, $location->id),
            $location->contentInfo->modificationDate
        );
        return $this->render(
            'MayflowerTemplateTutorialBundle:list:article_list.html.twig',
            ['articles' => $articles, 'viewType' => 'listitem'],
            $response
        );
    }
}

Im einzelnen bedient sich SubtreeController::getArticles() beim Symfony2-Container mit den eZ-eigenen LocationService und SearchService. Ersterer dient dazu, aus der übergebenen LocationId das Location-Objekt zur weiteren Verarbeitung zu gewinnen, über zweiteren führen wir eine Query auf das eZ Publish Query-API aus, deren Ergebnis wir an ein noch zu erstellendes Listentemplate („article_list.html.twig“) übergeben.

Dieses Template iteriert über den Array aus „articles“, den wir in unserem Controller ermitteln und ruft für jeden Eintrag dieses Arrays den Symfony2 Template-Helper „render“ auf, der wiederum in den in Symfony registrierten Service „ez_content“ mündet. „ez_content“ ist ein Alias für den bekannten „ViewController“, so dass sich hier eine Möglichkeit aufzeigt, aus einem Template heraus wiederum andere Content-Objekte über ihre Id („ViewController::viewContent()“) oder LocationId („ViewController::viewLocation()“) zu rendern

<div>Artikelliste:</div>
<ul>
{% for article in articles %}
    {{
        render(
            controller(
                "ez_content:viewLocation",
                {
                    'locationId': article.contentInfo.mainLocationId,
                    'viewType': viewType
                }
            )
        )
    }}
{% endfor %}
</ul>

Ein weiterer Parameter an das Template ist der „viewType“, der – wie man oben in der Templatedefinition sehen kann – an den ViewController als Parameter durchgereicht wird und letztlich definiert, welches Template für den Content (in unserem Fall vom Typ „article“) gerendert wird. Festgelegt wird die Zuordnung zwischen Contentklasse, viewType und Template wieder in unserer überschriebenen „ezpublish.yml“:

system:
    ezdemo_site_user:
        location_view:
            full:
                landing_page:
                    controller: subtree:getArticles
                    match:
                        Identifier\ContentType: landing_page
                article:
                    template: MayflowerTemplateTutorialBundle:full:article.html.twig
                    match:
                        Identifier\ContentType: article
            listitem:
                article:
                    template: MayflowerTemplateTutorialBundle:line:article.html.twig
                    match:
                        Identifier\ContentType: article

Wir haben hier an dieser Stelle einen eigenen viewType („listitem“) festgelegt, der über den Matcher auf den Content-Typ „article“ eingeschränkt wird und auf das Template unter <BundleDir>/Resources/views/line/article.html.twig verweist. Dieses stellt lediglich eine <li>-Zeile dar, die sich in das oben beschriebene Template „article_list.html.twig“ einfügt.

<li>
	<a href="{{ path( location ) }}">
		{{ ez_render_field( content, "title" ) }}
	</a>
</li>

Über diese Möglichkeit, beliebige viewTypes zu definieren und aufzurufen, erhalten wir die sehr mächtige Möglichkeit, verschiedenste – kontextabhängige – Repräsentationen des gleichen Content-Objekts zu erzielen.

Cache Control

Die Zeilen 32-35 unseres SubtreeControllers dienen der Cache-Steuerung. Der ViewController von eZ Publish vereinfacht die Anreicherung des Symfony2 Response-Objekts mit passenden Headereinträgen, die das Caching optimieren. Der erste Parameter stellt hierbei einen eindeutigen Identifier für den Request, der zweite das aktuelle Modifikationdatum des Content Objekts dar.

Avatar von Andreas Haberberger

Kommentare

Eine Antwort zu „eZ Publish 5 Templating, Teil 2: Ein eigener Controller“

  1. Lesenswert: eZ Publish 5 Templating – Teil 2: ein eigener Controller http://t.co/Mwn8m6lNwG

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.