Von veröffentlicht am

Statamic Frontend Basics

Eine kurze Einführung in Antlers, Statamic Tags und in die Template-Struktur von Statamic

Basics: Teil 3, 15 min.

dalle-2022-11-15-16.14.26---frontend-grid--linear-illustration-80ies-colors-.png

Bild generiert mit https://labs.openai.com/

Statamic nutzt Antlers als Template-Engine. Antlers ist eine Erfindung von Statamic und dient der Ausgabe von Informationen. Es ist einfach und schnell zu lernen, hat aber auch seine Beschränkungen.

Antlers ist eine Domain Specific Language ("DSL") für das Frontend von Statamic. Es ist vergleichbar zu anderen Template Sprachen wie Twig, Blade oder Smarty. Antlers ermöglicht es Entwickler:innen, den Programmfluss im Frontend zu kontrollieren und Daten auszugeben. Dazu verwendet Antlers Tags, die von geschweiften Klammern umgeben sind.

Statamic hat einen Parser für Antlers Dateien. Alle Dateien in /resources/views/*.antlers.html werden durch diesen gerendert.

Datentypen

Statamic speichert die Daten in Yaml Files im Verzeichnis /content ab. Diese Datenstrukturen werden indexiert und sind beim Aufruf einer Seite im Frontend verfügbar. Antlers muss/kann mit den in der Yaml definierten Datentypen umgehen. Dazu gehören: String, Integer, Float, Array und Directory.

Datenausgabe

Die Struktur der Daten im CMS werden von Statmic über Blueprints definiert. Hat man eine Datenstruktur definiert und will diese ausgeben, dann kann man den verwendeten Handler in geschweifte Klammern setzen. Im folgenden Beispiel geben wir das Textfeld "Title" (String) über Antlers aus:

<h1>{{ title }}</h1>

Ausgabe:

<h1>Beitragstitel</h1>

Je nach Feldtype kann die darin enthaltene Struktur komplex sein. Über den Bueprint können wir ein Feld vom Type Array erstellen. Zum Beispiel, wenn wir ein Replicator Field "Titles" (Array) verwenden mit einem eingebetteten Textfeld "Title" (String). Wollen wir nun alle Titel ausgeben, dann können wir einen einfachen Loop generieren:

{{ titles }}
	<h2>{{ title }}</h2>
{{ /titles }}

Ausgabe:

<h2>Erster Beitragstitel</h2>
<h2>Zweiter Beitragstitel</h2>
<h2>Dritter Beitragstitel</h2>

Hier wird durch alle Titel iteriert und innerhalb des Scopes der Schlaufe können wir dann auf die eingebetteten Daten zugreifen.

Viele Feldtypen in Statamic speichern mehr als nur einfachen Text. Legt man ein Feld vom Type Assets an, dann bietet das Feld Zugriff auf die Url des Bildes und den alternativen Text. In Yaml wird dies als Map (Dictionaries) abgelegt. In Antlers können wir bequem über folgenden Syntax darauf zugreifen:

<img src="feature_image:src" alt="feature_image:alt">

Daten modifizieren

Meist reicht es nicht Daten einfach auszugeben. Häufig müssen die Daten noch formatiert oder transformiert werden. Dazu bietet Statamic sogenannte Modifiers an. Diese können Daten vor der Ausgabe verändern und sind ein einfaches Mittel um Daten anzupassen:

<h1>{{ title | upper }}</h1>

Ausgabe:

<h1>BEITRAGSTITEL</h1>

Die Modifier können auch helfen, direkt auf ein Element eines Arrays zuzugreifen. Will ich das erste Element eines Arrays, dann kann ich dies wie folgt machen:

<h1>{{ titles | first | upper }}</h1>

Ausgabe:

<h1>ERSTER BEITRAGSTITEL</h1>

Modifiers können helfen, Daten zu formatieren. Klassischerweise will man ein Datum länderspezifisch formatieren:

{{ updated_at format="d.m. Y" }}

Ausgabe:

23.10. 2022

Modifier können fast beliebig kombiniert werden. Ähnlich wie Unix Commands kann man Modifier verbinden (pipen) und so den gewünschten Effekt erzielen:

{{ titel | ascii | upper | widont }}

Ausgabe:

UEBER UNSER&nbsp;TEAM

Auch zum Vergleich von Daten können Modifier verwendet werden. Dazu weiter unten mehr.

Programmfluss

Neben der Ausgabe von Daten kann auch der Fluss des Programms durch Antlers gesteuert werden. Dies ist wichtig, will man Daten nur unter gewissen Bedingungen anzeigen oder will man durch eine Menge an gleichförmigen Daten iterieren.

If und else

Im folgenden Beispiel wird geprüft, ob ein feature_image existiert oder nicht:

{{ if feature_image }}
	Bild existiert
{{ else }}
	Bild existiert nicht
{{ /if }}

Häufig ist die Abfrage jedoch komplexer als "existiert das Feld". Man will beispielsweise wissen, ob ein Text eine gültige E-Mail-Adresse darstellt. Hierzu kann man wiederum Modifiers nutzen, die einen Boolean zurückgeben. Im folgenden Beispiel prüfen wir, ob contact_email eine gültige E-Mail-Adresse repräsentiert und geben diese verschleiert aus:

{{ if contact_email | is_email }}
	<a href="mailto:{{ contact_email }}">{{ contact_email | obfuscate_email }} </a>
{{ /if }}

Loops

Antlers kennt keine klassischen for, foreach oder while -Loops. Schlaufen werden meist mittels der Daten generiert. Hat man ein Array von Images, dann kann man wie folgt durch dessen Werte iterieren:

{{ images }}	
     <img src="{{ src }}" alt="{{ alt }}">
{{ /images }}

Das Tag loop ermöglicht es, eine Schlaufe zu konstruieren.

Tags

Bis jetzt haben wir uns mit den Grundlagen von Antlers beschäftigt. Diese ermöglichen es Daten auszugeben, die bereits im Kontext eines Seitenaufrufs von Statamic bereitgestellt wurden. Ruft man im Browser direkt eine Seite auf, dann stehen die Inhalte der Seite im Kontext zur Verfügung. Diese können dann einfach als Variablen, z.B. {{ title }}, in der View ausgegeben werden.

Häufig will man aber darüber hinaus mit Statamic interagieren. Man will zusätzliche Daten abfragen oder Interaktionen zwischen der Nutzer:in und Statamic zulassen. Tags ermöglichen genau dies. Es sind zusätzliche Bausteine, die Daten aus Statamic holen und filtern können. Mit den Tags lassen sich Formulare bauen und Interaktionen mit der Nutzer:in werden möglich.

Collection

Das am meisten verwendete Tag ist collection. Das Tag ermöglicht es, eine Liste von Einträgen aus Statamic abzufragen. Hat man beispielsweise eine Collection "Posts" und will auf der Startseite eine Liste der letzten zehn Einträge darstellen, dann kann dies mit dem Collection-Tag zusammengestellt werden.

Im folgenden Beispiel werden die letzten Zehn Beiträge der Collection Posts abgebildet. Pro Post wird der Titel und die Anzahl Kommentare ausgegeben:

<section>
{{ collection:posts limit="10" sort="date:desc" }}
	<article>
		<h3><a href="{{ url }}">{{ title }}</a></h3>
		<small>Comments: {{ comments | count }}</small>
	</article>
{{ /collection:posts }}
</section>

Das collection Tag bietet verschiedene Möglichkeiten zum Filtern der Daten an. Folgendes Snippet zeigt alle Produkte, die der Kategorie "spielzeug" zugeordnet sind:

{{ collection:products taxonomy:category="spielzeug" }}
	<h3><a href="{{ url }}">{{ title }}</a></h3>
{{ /collection:products }}

Oder es sollen alle Artikel und Produkte eines Autors gelistet werden:

{{ collection from="posts|products" author:is="miky" }}
	<h3><a href="{{ url }}">{{ title }}</a></h3>
{{ /collection }}

Bei grösseren Seiten muss auch durch die Resultate geblättert werden können. Statamic bietet hier eine einfache Pagination an:

{{ collection:posts paginate="10" as="posts" }}
    {{ if no_results }}
        <p>Keine Resultate.</p>
    {{ /if }}
    {{ posts }}
	<article>
		<h3><a href="{{ url }}">{{ title }}</a></h3>
		<small>Autor: {{ author }}</small>
	</article>
    {{ /posts }}
    {{ paginate }}
        <a href="{{ prev_page }}">⬅ Vorherige Seite</a>
        {{ current_page }} von {{ total_pages }} Seiten
        (Total {{ total_items }} Beiträge)
        <a href="{{ next_page }}">Nächste Seite  ➡</a>
    {{ /paginate }}
{{ /collection:posts }}

Taxonomy

Neben collection ist taxonomy eines der am häufigsten genutzten Tags. Eine Taxonomy ist eine Ordnungsstruktur für Artikel. Klassische Taxonomien sind Tags oder Kategorien. Artikel werden diesen zugeordnet und können entsprechend gefiltert werden. Dadurch kann man Artikel inhaltlich gruppieren.

Mit dem Taxonomy-Tag können alle Tags oder Kategorien abgefragt werden. Dies ist beispielsweise hilfreich, wenn ein Filter für alle Artikel erstellt werden soll.

Im folgenden soll eine Liste aller möglichen Tags ausgegeben werden, mit der Anzahl verlinkter Artikel:

<ul>
{{ taxonomy:tags }}
    <li><a href="{{ url }}">{{ title }} ({{ entries_count }}</a></li>
{{ /taxonomy:tags }}
</ul>

Nav

Das nav Tag frag die in Statamic erstellte Navigation ab. Eine Navigation ist eine hierarchische Struktur. In Statamic werden hierarchische Inhaltstypen wie Navigationen oder hierarchische Collections als sogenannte structures abgebildet.

Im folgenden Beispiel wird eine Navigation mit einer maximalen Verschachtelungstiefe von drei Ebenen abgebildet. Die {{ *recursive children* }}-Anweisung wiederholt die Anweisungen des Nav Tages für jedes Kind des aktuellen Knotens.

<ul>
   {{ nav :from="main_nav" max_depth="3"}}
      <li>
         <a href="{{ url }}"{{ if is_current || is_parent }} class="active"{{ /if }}>{{ title }}</a>
         {{ if is_current || is_parent }}
            {{ if children }}
               <ul>{{ *recursive children* }}</ul>
            {{ /if }}
         {{ /if }}
      </li>
   {{ /nav }}
</ul>

Ausgabe:

<ul>
	<li>
	         <a href="/erster-beitrag" class="active">erster Beitrag</a>
	</li>
	<li>
	         <a href="/zweiter-beitrag" class="active">zweiter Beitrag</a>
		<ul>
			<li>
			         <a href="/dritter-beitrag">dritter Beitrag</a>
			</li>
		</ul>
	</li>
</ul>

Layout, Templates und Partials

Um das Thema Frontend Basics abzuschliessen, muss geklärt werden, wie Layouts, Templates und Partials miteinander interagieren. Gibt es wie in WordPress eine Template Hierarchie? Die Antwort lautet Nein. Es ist der Entwickler:in überlassen, welches Template für welchen Aspekte der Seite zuständig ist.

Wird eine Statamic Seite aufgerufen, dann lädt Statamic ein Layout für die Seite. Standardmässig ist dies /resources/views/layout.antlers.html. Im Layout wird die Basisstruktur der Webseite definiert. Innerhalb des Layouts wir dann je nach Inhalt ein Template oder ein Partial geladen.

Das folgende Layout-Beispiel aus der Statamic Basisinstallation definiert einige Basics einer HTML-Seite und ruft dann {{ template_content }} auf. Template_content ruft das im Entry definierte Template auf oder lädt default.antlers.html:

<!doctype html>
<html lang="{{ site:short_locale }}">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>{{ title ?? site:name }}</title>
        <link rel="stylesheet" href="{{ mix src='css/tailwind.css' }}">
    </head>
    <body class="bg-gray-100 font-sans leading-normal text-gray-800">
        <div class="max-w-4xl mx-auto px-2 lg:min-h-screen my-2">
            {{ template_content }}
        </div>
        <script src="{{ mix src='/js/site.js' }}"></script>
    </body>
</html>

Ein Template definiert das Markup des Inhaltes. Die konkrete Ausformulierung des Templates richtet sich nach dem Inhalt. Im folgenden ein Beispiel für eine sehr simples Template zur Darstellung einer Einzelseite. Das Template kann als /resources/views/page.antlers.html gespeichert werden. Damit das Template angewandt wird, muss es der Seite zugewiesen werden. Dazu dient das template fieldtype:

<article>
	<h1>{{ title }}</h1>
	<p>Von <address class="inline" rel="author">{{ author:name }}</address></p>
	{{ content }}
</article>

Unter Partials versteht Statamic Elemente, die an beliebigen Stellen geladen werden können. So können wiederverwendbare Komponenten erstellt werden und der Code wird insgesamt besser organisiert. Ein Partial kann beispielsweise für ein Fieldset verwendet werden. Oder der Footer kann in ein Partial ausgelagert werden. Partials können an beliebiger Stelle in Antlers eingebunden werden:

<article>
	<h1>{{ title }}</h1>
	{{# Hier wird das author partial geladen #}}
	{{ partial:partials.author }}
	{{ content }}
</article>

Das Partial /resources/views/partials/author.antlers.html wird über das Tag {{ partial:partials.author }} aufgerufen. Darin befindet sich die Darstellung der Autor:in, die nun auch anderswo in statamic verwendet werden kann.

<p>Von <address class="inline" rel="author">{{ author:name }}</address></p>  

Takeaway

Dies war nur eine Einführung in die von Statamic verwendeten Frontend Konzepte. Antlers ist eine einfache aber mächtige Sprache um Daten auszugeben und zu manipulieren. Antlers hat aber auch seine Einschränkungen. Müssen Daten in der View verarbeitet werden, ist dies müham. Bis Statamic 3.4 war es beispielsweise gar nicht möglich Variablen in Antlers zu setzen. Heute geht dies, aber es ist nicht gerade elegant oder intuitiv.

Modifiers springen in die Lücke, wenn es darum geht, Daten für die Darstellung zu formatieren. Zum Beispiel dann, wenn ein Datum formatiert werden soll. Mit Modifiers bietet Statamic Bausteine an, die kombiniert ein mächtiges Tool ergeben, um Daten die Form zu geben, die wir für die Ausgabe brauchen.

Interaktionen mit Statamic finden in Antlers über Tags statt. Diese ermöglichen es, Daten aus Statamic zu holen, zu filtern und zu manipulieren. Die Tags bieten ein Interface zu den verwalteten Daten und machen den Zugriff darauf zum Kinderspiel.