Beschreibung des Vorhabens

Dieser Beitrag beschreibt, wie man unter dem Joomla-Template Gantry 5 ein bestehendes Particle modifiziert ohne die Core-Scripte zu verändern, also unter Nutzung eines sauberen Overrides, so wie vom Gantry-Framework vorgesehen. Damit bleibt also Gantry trotz eigener Modifikatione updatefähig.

Dazu wollen wir nur eine sehr kleine Änderung beispielhaft durchführen, eine Änderung die bei einigen Particles Sinn macht, weil diese selten HTML-Text ausgeben, sondern diesen meistens als Plaintext liefern. Sobald man aber z.B. Listen (ul/ul) anzeigen will, werden diese nicht wie gewünscht angezeigt sondern HTML-Zeichen umgewandelt (gefiltert) dargestellt.

Für unser Vorhaben wollen wir das Particle OWLCAROUSEL modifizieren. Wenn wir statt dem standardmäßig eingestellten Content-Scoure Particle den Typ Joomla wählen, wird eines der Ausgabeelemente den Joomla-Beschreibungstext verwenden und als Text ausgeben. Genau dieses Feld wollen wir bei unserem Override modifizieren, so dass die Eingabe von HTML-Code möglich ist und dieser so ausgeben wird.

Dazu muss man wissen, dass TWIG in Gantry verschiedenen Ausgabetypen kennt, die in den TWIG-Scripten als Parameter (in TWIG auch Filter genannt) konfiguriert werden können (e = alias für escape, raw, ...) und einzeln oder kombiniert eingesetzt werden können. 

 

Schrittweises Vorgehen 

1. Override für das Owl-Carousel-Particle erstellen

Die Erleuterung erfolgt am Beispiel des RocketTheme Templates TOPAZ, was sich im Folgenden in dem Templatepfad /rt_topaz/ widerspiegelt. Sollten Sie ein anderes Template verwenden, wäre hierfür Ihr Templatepfad anzupassen.

Wir wollen einen eigenen Layout-Type, nennen wir es Spektrum zur Auswahl im Paticle-Konfig.-Dialog anbieten. Um das zu ermöglichen müssen wir die YAML-Steuerdatei ergänzen. Damit wir das nicht im Core-Script machen müssen, legen wir uns zunächst ein Override-Script ab. 

Konkret kopieren wir die beiden Scripte owlcarousel.yaml und owlcarousel.html.twig aus dem Pfad templates/rt_topaz/particles/ in ein neu anzulegendes Custom-Verzeichnis templates/rt_topaz/custom/particles/

RANDNOTIZ: Nicht alle Particles werden in diesem Ordner bereitgestellt. Sie werden evtl. Particles modifizieren wollen, die Sie nicht in diesem Ordner finden werden. Der Grund dafür ist, dass hier lediglich die Particle liegen, die für das Template, also in unserem Beispiel topaz speziell erstellt oder angepasst wurden. Das Gantry-Engine-Framework liefert selbst aber schon diverse Particles, welche wir in diesem Ordner finden: /media/gantry5/engines/nucleus/particles/. Dazu gehört z.B. eines der wichtigen Particle Joomla-Articles, intern bezeichnet als ContentArray (also die contentarray.html.twig und contentarray.yaml).

In der templates/rt_topaz/custom/particles/owlcarousel.yaml fügen wir in ca. Zeile 58 unten dem Eintrag für den newsslider unseren neuen Type spektrum: Spektrum als Zeileneintrag ein. Damit steht dieser Type schon zur Auswahl im Dialog zur Verfügung.

Damit TWIG mit diesem Typ dann auch sauber arbeiten kann, sollte in Zeile 41 von templates/rt_topaz/custom/particles/owlcarousel.html.twig noch eine Ergänzug eingefügt werden:

{% if particle.loop == 'enabled' and particle.layout != "showcase" and particle.layout != "newsslider" and particle.layout != "spektrum" %}



 

2. Layout-Type Spektrum erstellen

Nun erstellen wir unseren eigenen Custom-Layout-Type Sprektrum. Als Vorlage nutzen wir den Newsslider-Type und modifizieren diesen. Dazu kopieren wir das Script templates/rt_topaz/particles/owlcarousel/newsslider-joomla.html.twig in den Custom-Ordner templates/rt_topaz/custom/particles/owlcarousel/ und benennen diesen um in spektrum-joomla.html.twig

Zwei Änderungen nehmen wir vor. Zunächst damit unser Layout wieder ordentlich wie beim Newsslider angezeigt wird, müssen wir die CSS-Class g-owlcarousel-layout-newsslider hinzufügen, denn diese wird standardmäßig durch das Script in g-owlcarousel-layout-spektrum geändert, womit unsere Styleanweisungen nichts anfangen können. Dazu fügen wir in Zeile 20 unserer twig-Datei folgens ein:

<div class="{{ particle.class|e }} g-owlcarousel-layout-{{ particle.layout|e }} g-owlcarousel-layout-newsslider g-owlcarousel-{{ particle.displayitems }}-items">

Nun ändern wir noch den Filter-Parameter um den es ja als Schwerpunkt in diesem Beitrag ging. Dazu ändern wir die Zeile 45 und ersetzen |e durch |raw. Raw bedeutet: Verwende den Text aus dem Beitrags-Descriptionfeld ganz ohne irgendwelche Filterung:

{% if particle.jintrotext == 'enabled' and item.introtext %}{{ item.introtext|raw }}{% endif %}

Wenn wir jetzt mit diesem Typ einen Test auf unserer Seite ausführen, werden wir feststellen, dass die Anzeige perfekt ist - das Layout stimmt und HTML wird korrekt interpretiert.

 

Wer möchte, kann nun weitere Modifikationen vornehmen ohne Angst haben zu müssen, dass seine Eingriffe die Funktion der Origininalen-Gantry Layouttypen stört oder seine Änderungen durch spätere Gantry-Updates überschrieben würden.

 

Kleine Script-Schnippsel für die Particle-Programmierung

URL-Get-Parameter (request) im Particle auswerten

Anwendungsbeispiel für nachfolgende Problemlösung:

I.d.R. ist es so, dass man ein Particle mit seinen Parametern konfiguriert und an bestimmter Position und Seite platziert. Nun hatte ich den Fall, dass für ein Brand-Location-Particle die Particle-Daten je nach Seitenaufruf (Menülink) unterschiedlich die Inhalte anzeigen sollte. Es gibt eine Seite (Menülink) die alle als Items (subcontent) im Particle eingepflegten Locations in Kurzform auf einer Seite darstellt und eine andere Anzeigevariante die bei anderen Menülinks nur eine bestimmte - durch den Menüpunkt festgelegte Location anzeigen soll. Ich wollte ersparen, dass man dazu zwei Particle für die unterschiedlichen Darstellungen programmieren müsste und auch, dass das Particel dann noch mal je zusätzlich für jede Location als Modul eingebunden werden muss. Als hatte ich mir gesagt: Wie sich das Particel verhält, sollte über den Menüpunkt gesteuert werden können: Gesamtansicht oder Einzelne Brand-Location.

Lösung 1 - per Seitenklasse:

Eine einfache Möglichkeit besteht darin im Particle vorhanden Parameter des Menü-Eintrags auszuwerten und als Weiche zu verwenden. Diese sind als Information in der Variablen gantry.page abgelegt. Was sich darin befindet kann man z.B. im TWIG-Script durch folgende Ausgabe anzeigen lassen:

 

<pre>{{ gantry.page|json_encode }}</pre>

Leider werden im Gantry nicht alle für den Menüeintrag vorhandenen Parameter durchgeschleift. Aber mir genügte schon, dass ich so Zugriff hatte auf den Klassenselector (Seitenanzeige > Seitenklasse) für den Menüpunkt gantry.page.class. Im Partikel habe ich eine Optionsfeld zur Eingabe einer Seitenklasse als Selector programmiert. So kann ich dann im Twig-Script abfrage, ob z.B. die Seitenklasse des Menüpunktes eines Selectors für ein bestimmtes Brand-Location-Item entspricht:

{% if gantry.page.class == 'filiallocation_all' or gantry.page.class == '' %}
	Wenn die Seitenklasse leer oder z.B. 'filiallocation_all' ist, dann zeige alle Brandlocation in Kurzform auf einer Seite
	....
{% endif %}

{% if gantry.page.class != 'filiallocation_all' and gantry.page.class != '' %}

	{# begin: single-item-details #}
	{% for subcontent in particle.subcontents %}
		{% if subcontent.singleselector == gantry.page.class %}
			<div class="g-block singlelocation {{ subcontent.singleselector }}">
				<div class="g-content">
				Hier steht der Particle-Subcontent-Inhalt, z.B. für nur eine(!) Brand-Location.
				</div>
			</div>
		{% endif %}
	{% endif %}

{% endif %}

 

Der Vorteil dieser Lösung ist, dass die Seitenklasse ggf. gleich für Style-Zwecke verwendet werden kann. Nachteilig ist, dass sowohl im Menüeintrag als auch im Subcontent-Element im Particle immer beide Strings gepflegt werden müssen und man die Seitenklasse hier quasi zweckentfremdet verwendet, was nicht immer mgl. oder sinnvoll ist. Aber es ist ein doch eleganter Workaround.

 

2. Lösung - über das request-Objekt in gantry:

Diese Lösung ist für mich die bessere, und angestrebte. Oben genannte Lösung hatte ich praktiziert, weil mir bis dahin die nachfolgende Lösung mit der Existenz des request-Objektes noch nicht bekannt war.

Mein Absicht war ganz einfach ein URL-GET-Argument an einem Menülink (als externen URL) oder einem Seitenlink anzufügen, über den beim Seitenaufruf das Particel wunschgemäß wie oben beschrieben reagieren kann.

Tatsächlich gibt es das Objekt request, mit welchem man Zugriff auf die GET-Argumente hat. Praktisch kann das dann z.B. so aussehen - dieses Beispiel liest die GET-Parameter gantry.request in die Variable request und gibt dann einen GET-Parameter preselection aus:

{% set request = gantry.request.request %}
{{ request['preselection']|default(particle.preselection) }}

Natürlich kann nach dem Vorbild von Lösung 1 der preselection-Parameter wie o.g. singleselector ausgewertet werden.

Es sollte nicht vergessen werden zu erwähnen: Damit das Beispiel funktioniert, muss in der YAML Datei ein Parameter mit setbyurl: true angelegt sein, nur dann wird dieser URL-Parameter durchgeschleift:

    preselection:
      type: input.text
      label: Preselection
      default: all
      description: Vorauswahl für Anzeige (alle oder Einzelanzeige), auch als url-argument. Standard ist alle.
      setbyurl: true

Eine Besonderheit oder Möglichkeit von gantry 5 zeigt das Beispiel noch. Man kann einen Standardwert vorbelegen. Dieser kann in der YAML-Datei als solcher definiert werden:

Weitere Information zu diesem Thema sind in der Gantry-Documentation zu finden.

 

Kleine Know-How-Sammlung

Das contentarray-Particle greift auf Joomla-Artikel/Beiträgr und deren Kategorien zu. Damit das möglich ist, muss Gantry in die Joomla-Plattform nutzen. Hier ein paar dafür verantwortliche Scripte:

administrator/components/com_gantry5/templates/forms/fields/joomla/categories.html.twig
Dieses Script stellt für die Particle-Dialoge (Joomla Artikel) die Kategorie-Auswahlliste zur Verfügung.

libraries/gantry5/classes/Gantry/Joomla/Content/Content.php
libraries/gantry5/classes/Gantry/Joomla/Content/ContentFinder.php
Diese Scripte greifen auf die Joomla-Artikel zu und stellen die Inhalte im Particle (frontendseitig) zur Verfügung.

libraries/gantry5/classes/Gantry/Joomla/Category/Category.php
libraries/gantry5/classes/Gantry/Joomla/Category/CategoryFinder.php
Diese Scripte greifen auf die Joomla-Artikelkategorien zu, über die dann dies Auswahl der Artikel erfolgt.

libraries/gantry5/classes/Gantry/Framework/Platform.php
In diesem Classen-Script ist integriert die finder-Methode welches für content/article/articles und category/categories finder-Objecte lädt, die o.g. Scripte nutzend.