Schnipsel: Beiträge-Accordion mit Joomla-4-Hausmitteln (z.B. FAQ)
Einige Accordion-Module, die Beiträge anzeigen, haben sich mit dem Erscheinen von Joomla 4 "ausgelebt". Sie verwenden veralteten PHP-Code, Mootools, unnötigerweise JQuery... Wegen einer Anfrage so eine schon mehrfach wiederbelebte Leiche für Joomla 4 zu überarbeiten, habe ich am Ende nur einen Override für das joomla-eigene Modul "Beiträge - Kategorie" gebraucht, um den Einsatzzweck "nachzubauen".
Was ich machen sollte
- Es liegen mehrere Beiträge in einer Beitrags-Kategorie.
- Alle Beiträge dieser Kategorie sind inhaltlich sehr kurz und bestehen nur aus dem Introtext (Anmerkung: Introtext ist in Joomla der gesamte Beitragstext so lange kein Weiterlesen-Marker in den Editor eingesetzt wird; ansonsten alles vor dem Marker).
- Sie sollen alle untereinander in Form eines Accordions angezeigt werden. Bei Klick auf den Titel klappt der Beitrags-Text aus. So in der Art wie die oft zu sehenden Fragen-und-Anworten-Accordions (FAQs).
- Weiterlesen-Knöpfe sind nicht nötig. Bilder nicht und sonstiger Kram auch nicht; außer natürlich Bilder, die sich direkt im Beitragstext befinden.
- Wenn möglich, dann mit purem Joomla ("Hausmittel"), um die alte Erweiterung "in die Tonne klopfen" zu können, über die schon mehrere schlaue Köpfe über die letzten zwei Joomla-Versionssprünge rauchten. Am Ende war's nur noch ein Kuddelmuddel aus in der Not um die Ecke gedachten Code-Veränderungen und funktionslosen Einstellungen.
Das war's, außer, dass die unten vorgestellte Grundidee für mich ausbaufähig sein soll. Wenn dann doch irgendwann mal Weiterlesen-Buttons oder Bilder oder sonstiger Kram nötig werden sollten.
Was ich gemacht habe
- Das alte Modul gedreht und gewendet bis ich glücklicherweise entdeckte, dass das darin verwendete JavaScript die Mootools-Bibliothek benötigt, die es in Joomla 4 gar nicht mehr gibt. Juhuu! Mit gutem Gewissen "in die Tonne"...
- Noch unsicher das joomla-eigene Universal-Genie für Beiträge-Anzeige, das Modul "Beiträge - Kategorie" (
mod_articles_category
) gesichtet. - Dann nach bisschen Rumprobieren und Überlegen, ob man das der "Kundin" und mir antun kann, weil es seuchenhaft viele Einstellungen hat, festgestellt, dass man die alle bis auf drei oder vier, die selbst mich nicht überfordern, gar nicht braucht für unsere Umsetzung. Alle anderen kann man belassen wie sie sind, aber teils auch nutzen, wenn man möchte.
- Mir die Bootstrap-5-Doku angesehen, was das so kann bzgl. Accordion. Reines HTML ist möglich ohne verquaste, restriktive Joomla-Accordion-Methoden verwenden zu müssen, die mich nur wieder Zeit kosten bis ich sie verstehe und richtig platziere. Und Bootstrap 5 liegt Joomla 4 bei. Und benötigt kein JQuery mehr. Und das verwendete Cassiopeia-Template hat auch alles nötige CSS dabei (könnte man aber auch nachladen, falls nötig).
- Und eigene Module-Layouts mit beliebigen, eigenen Code-Ideen darin kann auch Joomla 4 noch ;-). Nahezu egal, welches Modul man verwendet. Aber natürlich sollte das hier gezielt ausgewählte Modul "Beiträge - Kategorie" mir die Arbeit abnehmen, je nach Einstellungen, alle Artikel erst mal zusammen zu sammeln und mir in meinen Code weiter zu reichen.
Schritt 1 - Override-Datei anlegen (eigenes Module-Layout)
Dateien und/oder Ordner neu anlegen und/oder bearbeiten und/oder Overrides per Klick erzeugen (von mir nicht empfohlen) kann man auch im Joomla-Backend im Template-Editor. J!3: Menü Erweiterungen > Templates > Templates. J!4: Menü System > Blöd rumsuchen > Site Templates. In beiden danach auf den verlinkten Templatetitel klicken. Im Template-Editor kann man jedoch nur auf Dateien und Verzeichnisse innerhalb des jeweiligen Template-Ordners und ggf. dem zugehörigen /media/-Ordner (Joomla 4) zugreifen! Nicht alle Dateitypen werden angezeigt.
Die Ordnerangabe /DEINTEMPLATE/
meint den Ordner, in dem das zu bearbeitende Template liegt. Jedes hat ja einen eigenen Namen und Ordner.
Am Beispiel eines Frontend-Templates namens "bs4ghsvs":
/templates/bs4ghsvs/
Lege im Ordner /templates/DEINTEMPLATE/html/mod_articles_category
eine neue Datei namens accordionGhsvs.php
an. Falls der Ordner noch nicht existiert, lege ihn zuvor an.
Schritt 2 - Den PHP-Code in Datei einfügen
Die neue, noch leere Datei accordionGhsvs.php
öffnest du zur Bearbeitung.
Kopiere den folgenden Code hinein und speichere die Datei bzw. kopiere sie via FTP in die Seite hoch; je nachdem welche Arbeitsweise du bevorzugst.
<?php
\defined('_JEXEC') or die;
use Joomla\CMS\Factory;
if (!$list)
{
return;
}
Factory::getApplication()
->getDocument()
->getWebAssetManager()
->useScript('bootstrap.collapse');
$id = 'accordionGhsvs-' . $module->id;
?>
<div class="accordion" id="<?php echo $id; ?>">
<?php
foreach ($list as $key => $item)
{
$itemId = $id . '-' . $key;
?>
<div class="accordion-item">
<h2 class="accordion-header" id="<?php echo $itemId; ?>Header">
<button class="accordion-button" type="button" data-bs-toggle="collapse"
data-bs-target="#<?php echo $itemId; ?>" aria-expanded="false"
aria-controls="<?php echo $itemId; ?>">
<?php echo $item->title; ?>
</button>
</h2>
<div id="<?php echo $itemId; ?>" class="accordion-collapse collapse"
aria-labelledby="<?php echo $itemId; ?>Header"
data-bs-parent="#<?php echo $id; ?>">
<div class="accordion-body">
<?php echo $item->introtext; ?>
</div>
</div><!--/accordion-collapse-->
</div><!--/accordion-item-->
<?php
} ?>
</div><!--/accordion -->
Musste nicht lesen - wenn's dich eh nicht interessiert
Nach joomla-typischem Vorgeplänkel wird in Zeilen 11 bis 14 das notwendige JavaScript vom Joomla-Web-Asset-Manager (WAM) geladen. Dieses JS bringt Joomla 4 mit. Dass wir da was mit collapse
laden und nicht was mit accordion
ist schon richtig so. Das Bootsrap-Accordion nutzt die Bootstrap-Collapse
-Komponente (nicht zu verwechseln mit einer Joomla-Komponente).
Das Accordion nutzt etwas abweichende, eigene CSS-Klassen, die sich auch im Code-Block oben finden (accordion
, accordion-collapse
, accordion-item
, accordion-header
, accordion-body
, accordion-button
). Ein paar benötigt man für die Funktionalität des Accordions. Andere kümmern sich um das Aussehen. Da ich eine faule Sau bin, nehm ich sie erst mal gerne mit wie sie sind.
Der öffnende <DIV>
-Container mit Klasse accordion
in Zeile 18 ist obligatorisch. Das gesamte Accordion wird von ihm umschlossen.
In Zeile 20 lassen wir das PHP alle Beiträge, die das Modul für uns gesammelt hat, einzeln durchlaufen und erstellen für jeden ein HTML-Gerüst, das jeweils von einem <DIV>
mit CSS-Klasse accordion-item
umschlossen wird.
In Zeile 29 wird im späteren Öffnen/Schließen-Button der Beitragstitel eingesetzt und in Zeile 36 der vorerst versteckte Introtext des Beitrags.
Entfernt man den Teil data-bs-parent="#<?php echo $id; ?>"
aus Zeile 34, kann man später mehrere Accordion-Elemente gleichzeitig öffnen.
Ob man den Titel nun in einem <H2>
-Tag ausgibt oder besser einem anderen oder gar keinen, war mir erst mal wurst. Weil nämlich: Joomla-Template-Overrides bzw. eigene Modul-Layouts sind dafür da, dass man sie nach Gusto anpasst, verkürzt, entrümpelt. Nur den Mut muss man halt aufbringen.
Schritt 3 - Modul "Artikel - Beiträge" anlegen
Wie man es eben macht in Joomla. Im Backend in den Modulemanager gehen und auf Neu klicken.
Modulkonfiguration für unsere einfachen Zwecke
Es werden in der Tabelle unten nur die Einstellungen angegeben, die relevant sind. Andere sollte man für erste Versuche auf Voreinstellungen belassen. Später kann man ja nach Belieben rumspielen und -testen.
Die meisten Filter-Einstellungen sollten problemlos funktionieren. “Gliederung” ist immer verboten!. “Modus” habe ich nie getestet!
Einstellung | Wert |
---|---|
Titel | Beliebig. |
Tabulator Filter > Kategorie | Die Kategorie wählen, die die Beiträge enthält. |
Tabulator Filter > Anzahl | Wenn die Kategorie übertrieben viele Beiträge enthält, wohl besser erst mal einen überschaubaren Wert einsetzen. |
Tabulator Reihenfolge | Beliebig. |
Tabulator Gliederung | "KEINE" (!!!!!) |
Tabulator Anzeige | “VERBERGEN” für ALLE (wird im Override bisher eh nichts von verwendet). |
Tabulator Erweitert > Layout | "accordionGhsvs" (= das zuvor angelegte eigene Modul-Layout). |
Tabulator Modul > Position | Beliebig für erste Tests. Später kann man nat. auch leer lassen, wenn der Module-Button im Beitragseditor verwendet werden soll und/oder was Joomla halt an Möglichkeiten bietet, um hier oder da Module anzuzeigen. |
Tabulator > Menüzuweisung | Beliebig. Halt mindestens die Seite auf der das Modul angezeigt werden soll. |
Schritt 4 - Modul anzeigen, anschauen, rumspielen
Ich verwende zwar derzeit noch Joomla 3, aber mein eigenes Template verwendet auch schon lange Bootstrap 5 und mit einer kleinen Änderung im Code oben, präsentiere ich mit größter Erregung und wenig Stolz mein Accordion hier drunter.
Aber, keine Angst! Don't panic!
Dass das bei mir optisch bisschen "Kacka" aussieht, Icons fehlen und Kram, liegt einfach an meinem CSS, das die speziellen Accordionhübscher-Klassen von Bootstrap 5 nicht drinnen hat ;-) Die brauche ich sonst nirgends und bin zu faul, die extra für diesen Beitrag reinzudingsen... Hauptsache es tut klappen.
Am besten kompiliert man SCSS mithilfe von Konsole-Tools wie npm. Ich habe diese Möglichkeit beim Programmieren ohne bremsenden Aufwand nicht. Ich nutze bei(!) der Arbeit von Webseiten einen PHP-SCSS-Compiler, basierend auf scssphp/scssphp, der mir das CSS on-the-fly erstell. Crux: Die Vendor-Prefix-Mixins wurden in BS4 entfernt. Der PHP-Compiler kann die Browser-Prefixe also auch nicht einbauen.
In Betriebssystemen (OS), z.B. Windows, kann man ein Farbschema einstellen; "dark" (dunkel) oder "light" (hell), neben anderen, die hier aber nicht gemeint sind. Man spricht auch von "Dark-Mode" und "Light-Mode".
Es gibt ein CSS-MediaQuery, z.B. @media (prefers-color-scheme: dark) {...}
, eine Weiche, mit der der ein guter Browser ermitteln kann, welches Schema der Besucher in seinem OS eingestellt hat.
Variante "Wie könnte ich das erste Item standardmäßig anzeigen, also bei Seitenladen ausklappen?"
<?php
\defined('_JEXEC') or die;
use Joomla\CMS\Factory;
if (!$list)
{
return;
}
Factory::getApplication()
->getDocument()
->getWebAssetManager()
->useScript('bootstrap.collapse');
$id = 'accordionGhsvs-' . $module->id;
$expandFirst = true;
?>
<div class="accordion" id="<?php echo $id; ?>">
<?php
foreach ($list as $key => $item)
{
$ariaExpanded = 'false';
$show = '';
if ($key == 0 && $expandFirst === true)
{
$ariaExpanded = 'true';
$show = ' show';
}
$itemId = $id . '-' . $key;
?>
<div class="accordion-item mb-1">
<p class="accordion-header h6 mb-0" id="<?php echo $itemId; ?>Header">
<button class="accordion-button text-start w-100 btn-warning" type="button" data-bs-toggle="collapse"
data-bs-target="#<?php echo $itemId; ?>" aria-expanded="<?php echo $ariaExpanded; ?>"
aria-controls="<?php echo $itemId; ?>">
<?php echo $item->title; ?>
</button>
</p>
<div id="<?php echo $itemId; ?>" class="accordion-collapse collapse<?php echo $show; ?>"
aria-labelledby="<?php echo $itemId; ?>Header"
data-bs-parent="#<?php echo $id; ?>">
<div class="accordion-body">
<?php echo $item->introtext; ?>
</div>
</div><!--/accordion-collapse-->
</div><!--/accordion-item-->
<?php
} ?>
</div><!--/accordion -->
In Zeile 17 habe ich einen Schalter $expandFirst
hinzugefügt, der entweder true
oder false
sein kann. Wenn er false
ist, ist das Ergebnis das selbe wie beim oberen Override; alle Items sind erst mal zugeklappt.
Setze ich $expandFirst
aber auf true
, wird das erste Item beim Laden der Seite ausgeklappt. In den Zeilen 26 bis 30 wird dafür das Attribut aria-expanded
"umgedreht" und eine CSS-Klasse show
vorbereitet, die weiter unten in Zeile 42 hinzugefügt wird.