TYPO3 CMS 6.2 LTS – Was ist neu in Extbase & Fluid?

t362neu_extbase

Am 25.03.2014 wurde die neueste Version TYPO3 CMS 6.2 LTS mit Langzeitsupport bis 2017 veröffentlicht. Zu den wichtigsten Änderungen gehören:

  • Rewrite des Install Toos
  • Entschlackung der Code-Basis
  • Portierung des Package-Managements von TYPO3 Flow
  • Einführung eines Distribution-Managers um Distributionen (wie Introduction Package, Government Package, …) zu verwalten
  • Responsive Image Rendering in den Core integriert
  • Core Updater (auf Knopfdruck Minor-Versionen aktualisieren)
  • Data-Provider für Backend-Layouts
  • Übersetzungsmöglichkeit von FAL Medadaten
  • u.v.a.m

Alle Änderungen finden sich in dem Dokument „TYPO3 CMS 6.2 LTS – Die Neuerungen„.

Natürlich wurde aber auch zahlreiche Änderunge im Bereich Extbase und Fluid zugefügt, welche hier im Folgenden genauer aufgelistet werden.

 

Änderungen in Extbase

 

Object Manager

Der Object Manager hat die Methode getScope hinzubekommen, mit der es möglich ist, zu prüfen, ob eine Klasse vom Typ Singleton oder Prototyp ist:

 

Automatische Ermittlung des PageTypes in URLs

Wenn man einen Link setzt, hinter dem das Format geändert werden soll, muss gleichzeitig auch der Parameter pageType gesetzt werden:

Über eine neue TypoScript Option formatToPageTypeMapping, kann nun ein Mapping hinterlegt werden, welches automatisch zur Erkennung des PageTypes beim Wechsel des Formats sorgt:

Nun reicht:

 

Portierung des Object Type Converters

Der in TYPO3 Flow eingeführte „Object Type Converter“ wurde nach Extbase portiert. Damit ist es möglich, Arrays in nicht-persistente Objekte zu konvertieren.

Beispiel: Erstellen eines nicht-persistenten Objekts $demand aus einem GET-Request heraus:

Der GET-Request könnte beispielhaft nun wie folgt aussehen:

Die initializeListAction() des Entity-Controllers enthält dabei den folgenden Code:

Die listAction() des Entity-Controllers:

Die Model-Datei  [Vendor]\[ExtKey]\Domain\Dto\Demand.php:

 

Chaining der QuerySettings

Das Chaining (Verketten) von QuerySettings ist nun auch mit den „neuen“ Optionen setIncludeDeleted und setIgnoreEnableFields (die mit TYPO3 CMS 6.0 eingeführt wurden) möglich:

 

RawQueryResult

Bisher war es möglich, mittels 

$query->getQuerySettings()->setReturnRawQueryResult(TRUE)

 dafür zu sorgen, dass keine Objekte vom QueryManager rekonstruiert werden, sondern das Query-Ergebnis „roh“ zurückgegeben wird.

Ab sofort gibt es diese Möglichkeit nicht mehr zentral, sondern man gibt dies per Query im execute-Statement mittels TRUE an:

 

Rekursive Validierung und optionale Werte

Extbase verwendet nun die von Flow portierte sogenannte „Rekursive Validierung“

Dies bedeutet, dass bei Erzeugung von verschachtelten Objekten (Objekt-Baum) durch den Property-Mapper auch die inneren Objekte validiert werden und nicht nur das äußere Objekt wie bisher.

Zudem ist es nun möglich, leere (optionale) Werte zu zulassen. Will man daher explizit erreichen, dass eine Eigenschaft angegeben werden muss, so muss der NotEmptyValidator verwendet werden.

 

Application Context

Innerhalb von Extbase kann man nun den von TYPO3 Flow bekannten ApplicationContext verwenden. Der Kontext wird über die Umgebungs-Variable TYPO3_CONTEXT gesetzt. Als Root-Kontext gibt es: „Development“, „Testing“ und „Production“. Anschließend kann es einen Sub-Kontext geben – z.B.: „Production/Staging“. Ist kein Kontext gesetzt, wird dieser per Default auf „Production“ gesetzt

Gesetzt werden kann der Kontext beispielsweise wie folgt (z.B. in der Datei .htaccess):

Abgefragt werden kann der Kontext nun wie folgt:

 

Prepared Statements

Es ist nun möglich, im Repository in der Funktion statement() neben einem SQL-String auch ein Prepared-Statement (welches das Interface TYPO3\CMS\Core\Database\PreparedStatement implementieren muss) zu verwenden. In den Typo3QuerySettings gibt es hierzu die Property $usePreparedStatement und die Funktionen usePreparedStatement() sowie getUsePreparedStatement(). Dabei sind Prepared Statements aber nur für  SELECT Abfragen möglich.

Eingeschaltet werden kann das Verhalten per Query via:

Die Verwendung von Prepared Statements beschleunigt die lesenden Repository-Zugriffe unter Extbase wesentlich.
Einen Artikel zu Prepared Statements in TYPO3 gibt es hier: http://buzz.typo3.org/teams/core/article/typo3-45-lts-prepared-queries-are-the-way-to-go/

 

Query Cache

Bislang war die Extbase Persistenz relativ langsam. Zum Teil war daran das Erstellen der Queries dafür zuständig. Für jeden Query mussten die Methoden parseQuery() und buildQuery() aufgerufen und erneut abgearbeitet werden. Daher wurde nun ein sogenannter „Query Cache“ eingeführt, der die Query-Struktur zwischen speichert. Damit kann der Query erneut verwendet werden – sogar mit unterschiedlichen Parametern.

Zuständig dafür ist der neu geschaffene QueryParser: 
\TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser

Der Query Cache ist per Default eingeschaltet, kann aber manuell per Query ausgeschaltet werden, wenn der Cache zugespammt werden sollte:

Der zuständige Cache lautet: \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend und die Konfiguration: $GLOBALS[‚TYPO3_CONF_VARS‘][‚SYS‘][‚caching‘][‚cacheConfigurations‘]= array(‚groups‘ => array(‚system‘));
Infos hierzu finden sich hier:
 http://forge.typo3.org/projects/typo3cms-core/repository/revisions/2583fd2a12dd3e740a9739f73aa602c2793999ec

 

JsonView Backport

Das Feature „JsonView“ wurde für die TYPO3 CMS 6.2 LTS von TYPO3 Flow nach Extbase portiert. Vor allem bei der Verwendung mittels Ajax oder als Webservice, wird vom Controller ein Datenformat als Rückgabe erwartet, welches leicht weiter verarbeitet werden kann.

Dies ist vermehrt JSON, da dies sehr leichtgewichtig und einfach zu parsen ist. Natürlich könnte man JSON durch ein entsprechendes Fluid-Template zur Verfügung stellen – allerdings ist ein „richtiger“ View deutlich praktischer.

Um den JSON-View im Controller benutzen zu können, wird er über die Variable $defaultViewObjectName aktiviert:

Die Zuweisung erfolgt nun wie gehabt:

Per Default wird nur die Variable „value“ gerendert. Will man andere Variablen rendern lassen, so muss man dies entsprechend konfigurieren:

Die Ausgabe sind dann wie folgt aus:

Die Konfiguration des erzeugenden Arrays kann sehr detailliert durchgeführt werden:

Das Array ARRAY kann dabei die folgenden Optionen besitzen:

Die möglichen Optionen lauten:

_only (array): Nur die angegebene Eigenschaft inkludieren
_exclude (array): Inkludieren von allen Eigenschaft, mit Ausnahme der angegebenen
_descend (associative array): Inkludieren der spezifizierten Sub-Objekte
_descendAll (array): Inkludieren aller Sub-Objekte (als numerisches Array)
_exposeObjectIdentifier (boolean): Inkludieren des Objekt-Identifier als __identifier
_exposeObjectIdentifierKey (string): Angabe des JSON-Feldnames

 

Änderungen in Fluid

 

Image-ViewHelper nun mit optionalem Title-Attribut

Im Image-ViewHelper kann nun das Attribut title weggelassen werden und dieses wird dann auch nicht mit ausgegeben.

Das Verhalten vor TYPO3 CMS 6.2 war so, dass in diesem Fall ein Attribut title gerendert und dafür der Inhalt des Attributs alt verwendet wurde:

 <f:image src=“background.jpg“ alt=“Text“ /> 

führt zu

 <img src=“background.jpg“ alt=“Text“ /> 



(und nicht wie vor TYPO3 CMS 6.2 zu)

 <img src=“background.jpg“ alt=“Text“ title=“Text“ />.

 

Placeholder-Attribut für Textfield und Textarea

Die beiden ViewHelper form.textfield und form.textarea können nun mit einem Attribut placeholder ausgestattet werden:

 

Switch-ViewHelper

Es gibt nun einen Switch-ViewHelper der es ermöglicht, aufgrund eines Ausdrucks (Attribut expression) einen der Fälle (die mit dem case-ViewHelper realisiert werden, Default ist ebenfalls möglich) auszuwählen:

Achtung: Die exzessive Verwendung dieses ViewHelpers könnte auf eine schlechte Architektur hindeuten. So wäre in obigen Beispiel auch folgendes möglich:

 <f:render partial=“title.{person.gender}“ /> 

mit den entsprechenden Partials title.male.html und title.female.html. 
Benötigt man sehr viele case-ViewHelper, sollte man diese besser durch Partials ersetzen.

 

Format.bytes ViewHelper zugefügt

Dieser ViewHelper verwandelt eine Byte-Angabe (in Form eines Integers) in eine lesbare Version


.

Beispiel (fileSize = 1263616):

 

Backend ViewHelper Button.Icon finalisiert

Der Button.Icon ViewHelper, ist nun nicht mehr „experimental“, sondern finalisiert worden. Zweck des ViewHelpers ist es, ein Button-Icon zurückzuliefern (und ggf. zu verlinken)

Für das Attribut „icon“ können zahlreiche (über 310) Werte verwendet werden, die in der folgenden Datei unter dem Schlüssel $GLOBALS[‚TBE_STYLES‘][’spriteIconApi‘][‚coreSpriteImageNames‘] aufgelistet sind:

typo3/systext/core/ext_tables.php

 

addQueryStringMethod Support

Die Option addQueryString arbeitet bisher nur mit GET-Parametern, indem diese an den erzeugten Link wieder angehängt werden. Damit ist es aber nicht möglich POST Parameter (wie sie z.B. bei Widgets vorkommen) anzuhängen.

Über die Option addQueryStringMethod kann nun angegeben werden, welche Parameter verwendet werden sollen: GET oder POST oder GET,POST oder POST,GET – default ist GET. Der UriBuilder verfügt nun ebenfalls über diese Option.

Folgende ViewHelper wurden mit dieser Option ausgestattet: link.action, link.page, uri.action, uri.page, widget.link,  widget.uri, widget.paginate

 

Fluid Template Fallback Support 

Wenn man in Extbase Templates erweitern will, musste man bislang alle Templates kopieren. Ab sofort kann man „Fallback-Pfade“ definieren. Fluid schaut in dem Verzeichnis mit dem höchsten Index und geht (wenn das Template nicht gefunden wurde) runter bis zum kleinsten Index.

Fallbacks gibt es für Templates, Partials und Layouts: 
templateRootPaths, partialRootPaths, layoutRootPaths

6 Comments

  1. formatToPageTypeMapping

    Woher stammt diese Information? Nachdem die Neuerung bei meiner Installation (6.2.3) nicht gegriffen hat, habe ich mal den Source der 6.2.3 durchsucht.. der einzige Fund von „formatToPageTypeMapping“ ist in einem Unit-Test. Wird bei mir auch definitiv nicht ausgewertet..

    Reply
    • In der Datei „ExtensionService.php“ (Verzeichnis: typo3/sysext/Extbase/Classes/Service) gibt es in Zeile ca. 206 die Methode getTargetPageTypeByFormat(), die das entsprechende TypoScript-Setting auswertet.


      public function getTargetPageTypeByFormat($extensionName, $format) {
      $targetPageType = 0;
      $settings = $this->configurationManager->getConfiguration(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS, $extensionName);
      $formatToPageTypeMapping = isset($settings['view']['formatToPageTypeMapping']) ? $settings['view']['formatToPageTypeMapping'] : array();
      if (is_array($formatToPageTypeMapping) && array_key_exists($format, $formatToPageTypeMapping)) {
      $targetPageType = (int)$formatToPageTypeMapping[$format];
      }
      return $targetPageType;
      }

      Reply
  2. Fluid Template Fallback Support:
    Bei meinem ersten Versuch mit den lange ersehnten Fallbacks zu arbeiten, habe ich einige Anlaufschwierigkeiten (vermutlich auch mangels genauem Lesen und der case sensitivity bei Template- und Partial-Dateinamen) gehabt, bis es so klappte, wie ich es wollte.
    Hilfreich wäre meiner Meinung nach, wenn du hier (und in deinem Buch 😉 als 10 = EXT:simpleblog/Resources/Private/Templates angeben würdest und die anderen entsprechend um 10 erhöhst. Denn ich bin fälschlicherweise davon ausgegangen, dass als letzte Möglichkeit immer das Template aus den Extension Ressources genommen wird, was aber nicht der Fall ist.
    VG
    Christian

    Reply
  3. Hallo
    ich bin gerade dabei das JsonView zu benutzen und habe dabei ein Problem.
    Grundsätzich funktioniert das JsonView und das Model wird im JSON ausgegeben. Leider werden Arrays die im Model zurückgegeben werden nicht mit ausgegeben. Kann man das über die setConfiguration Funktion konfigurieren?

    Gruß Jan

    Reply
    • Hi Jan,

      bei mir hat es beispielsweise wie folgt funktioniert (Beispiel ist das Blog-Example):

      public function jsonAction(){
      $this->view->setVariablesToRender(array(‚blogs‘,’posts‘));
      $this->view->setConfiguration(
      array(
      ‚blogs‘ => array(
      ‚_descendAll’=>array(
      ‚_only’=>array(‚title‘,’posts‘),
      ‚_descend’=>array(
      ‚posts’=>array(
      ‚_descendAll’=>array(
      ‚_only’=>array(‚title‘),
      //’_descend’=>array(‚title‘)
      )
      )
      )
      ),
      ),
      )
      );
      $this->view->assign(‚blogs‘, $this->blogRepository->findAll());

      }

      VG Patrick

      Reply

Leave a Comment.