web & mobile DEVELOPER 10 / 2015 – Neos CMS NodeTypes

Bildschirmfoto 2015-09-22 um 12.01.40

 

Neos CMS – NodeType Mania

Eines der spannendsten Konzepte im CMS Umfeld derzeit ist sicherlich das der NodeTypes des Open Source CMS Neos – nie war es einfacher, völlig flexible Content-Strukturen aufzubauen und zu verwenden.

Von Patrick Lobacher

Den meisten Lesern wird zunächst der Name „Neos CMS“ nicht unbedingt bekannt vorkommen. Hierbei handelt es sich um das seit 8 Jahren in der Entwicklung befindliche CMS „TYPO3 Neos“. Am 18.05. haben sowohl TYPO3 Association wie auch Neos-Team gemeinsam und in aller Freundschaft entschieden, zukünftig getrennte Wege zu gehen. Damit einhergehend wurde das Produkt auch um den Namenszusatz „TYPO3“ erleichtert.

Download & Installation

Vor kurzem wurde die Major-Version 2.0 veröffentlicht, auf die sich der vorliegende Artikel bezieht. Um die Beispiele entsprechend nachzuvollziehen, ist es daher notwendig diese zu installieren. Neos CMS kann auf der folgenden Seite heruntergeladen werden – hier finden Sie auch Hinweise zur Installation oder zum Upgrade einer älteren Version: https://neos.typo3.org/develop/download.html

Sollte bis zur Veröffentlichung des Artikels auch die Dokumentation vom TYPO3-Projekt weggezogen sein, so können Sie Ihr Glück unter http://neos.io/ versuchen.

Die folgenden Beispiele basieren auf der Demo-Site „NeosDemoTypo3Org“, die man erhält, wenn man Neos installiert.

Nodes & NodeTypes

Alle Inhalts-Strukturen basieren in Neos auf sogenannten Nodes. Nodes können Seiten, Inhalte, Strukturen oder ähnliches repräsentieren. Dabei haben Nodes einen sogenannten NodeType, einen eindeutigen Pfad (NodePath) und verschiedene, individuelle Eigenschaften (Properties).

So hat beispielsweise der Site-Root den Pfad /sites, die Demo-Website den Pfad /neosdemotypo3org und der erste Content-Container darauf /main. Jede Seite und jedes Element lässt sich so eindeutig als Pfad identifizieren.

neos_nodetypemania_lobacher_01

Weiterhin besitzt die Demo-Website den NodeType TYPO3.NeosDemoTypo3Org:Homepage, der vom SuperType TYPO3.Neos.NodeTypes:Page ableitet (der wiederum vom SuperType TYPO3.Neos:Document ableitet) und damit dessen Eigenschaften erbt. Hier wurde ein eigener NodeType aus dem Grund verwendet, da man auf der Homepage einen sogenannte Shared-Footer einbringen wollte.

Grundsätzlich gibt es technisch keinerlei Unterscheidung zwischen Seiten und Inhaltselemente. Lediglich die verschiedenen Wizards und UI-Elemente in Neos zeigen u.U. unterschiedliche Nodes an. So stellt der Document-Tree auf der linken Seite des Neos-Backends beispielsweise alle Nodes an, die vom SuperTyp TYPO3.Neos:Document ableiten.

Eingebaute Inhalts-Elemente

Neos bringt bereits eine ganze Menge Content-Elemente mit – wie z.B. „Text“, „Headline“ oder „Image“. Diese basieren auf NodeType-Definitionen, die sich im Ordner Packages/Application/TYPO3.Neos.NodeTypes/Configuration befinden. Dort liegen die enstprechenden Konfigurations-Dateien, die mit „NodeType“ anfangen und mit „.yaml“ enden. Diese werden von Neos automatisch eingelesen und ausgewertet.

Das Demo-Package bringt nun weitere NodeTypes mit, welches sich ebenfalls in dessen Verzeichnis Configuration befinden. Jedes Package kann zudem ebenfalls neue NodeTypes einbringen oder bestehende verändern.

Die Kochrezept-Datenbank

Für diesen Artikel wollen wir eine kleine Kochrezept-Datenbank aufbauen, welche folgende Features besitzt:

  • Einem Seitentyp „Rezept“, auf dem man Arbeitsschritte einfügen kann und auch hinterlegen kann, welche Lebensmittel verwendet wurden
  • Ein Content-Element „Arbeitsschritt“, welches aus einer Überschrift, einem Bild und einem Text besteht
  • Einem Seitentyp „Lebensmittel“, auf dem ein Lebensmittel näher beschrieben wird
  • Ein Content-Element „Rezept-Teaser-Menü“ welches ein Menü rendert, das alle Rezepte beinhaltet

Package anlegen

Wir könnten grundsätzlich auch direkt in der Demo-Website arbeiten – schöner ist es allerdings in diesem Fall ein eigenes Package anzulegen. So können wir die Rezeptdatenbank auch leicht mit einer anderen Website verwenden.

Dafür geben wir auf der Kommandozeile folgenden Befehl im Root-Verzeichnis der Installation an:

Listing 1: Kommandzeile

Hiermit wird ein Package (im Verzeichnis Application/Packages/) angelegt, welches als Vendor-Namespace „Wmd“ (web & mobile DEVELOPER) und als Package-Namespace „Recipes“ erhalten hat.

Weitere Pfadangaben ab sofort sind relativ von diesem Verzeichnis ausgehend.

Settings

Sobald man neue Content-Elemente anlegen will, erhält man den sogenannten „New Content Element Wizard“, welcher eine Auswahl der zur Verfügung stehenden Content.-Elemente präsentiert.

Hier gibt es per Default drei Sektionen: General, Structure und Plugin. Wir wollen dies um eine neue Sektion „Rezepte“ erweitern.

Dafür müssen wir die Datei Configuration/Settings.yaml anlegen. Fügen Sie anschließend folgenden Code dort ein:

Listing 2: Settings.yaml

Hiermit wird ein Gruppe „recipes“ definiert, welche ein Label „Rezepte“ hat und über die Position zunächst ganz unten im New Content Element Wizard einsortiert wird.

neos_nodetypemania_lobacher_02

Zusätzlich wird mit dem Schlüssel typoScript.autoInclude erreicht, dass das zu dem Paket zugehörige TypoScript automatisch geladen wird. Dazu muss eine Datei root.ts2 im Verzeichnis Resources/Private/TypoScript/ existieren. Legen Sie diese zunächst leer an.

Beachten Sie zudem, dass bei Yaml jede Zeile immer mit zwei Leerzeichen (und niemals Tabs) je Ebene eingerückt wird.

Content Element Arbeitsschritt

Für diesen neuen NodeType legen wir eine Datei Configuration/NodeTypes.Content.yaml an und vermerken dort die folgende Definition:

Listing 3: NodeTypes.Content.yaml

Hier vergeben wir zunächst einen Namen für unseren NodeType. Dazu müssen wir den Namespace verwenden (Vendor-Namespace Wmd gefolgt von dem Package-Namespace Recipes) und durch einen Doppelpunkt getrennt den Namen des NodeTypes angeben. Wir entscheiden uns hier für RecipeTask als Namen.

Anschließend geben wir mit der Option superTypes den NodeType an, von dem unser NodeType erben soll. Hier wählen wir den für (fast) alle Content-Elemente nützlichen Basis-Typ TYPO3.Neos:Content.

Mit dem Unterschlüssel ui wird das Content-Element in das User-Interface eingepasst. hier wird beispielsweise festgelegt, dass es in der Grupp recipe des New Content Element Wizards auftauchen soll.

Unterhalb von properties folgen nun die drei Eigenschaften, die das Content-Element haben soll: eine Headline, ein Bild und der Text. Bis auf das Bild können alle Inhalte inline editiert werden, daher besitzen diese auch die Option inlineEditable: TRUE.

Das Bild wird über den Property-Inspektor am rechten Bildschirmrand editiert – hier muss zudem ein spezieller Typ (type) angegeben werden, der dafür sorgt, dass man ein entsprechendes Interface hierfür erhält.

Nun wird ein Fluid-Template benötigt, welches im Verzeichnis Resources/Private/Templates/NodeTypes/ erwartet wird und den Namen RecipeTask.html haben muss:

Listing 4: RecipeTask.html

Das Template enthält zunächst zwei Namespaces, damit einerseits das Bild angezeigt werden kann (Package TYPO3.Media) und andererseits das JavaScript eingebracht wird (Package TYPO3.Neos). Letzteres ist wichtig, damit man den Text und die Headline inplace editieren kann.

In die Datei Root.ts2 des Packages Wmd.Recipes tragen wir nun noch folgendes TypoScript ein:

Listing 5: Root.ts2

Grundsätzlich kann man das Auslesen der Properties (wenn man diese nicht verändern will) auch weglassen – dies übernimmt Neos automatisch selbst und stellt dem Template die Property unter {propertyname} zur Verfügung.

Allerdings ist die explizite Auflistung natürlich übersichtlicher und zudem kann man die Properties (wie im Fall der Headline) vor dem Ausgeben prozessieren. Hier wird der Inhalt beispielsweise in Großbuchstaben umgewandelt.

neos_nodetypemania_lobacher_03

Nun können wir bereits Arbeitsschritte eingeben – das Bild wird im Inspektor gepflegt, Headline und Text direkt auf der Seite.

Seitentyp Lebensmittel

Als nächstes wollen wir den Seitentyp für die Lebensmittel erstellen. Hierzu wollen wir lediglich den Seitentyp TYPO3.Neos.NodeTypes:Page erweitern und zudem eine Checkbox integrieren, mit der man angeben kann, ob das Lebensmittel vegetarisch ist.

Hier legen wir eine Datei NodeTypes.Document.yaml im Verzeichnis Configuration/ mit dem folgenden Inhalt an:

Listing 6: NodeTypes.Document.yaml

Unser neuer Seitentyp wird intern mit Wmd.Recipes:Groceries bezeichnet und leitet vom Default-Seitentyp ab. Wir wählen ein eigenes Icon und legen einen Bereich im Property-Inspektor an, um Properties aufzunehmen. Anschließend wird die Property vegetarian in eben jenem Bereich im Property Inspektor positioniert. Der Datentyp boolean  wird dabei automatisch als Checkbox repräsentiert. Hiermit können wir einstellen, ob ein Lebensmittel vegetarisch ist (dies geben wir später bei der Auflistung der an einem Rezept beteiligten Lebensmittel wieder aus).

neos_nodetypemania_lobacher_04

Seitentyp Rezept

Das Rezept nun hat ein paar Besonderheiten:

  • Es soll eine eigener Content-Bereich geschaffen werden, auf dem lediglich Content-Elemente vom Typ Wmd.Recipes:RecipeTask eingefügt werden dürfen und keine anderen
  • Der Seite können Lebensmittel zugeordnet werden, deren Auswahlliste automatisch aus allen verfügbaren Lebensmittel-Seiten ermittelt werden
  • Die Lebensmittel werden auch auf der Rezept-Seite anzeigt (inkl. einer Markierung, falls dieses vegetarisch sein sollte)

Starten wir zunächst mit dem NodeType, den wir in der Datei Configuration/NodeTypes.Document.yaml ergänzen:

Listing 7: NodeTypes.Document.yaml

Hier sind einige Dinge beachtenswert. Beispielsweise wurde über die Eigenschaft childNodes angegeben, dass – wann immer ein Rezept als Seite eingefügt wird – automatisch auch eine Node mit dem Namen tasks mit angelegt wird. Diese kann grundsätzlich Content enthalten, da sie vom Typ ContentCollection ist – wird aber durch die Untereigenschaft constraints so eingeschränkt, dass lediglich Rezeptschritte eingefügt werden dürfen.

Weiterhin haben wir eine Eigenschaft groceries, die vom Typ references ist. In den weiteren Eigenschaften geben wir an, dass wir hier Elemente vom Typ Groceries verknüpfen wollen. Das sorgt dafür, dass wir im Property-Inspektor eine Auswahlbox bekommen, in der wir nach Lebensmitteln suchen können.

neos_nodetypemania_lobacher_05

Wenn wir lediglich eine Relation hätten zulassen wollen, dann müssten wir hier den Typ reference wählen.

Wir wollen nun an dieser Stelle das Standard-Template etwas erweitern. Dazu müssen wir zunächst den sogenannten „Root-Matcher“ (welches sich in der Datei Packages/Application/TYPO3.Neos/Resources/Private/TypoScript/DefaultTypoScript.ts2 befindet) so erweitern, dass wir einen eigenen Render-Pfad immer dann bekommen, wenn eine Seite vom Typ Recipe ist.

Dazu erweitern wir unsere Roots.ts2 des Packages Wmd.Recipes:

Listing 8: Root.ts2

Dies sorgt dafür, dass ein TypoScript-Pfad recipe gesucht wird, sobald der Node vom Typ Recipe ist.

Grundsätzlich wollen wir von der Definition des TypoScript-Pfads page im Site-Package ableiten und einige Dinge verändern bzw. hinzufügen. Da Site-Packages aber immer am Schluss geladen werden, müssen wir nun doch kurz in das Root.ts der Demo-Website gehen und ganz am Ende die folgende Zeile positionieren, die dafür sorgt, dass am Ende ein spezielles TypoScript aus unserem Paket geladen wird.

Listing 9: Root.ts2 (DemoSite-Package)

Wir legen nun das Verzeichnis Packages/Application/Wmd.Recipes/Resources/Private/TypoScript/NodeTypes/ an und legen dort eine Datei Recipe.ts2 mit folgendem Inhalt an:

Listing 10: Recipe.ts2

Hier kopieren wir zunächst die gesamte TypoScript-Konfiguration der Website in den Root-Pfad recipe (diesen haben wir weiter oben eingestellt). Anschließend überschreiben wir den Template-Pfad hierfür, damit wir die Möglichkeit haben, dieses individuell anzupassen.

Zusätzlich definieren wir den Content-Bereich tasks (der die Arbeitsschritte aufnehmen wird) und wir lesen die Eigenschaft groceries aus, um die zugeordneten Lebensmittel zu erhalten.

Nun kopieren wir uns das Default-Template der Demo-Website von Packages/Sites/TYPO3.NeosDemoTypo3Org/Resources/Private/Templates/Page/Default.html nach Packages/Application/Wmd.Recipes/Resources/Private/Templates/Page/Recipe.html und ergänzen folgenden Code (fett gedruckt):

Listing 11: Recipe.html

Zunächst definieren wir einen Namespace auf das Neos-Package um Nodes verlinken zu können.

Dann prüfen wird, ob dem Rezept Lebensmittel zugewiesen wurden und geben diese aus. Gleichzeitig verlinken wir auch jedes ausgegebene Lebensmittel mit der zugehörigen Seite. Wenn beim Lebensmittel die Checkbox „vegetarisch“ ausgewählt wurde, geben wir hier einen kurzen Hinweistext aus.

Anschließend geben wir die Arbeitsschritte aus.

neos_nodetypemania_lobacher_06

Rezepte Menü

Nun wollen wir noch ein Content-Element erstellen, mit dem es möglich ist, alle in das System eingegebenen Rezepte auszulesen.

Hierfür starten wir wieder bei der Datei Configuration/NodeTypes.Content.yaml, die wir wie folgt ergänzen:

Listing 12: NodeTypes.Content.yaml

Nun brauchen wir noch etwas TypoScript, um das Menü zu konfigurieren und ein eigenes Template auszuwählen – dies ergänzen wir in der Roots.ts2 des Packages Wmd.Recipes:

Listing 13: Root.ts2

prototype(Wmd.Recipes:RecipeTeaserMenu) < prototype(TYPO3.Neos.NodeTypes:Menu){
  filter = 'Wmd.Recipes:Recipe'
  entryLevel = 1
  renderHiddenInIndex = 1

  imgwidth  = 80
  imgheight = 60
}

Einerseits geben wir hier unseren Prototypen an und lassen ihn vom Menu-Prototypen ableiten. Und andererseits setzen wir einen Filter auf den NodeType Recipe, um im Menü ausschließlich Rezepte zu erhalten.

Da man die Rezepte-Seiten im Menü ausblenden kann, konfigurieren wir dieses Menü so, dass diese dort wieder integriert sind und setzten schließlich manuell eine Breite und Höhe für das Vorschau-Bild.

Das Template wird nun im Verzeichnis Packages/Application/Wmd.Recipes/Resources/Private/Templates/NodeTypes/RecipeTeaserMenu.html erwartet und hat folgenden Inhalt:

Listing 14: RecipeTeaserMenu.html

Hier gehen wir die Liste der gefunden Rezepte durch und zeigen links das Vorschaubild und rechts den verlinkten Seitentitel an.

neos_nodetypemania_lobacher_07
Schon sind wir fertig mit unserer Rezepte-Datenbank.

Fazit

In diesem Artikel haben wir nun einen anspruchsvollen Use-Case ausschließlich mit NodeTypes und völlig ohne Programmierung umgesetzt. Das soll vor allem die scheir grenzenlose Vielseitigkeit des NodeType-Ansatzes zeigen, mit dessen Hilfe es möglich ist, jedwelche Strukturen in kurzer Zeit aufzubauen.

Nun fehlt nur noch ein graphischer NodeType-Editor – der aber für die zweite Jahreshälfte 2015 angekündigt ist.

Leave a Comment.