Neos Workshop Teil 2 - Ein eigenes Sitepackage bauen

Daniel Lienert
Daniel Lienert hat neben seinen Aufgaben als ScrumMaster auch eine großen Leidenschaft für gute Softwarearchitektur und performante Systeme.

Im ersten Teil des Neos Workshops haben wir uns bereits eine virtuelle Umgebung für das CMS geschaffen und uns mit der Funktionsweise des Backends vertraut gemacht. Mit diesem Teil wollen wir nun beginnen, ein eigenes Projekt in Neos umzusetzen. Als Beispielprojekt soll uns die Präsenz eines lokalen Weinladens dienen.

Ein neues SitePackage erstellen

Jede neue Seite in Neos startet mit dem Anlegen eines neuen Site Packages. Das Site Package beinhaltet alle Teile, welche das Aussehen und die Grundfunktionen der Seite ausmachen. Um frisch starten zu können, entfernen wir sowohl den Content als auch das Site Package der bereits installierten Demo Seite. Das geht am bequemsten über das Kommandozeilen-Interface von Flow - Flow ist das Applikationsframework hinter Neos.

Dazu loggen wir uns auf unserer Virtuellen Maschine ein, navigieren zum Projektordner (/var/www) und führen die folgenden Befehle aus:

./flow site:prune
./flow package:delete TYPO3.NeosDemoTypo3Org
composer remove typo3/neosdemotypo3org

./flow kickstart:site WL.WeinLaden weinladen.local
./flow site:import WL.WeinLaden

In der ersten Zeile löschen wir mit site:prune alle Inhalte und Seiten der Demo Seite aus der Datenbank. Mit package:delete löschen wir dann das Package der Demo Seite und entfernen es dann auch aus der Liste der per composer installierten Pakete. 
Nun erstellen wir mit kickstart:site unser neues, leeres Site Package welchem wird den Vendornamen WL und den Paketnamen WeinLaden geben. Mit dem site:import in der letzten Zeile importieren wir die root-page welche für das Anzeigen der Seite nötig ist.

Die Flow Kommandozeile

Die Flow Kommandozeile bietet noch jede Menge weitere nützliche Kommandos. Die komplette Liste zeigt der Befehl ./flow help an.
Eine genaue Beschreibung der Befehle, inklusive alle Parameter erhalten Sie mit dem Befehl
./flow help <BefehlName>.

Der Kickstarter legt uns im Verzeichnis Packages/Sites/WL.WeinLaden eine Reihe von Verzeichnissen und Dateien an, deren Bedeutung ich kurz beschreiben möchte.

.
|-- Classes
|-- Configuration
|   `-- NodeTypes.yaml
|-- Resources
|   `-- Private
|       |-- Content
|       |   `-- Sites.xml
|       |-- Templates
|       |   `-- Page
|       |       `-- Default.html
|       `-- TypoScript
|           `-- Root.ts2
|-- Tests
|   |-- Functional
|   `-- Unit
`-- composer.json

Werden PHP Klassen für die Umsetzung der Seite benötigt, werden diese unter Classes abgelegt und von dort automatisch geladen. Das Verzeichnis Configuration enthällt bereits eine Datei "NodeTypes.yaml" welche für die Definition eigener Inhaltstypen verwendet werden kann. 
Unter Resources/Private liegen Dateien, welche für das Projekt benötigt werden, aber nicht von aussen zugänglich sein sollen. Unter anderem wurden hier schon eine rudimentäre Template Datei sowie eine Datei für TypoScript Code angelegt.

Entwicklungsumgebung vorbereiten

Um komfortabel an unserer Seite entwickeln zu können, ist die Verwendung einer IDE, welche zumindest ein Syntax Highlighting der gängigen Websprachen beherrscht, zu empfehlen. Das kann beispielsweise das leichtgewichtige SublimeText oder das mächtige PHPStorm sein.

Um mit einer IDE an unserer Seite arbeiten zu können, kopieren wir uns die Dateien am besten in einen lokalen Ordner. Dazu wechseln wir in das vagrant Verzeichnis (~/vagrant-neosbox) und führen den folgenden, etwas sperrigen Befehl aus, welcher die Dateien in den Ordner neos-workshop in unserem Home Verzeichnis kopiert:

rsync -avP --rsh="ssh -i "$(vagrant ssh-config | grep IdentityFile | awk  '{print $2}')"" vagrant@172.17.28.28:/var/www/Packages/Sites/ ~/neos-workshop

Änderungen, welche wir im Laufe des Workshops an dem SitePackage vornehmen, sollen am Besten automatisch zurück in die Box kopiert werden. Vagrant bringt dafür eine elegante Lösung mit. Um diese zu nutzen, bearbeiten wir die Datei Vagrantfile in unserem Vagrant Ordner (~/vagrant-neosbox) und fügen die unten markierten Zeilen 5 und 6 hinzu.

Die neuen Zeilen führen dazu, dass Änderungen im Ordner neos-workshop von Vagrant automatisch erkannt werden und per rsync an die richtige Stelle in die Box kopiert werden.

Vagrant.configure("2") do |config|
  config.vm.box = 'punktde/workshop'
  config.vm.box_url = "https://punkt.de/Download/workshop.box"
  config.vm.synced_folder '.', '/vagrant', id: 'vagrant-root', disabled: true
  config.vm.synced_folder "~/neos-workshop/", "/var/www/Packages/Sites/", type: "rsync",
    rsync__exclude: ".git/"
  config.vm.network 'private_network', ip: '172.17.28.28'
  config.ssh.forward_agent = true
  config.vm.provider 'virtualbox' do |vb|
    vb.memory = '4096'
    vb.cpus = '1'
    vb.name = 'workshopbox'
  end
end

Nach der Änderung muss die Box einmal neu gestartet werden. Das geschieht mit dem Befehl:

vagrant reload

Die automatische Synchronisation steht nun bereit und kann mit folgenden Befehl gestartet werden:

vagrant rsync-auto

Erstes Templating mit TypoScript und Fluid

Nun kann es richtig los gehen! Im folgenden werden wir die vom Kickstarter erstellten Dateien Schritt für Schritt erweitern, um eine Seite mit Menü, Content und Footer Bereich zu erhalten. Das Endergebnis lässt sich immer auch im GitHub Repository zu diesem Workshop nachschauen.

Da wir uns in diesem Workshop hauptsächlich auf die Funktionen von Neos konzentrieren, beschränken wir uns bei den anderen Bausteinen einer Webseite wie HTML, CSS und Javascript auf das Allernötigste.

Etwas Farbe tut unserer Seite aber trotzdem gut, daher beginnen wir mit dem Einbinden einer, auf dem CSS Framework Bootstrap basierenden, CSS Datei.

Alle direkt herunterladbaren Dateien wie CSS oder Javascript Dateien müssen sich bei Neos im Pfad Resources/Public befinden. Wir erstellen innerhalb unseres Site-Packages daher in diesem Pfad die Datei Resources/Public/Styles/Main.css, welche wir mit dem Inhalt aus https://raw.githubusercontent.com/punktDe/neos-workshop/master/Resources/Public/Styles/Main.css befüllen.

Fluid

Fluid ist eine einfache aber mächtige Template Engine, welche eigens für das Application Framework Flow entwickelt worden ist und auch im CMS TYPO3 Verwendung findet. Alle Konstrukte zur Umsetzung von Beispielsweise Schleifen oder Bedingungen sind selbst valides XML-Markup. Mit eigenen ViewHelpern lässt sich die Sprache beliebig erweitern und an die Anforderungen des eigenen Projektes anpassen. Eine Beschreibung aller Sprachkonstrukte findet sich hier.

Zur Einbindung der Datei ist bereits eine Section im HEAD-Bereich der generierten Default.html vorgesehen. Der Fluid Resource ViewHelper generiert uns den Pfad zu den Dateien unter Resources/Public.

<head>
	<f:section name="stylesheets">
		<link rel="stylesheet" href="{f:uri.resource(path: 'Styles/Main.css', package: 'WL.WeinLaden')}" />
	</f:section>
	<f:section name="headScripts">
	<!-- Put your scripts inclusions for the head here, they will be included in your website by TypoScript -->
	</f:section>
</head>

Welche Sections aus der Template Datei gerendert werden, wird in der TypoScript Datei Root.ts2 definiert.
Hier wird auch das Menü mit dem einfachen Konstrukt "menu = Menu" aus dem TypoScript-Objekt Menu instanziiert und in den Variablen menu bereit gestellt. Die Erstellung des Menüs können wir mit diversen Parametern anpassen. In unserem Beispiel benötigen wir weitere CSS Klassen, damit das CSS von Bootstrap Wirkung zeigt. Die Zeile wird also folgendermaßen erweitert:

menu = Menu {
	attributes.class = 'nav navbar-nav pull-right'
}

Viele weitere Parameter des Menüs und seiner Elemente können hiermit angepasst werden. Eine komplette Liste findet sich in der TypoScript Referenz.

Als letztes erweitern wir das Markup der Default.html um das Menü und ein Logo für unsere Seite.

<f:section name="body">
    <nav class="navbar navbar-default">
        <div class="container">
            <a class="navbar-brand" href="/">Wein<span>Laden</span></a>
            {parts.menu -> f:format.raw()}
        </div>
    </nav>

	<div class="container">
		{content.main -> f:format.raw()}
	</div>
</f:section>

Ein Footerbereich für alle Seiten

Nun fehlt der Seite noch ein frei gestaltbarer Footer Bereich. Dazu reichen kleine Erweiterungen in der Seitenkonfiguration, im TypoScript und dem Template, die im folgenden Schritt für Schritt erklärt werden. Die genaueren Hintergründe, wie Neos die Daten speichert und in welcher Weise wir darauf zugreifen können, soll aber erst Inhalt des dritten Teils des Workshops sein.

Zunächst legen wir in der NodeTypes.yaml, welche wir im Verzeichnis Configuration finden, mit den folgenden Zeilen einen neuen Bereich mit dem Namen footer an:

'TYPO3.Neos.NodeTypes:Page':
  childNodes:
    'footer':
      type: 'TYPO3.Neos:ContentCollection'

Damit erhalten alle neu angelegten Seiten einen weiteren Content-Bereich für den Footer. Dieser Bereich muss nun auch allen bereits angelegten Seiten hinzugefügt werden. Dazu verwenden wir den Befehl node:repair des flow Kommandos auf der Console, welcher die bestehenden Seiten an die neue Konfiguration anpasst und den Footer Bereich auch dort anlegt:

./flow node:repair

In der TypoScript Datei Root.ts2 können wir nun den Footer (Zeile 7-9) ähnlich dem Hauptbereich selektieren und an das Template übergeben ...

content {
// The default content section
	main = PrimaryContent {
		nodePath = 'main'
	}

	footer = PrimaryContent {
		nodePath = 'footer'
	}
}

... und dort im Template anzeigen:

<footer>
	<div class="container">
		{content.footer -> f:format.raw()}
	</div>
</footer>

Sollen alle Seiten den gleichen Footer erhalten, reicht es, die obige Zuweisung im TypoScript durch die Folgende zu ersetzen. Durch die folgenden Zeilen wird nicht der Footer der jeweils gewählten Seite selektiert und bearbeitet, sondern stets der Footer der Root-Seite. 

footer = ContentCollection {
	nodePath = ${q(site).children('footer').property('_path')}
	collection = ${q(site).children('footer').children()}
}
Ansicht der Weinladen Seite nach unserem Workshop

So sieht unsere Seite nach nur wenigen Anpassungen aus.

Somit ist unsere erste Seite mit zwei Inhaltsbereichen und dem Menü fertig und kann mit Inhalten gefüllt werden. Der Stand des Sitepackages nach diesem Teil des Workshops kann auch noch einmal auf dem dazugehörigen Repository auf github nachvollzogen werden.

Autor: Daniel Lienert

Kommentare

Bisher wurden keine Kommentare eingereicht.


Weitere Beiträge

19. August 2016

Anzeigen dynamischer Seiteninhalte im Zusammenspiel mit dem Zurück-Button

In Zeiten von dynamisch nachgeladenem Seiteninhalt kommt es häufiger vor, dass ein Zurückspringen auf … mehr

21. Juni 2016

Agile Coach Camp 17.-19. Juni 2016 in Rückersbach

Es waren einmal zwei ScrumMasterinnen bei punkt.de, die sich nach Fortbildung und Inspiration sehnten. … mehr