Das Thema Joomla-Overrides wurde schon in einem früheren Beitrag eingehend beschrieben. Mit Overrides können die Ausgaben („views“) des Joomla Cores (z.B. com_content) verändert werden. Seit Joomla 3.7 besteht die Möglichkeit, eigene Felder (Custom Fields) zu definieren und zwar nicht nur für Beiträge, sondern auch für Kategorien, Kontakte (inklusive Kontaktformular) und Benutzer. In diesem Beitrag wird die Kombination von Joomla-Overrides und Custom Fields anhand eines realen Beispiels detailliert beschrieben.
Die Kombination von Joomla-Overrides und Custom Fields
Ein Verein möchte auf der Website eine Liste der Mitglieder ansprechend darstellen. Die Liste soll alphabetisch sortiert sein und verschiedene Informationen wie „Mitgliedsform“ und „Funktion im Verein“ anzeigen. Natürlich könnten wir auf dem JED (Joomla Extensions Directory) nach eine Erweiterung suchen, die diese Funktionalität anbietet. Aber viel besser ist es, wenn wir dafür nur Joomla Core verwenden. Eigentlich hat Joomla alles was wir brauchen, um die Liste zu erstellen.
Eine Ausgabe, die selten verwendet wird ist die „Kategorieliste“, die kleine Schwester des „Kategorieblogs“. Eine Kategorieliste stellt die Beiträge einer Kategorie in tabellarischer Form dar. Die Liste ist sortierbar, hat eine Filterfunktion und eine Paginierung. Standardmäßig können unter anderem folgende Spalten angezeigt werden: Beitragstitel, Autor und Datum.
Erste Schritte
Um die Mitglieder des Vereins darstellen zu können, wird jedes Mitglied als Einzelbeitrag in der Kategorie „Mitglieder“ angelegt. Als Erstes erstellt man die Kategorie:
Inhalt -> Kategorien -> Neue Kategorie
Hier braucht man keine besondere Einstellungen.
Wie oben schon erwähnt soll die Liste nach Namen alphabetisch sortiert werden. Bei der Beitragssortierung bietet Joomla verschiedene Möglichkeiten: Beitragsreihenfolge, Neueste Beiträge zuerst, usw. Wenn man den Name des Mitglieds als Beitragstitel verwendet, würde die Sortierung Titel von A bis Z passen. Bei der Schreibweise „Vorname Nachname“ wird die Liste natürlich nach Vornamen sortiert. Wenn man aber nach Nachnamen sortieren will, muss man entweder „Nachname, Vorname“ schreiben, oder man bedient sich eines kleinen Tricks und macht aus dem Namen zwei Felder. Dafür kommt das erste Custom Field im Spiel.
Nachname = Beitragstitel
Vorname = Custom Field
Am Ende werden wir diese beide Informationen für die Darstellung zusammen führen.
Weitere benötigte Felder
Im Verein gibt es drei Mitgliedsformen: Vereinsmitglied, assoziiertes Mitglied und Ehrenmitglied. Um diese Information anzuzeigen, benötigt man ein zweites Custom Field. Außerdem erfüllen einige Mitglieder verschiedene Funktionen im Verein: Vorstand, Kassenwart, usw. Dafür wird ein drittes Custom Field angelegt.
Eine weitere Information, die auf der Liste soll, ist die Firma, in der der Mitglied beschäftigt ist. Der Name der Firma soll verlinkt sein. Hier werden wir noch zwei Custom Fields brauchen: Name der Firma und URL.
Custom Fields anlegen
Die Struktur ist jetzt klar, dann legen wir die nötigen Custom Fields an. Damit die Felder besser organisiert werden können, erstellen wir zuerst eine Feldgruppe: Inhalt -> Feldgruppen -> Neu
Die Feldgruppe bekommt einen Namen und wird gespeichert: Speichern und schließen.
Um die Felder anzulegen, geht man auf Inhalt -> Felder -> Neu
Wenn man über die Suchwerkzeuge die vorher angelegt Feldgruppe auswählt, werden die neuen Felder dieser Gruppe zugeordnet.
Für „Vorname“ braucht man ein Feld des Typs „Text“. Feldgruppe ist schon ausgewählt. In Kategorie wählt man „Mitglieder“ damit den Tab mit den Felder nur beim Anlegen von Beiträgen in der Kategorie Mitglieder angezeigt wird. So spart man sich später Missverständnisse (es würde keinen Sinn machen, die Felder „Infos“ in Beiträgen der Kategorie „Events“ ausfüllen zu wollen). Sinnvoll ist, wenn man das Feld „Vorname“ als Pflichtfeld definiert.
Unter „Optionen“ wird die automatische Anzeige ausgeschaltet, indem man „Keine automatische Anzeige“ auswählt.
Custom Fields können automatisch an verschieden Stellen eines Beitrags angezeigt werden. Zur Auswahl stehen “Nach Titel”, “Vor Inhalt” und “Nach Inhalt” . Diese „Platzhalter“ werden in den entsprechenden Views durch Plugins getriggert, z.B. in Beiträgen – com_content/views/article/tmpl/default.php – Zeile 81:
<?php echo $this->item->event->afterDisplayTitle; ?>
Hier werden die Felder eingefügt, wenn man in der Option “automatische Anzeige” “Nach Titel” gewählt hat.
Die Anzeige der Felder an bestimmten Positionen erleichtert die Arbeit sehr, aber für diesem Beispiel ist eine automatische Anzeige eher hinderlich, da die Infos in einer individuellen Anordnung angezeigt werden sollen, die mit einem Override erzielt wird.
Für „Firma“ und „Funktion im Verein“ legt man genauso zwei neue Textfelder.
Der Inhalt des Feldes „Mitgliedsform“ ist bekannt, dafür kann man ein Feld des Typs „Liste“ anlegen. In Listenwerte trägt man dann die verschiedene Mitgliedsformen ein:
Dieses Feld soll auch Pflicht sein.
Das letzte Feld ist „Link“ für die Verlinkung der Firma. Dafür legt man ein Feld des Typs „URL“ an. Damit die Links später richtig eingetragen werden, definiert man unter „Schemata“ welche URL-Typs erlaubt sind. In diesem Fall sind HTTP und HTTPS sinnvoll.
Die Liste der angelegten Felder sieht dann so aus:
Beiträge erstellen
Jetzt können wir uns an der Arbeit machen und die Mitglieder anlegen:
Inhalt -> Beiträge -> Neu
Hier gilt auch wieder: wenn man über Suchwerkzeuge die Kategorie auswählt, werden die Beiträgen dieser Kategorie zugewiesen, man spart Zeit und vermeidet damit Fehler. Es hat auch den Vorteil, dass es gleich die richtigen Custom Fields als extra Tab (in diesem Fall „Info“) angeboten werden. Die Funktion „Speichern und neu“ ist hier auch sehr praktisch, da man leichter hintereinander die Mitglieder anlegen kann.
Kategorieliste
Die ersten Mitglieder sind erstellt, jetzt wollen wir sie als Liste anzeigen. Dafür legen wir einen neuen Menüeintrag „Mitglieder“ an:
Menü -> Main Menu -> Neu
Als Menüeintragstyp wählt man Beiträge -> Kategorieliste. Kategorie ist natürlich „Mitglieder“
Jetzt müssen wir uns die weiteren Optionen für die Anzeige genauer anschauen. Je nach Konfiguration von Joomla kann es unterschiedlich aussehen. Die meisten Einstellungsmöglichkeiten, die in einem Menüeintrag angepasst werden können, sind auch in den globalen Einstellungen für Inhalte zu finden. Die Konfiguration des Menüeintrags überschreibt aber die globalen Einstellungen.
Bei dem Tab „Kategorie“ findet man alle Einstellungen der Kategorie betreffend: Ob Kategorietitel, Kategoriebeschreibung, usw. angezeigt werden soll. Die Optionen sind immer „Globale Einstellung (entsprechend was dort eingestellt ist)“, „Anzeigen“ oder „Verbergen“.
In diesem Beispiel stellt man alle Einstellungen auf „Verbergen“ bzw. „Keine“ bei Unterkategorie-Ebenen:
Um die Möglichkeiten der Kategorieliste zu demonstrieren stellen wir zunächst alle Einstellungen unter „Listenlayout“ auf „Anzeigen“, bei „Filterfeld“ wählen wir „Titel“ und bei „Datum“ „Erstellt“:
Im unteren Teil von „Listenlayout“ sind weitere Einstellungen, die man wie folgt wählt:
Den Tab „Optionen“ werden wir später behandeln.
Jetzt kann man sich die Liste im Frontend anschauen:
Nicht schlecht, aber es enthält einige Spalten, die wir in dem Fall nicht brauchen und die Infos aus den Custom Fields sind nirgendwo zu sehen.
Wir gehen zurück zu den Einstellungen des Menüeintrags und verbergen Filterfeld, Datum, Seitenaufrufe, Autor, Stimmen und Bewertungen.
Das Ergebnis ist nicht besonders schön:
Override erstellen
Jetzt ist es an der Zeit, dass wir uns mit dem Override der Kategorieliste beschäftigen, um unsere Custom Fields anzeigen zu können. Bevor wir anfangen schauen wir uns noch mal die Liste der Custom Fields an und merken uns die ID von jedem Feld. Die werden wir gleich im Override benötigen.
Um den Override anzulegen gehen wir auf
Erweiterungen -> Templates -> Templates
und klicken auf den Namen unseres Standard Templates (in diesem Beispiel ist es Protostar).
Wir wählen den Tab „Overrides erstellen“ und suchen unter Komponenten -> com_content -> category
Joomla wird Overrides für Kategorieblog und Kategorieliste anlegen,diese beiden Views sind unter „category“ zu finden. Wenn wir jetzt zum Tab „Editor“ gehen, können wir unter html -> com_content -> category alle Files sehen, die angelegt wurden. Wir ignorieren erst mal die Blog Files, uns interessieren die Files mit Name „default“.
Die Datei „default.php“ beinhaltet nicht viel und braucht nicht verändert zu werden. Die eigentliche Inhalte für die Kategorieliste befinden sich in der Datei „default_articles.php“
Der Code verunsichert auf dem ersten Blick, weil er sehr verschachtelt ist und jede Menge „if-Anweisungen“ beinhaltet. Um so sorgfältiger müssen wir mit unseren Änderungen agieren. Ab Zeile 91 wird die Tabelle gebaut. Wir müssen hier weitere Inhalte zusammenführen und brauchen neue Spalten für die Custom Fields. Momentan wird in der ersten Spalte der Tabelle nur der Nachname der Mitglieder angezeigt, weil wir ihn als Beitragstitel angelegt haben. Sinnvollerweise müssen wir nun den Vorname, den wir als Custom Field erstellt haben, vor dem Nachname stellen:
Tabellen-Header:
<th scope="col" id="categorylist_header_title">
<?php echo JHtml::_('grid.sort', 'JGLOBAL_TITLE', 'a.title', $listDirn, $listOrder, null, 'asc', '', 'adminForm'); ?>
</th>
Tabellen-Body:
<td headers="categorylist_header_title" class="list-title">
<?php if (in_array($article->access, $this->user->getAuthorisedViewLevels())) : ?>
<a href="<?php echo JRoute::_(ContentHelperRoute::getArticleRoute($article->slug, $article->catid, $article->language)); ?>">
<?php echo $this->escape($article->title); ?>
</a>
.....
Der Code hier ist ziemlich lang, weil viele Möglichkeiten beinhaltet: Wird der Titel verlinkt oder nicht, ist der Beitrag veröffentlicht, hat der Besucher Zugang zum Beitrag, usw.
Für uns wichtig sind die zwei Stellen wo der Beitragstitel ausgegeben wird und zwar mit:
<?php echo $this->escape($article->title); ?>
In meinem System hat das Feld „Vorname“ die ID 10. Das kann in jedem System anders sein. Ersetzen Sie die ID des Feldes (eckige Klammern), die Sie sich vorher notiert haben.
<?php echo $article->jcfields[10]->value; ?>
Die Zeilen sollen jetzt so aussehen:
<?php echo $article->jcfields[10]->value .' '.$this->escape($article->title); ?>
und weiter unten:
<?php echo $article->jcfields[10]->value .' '.$this->escape($article->title) . ' : ';
$menu = JFactory::getApplication()->getMenu();
$active = $menu->getActive();
$itemId = $active->id;
$link = new JUri(JRoute::_('index.php?option=com_users&view=login&Itemid=' . $itemId, false));
$link->setVar('return', base64_encode(ContentHelperRoute::getArticleRoute($article->slug, $article->catid, $article->language)));
?>
Wir speichern die Änderung und rufen die Kategorieliste auf. Wenn wir alles richtig gemacht haben, soll jetzt der Vorname zu sehen sein:
Das ging einfach. Für die anderen Custom Fields müssen wir zuerst neue Spalten in der Tabelle ergänzen.
Fangen wir mit „Firma“ an. Wir suchen die Stelle im Code wo die Headers der Tabelle definiert werden und nach dem Beitragstitel fügen wir eine neue Spalte ein:
<th scope="col" id="categorylist_header_firma">
<?php echo $article->jcfields[11]->label; ?>
</th>
Damit wird der Titel (label) des Feldes ausgegeben. Dann weiter unten im Body der Tabelle fügen wir auch die Spalte ein und zwar auch nach der Beitragstitel-Spalte. Wir erinnern uns, dass die Firma verlinkt sein soll. Das heißt, wir müssen hier zwei Felder zusammenführen: Firma und Link:
<td headers="categorylist_header_firma">
<?php if (!empty($article->jcfields[14]->rawvalue)) : ?>
<a href="<?php echo $article->jcfields[14]->rawvalue; ?>" target="_blank" rel="nofollow noopener noreferrer"><?php echo $article->jcfields[11]->value; ?></a>
<?php else : ?>
<?php echo $article->jcfields[11]->value; ?>
<?php endif; ?>
</td>
Mit dem Code schauen wir zuerst, ob das Feld „Link“ ein Wert hat. Wenn ja, bauen wir uns einen Link mit dem Wert des Feldes in „href“ und der Wert des Feldes „Firma“ als Text, der angezeigt wird. Wenn „Link“ leer ist, soll nur der Name der Firma angezeigt werden.
Wie Sie sicher bemerkt haben, geben wir oben zwei unterschiedliche Feld-Werte aus: value und rawvalue. Im Fall vom Feld des Typs „URL“ ist es so, dass „value“ eine komplett gebaute URL Struktur ausgeliefert wird. Hier würde es so aussehen:
<a href="https://www.dr-menzel-it.de" target="_blank" rel="nofollow noopener noreferrer">https://www.dr-menzel-it.de</a>
Das heißt, der Wert, den wir im Feld eingeben, wird als href und als Text ausgegeben. In unserem Beispiel wollen wir aber der Name der Firma als Text des Links, deswegen bedienen wir uns des „rawvalues“ des Feldes: https://www.dr-menzel-it.de und bauen uns den Link selber.
Unsere Tabelle sieht jetzt so aus:
Von Herrn Jardin haben wir keine URL erhalten, deswegen ist bei ihm die Firma nicht verlinkt.
Die weiteren Spalten für Custom Fields bauen wir genauso ein:
<th scope="col" id="categorylist_header_form">
<?php echo JHtml::_('grid.sort', $article->jcfields[13]->label, 'a.title', $listDirn, $listOrder, null, 'asc', '', 'adminForm'); ?>
</th>
Mit diesem Code erreichen wir, dass die Spalte sortierbar ist (so wie die Spalte Beitragstitel).
Weiter unten noch:
<td headers="categorylist_header_funktion">
<?php echo $article->jcfields[12]->value; ?>
</td>
<td headers="categorylist_header_form">
<?php echo $article->jcfields[13]->value; ?>
</td>
Ein Blick auf unserem Tabelle verrät uns, dass wir alle Infos der Custom Fields jetzt angezeigt werden:
Beitrag Ansicht
Oben habe ich erwähnt, dass wir den Tab „Optionen“ der Kategorieliste erst mal ignorieren. Jetzt fällt auf, dass der Beitragstitel verlinkt ist. Ein Klick auf den Namen des Mitglieds führt uns zum Einzelbeitrag, der momentan nicht so toll aussieht:
Wir haben jetzt zwei Möglichkeiten: entweder entfernen wir den Link oder wir erstellen einen Override vom Beitrag und bauen uns eine schöne Profil-Seite.
Seit Joomla 3.8 ist es möglich, bei Kategorieblog und Kategorieliste ein alternatives Layout für die Anzeige der einzelnen Beiträge anzugeben:
Der Vorteil von alternativen Layouts liegt darin, dass sie nicht global gelten sondern nur dann, wenn man sie auswählt.
Also legen wir ein Override von com_component/article an und benennen die Datei (default.php) um zu mitglied.php. Nach dem Speichern wird dieses Layout in der Liste angezeigt:
Wir wählen das alternative Layout und verbergen alle Optionen, die nicht gebraucht werden, wie Kategorie, Autor, Datum, usw.
Um Custom Fields im Beitrag-View auszugeben, braucht man folgenden Code:
<?php echo $this->item->jcfields[10]->value; ?>
Als erstes ergänzen wir den Vornamen zu dem Nachnamen (Beitragstitel) des Mitglieds:
<?php if ($params->get('show_title')) : ?>
<h2 itemprop="name">
<?php echo $this->item->jcfields[10]->value .' '.$this->escape($this->item->title); ?>
</h2>
<?php endif; ?>
Jetzt möchten wir ein wenig Text bei jedem Mitglied schreiben und auch ein Profilfoto anzeigen. Dafür legen wir ein Custom Field des Typs „Media“ an und ergänzen die Information bei den Mitgliedern.
Wieder im Override / alternativen Layout ändern wir die Darstellung und fügen die weiteren Felder ein. Dafür suchen wir diese Stelle im Code:
<div itemprop="articleBody">
<?php echo $this->item->text; ?>
</div>
und ändern es in:
<div class="row-fluid" itemprop="articleBody">
<div class="span8">
<?php echo $this->item->text; ?>
</div>
<div class="span4 well">
<?php echo $this->item->jcfields[15]->value; ?>
<?php if (!empty($this->item->jcfields[12]->value)) : ?>
<p><?php echo $this->item->jcfields[12]->value; ?></p>
<?php endif; ?>
<?php if (!empty($this->item->jcfields[13]->value)) : ?>
<p><?php echo $this->item->jcfields[13]->value; ?></p>
<?php endif; ?>
<?php if (!empty($this->item->jcfields[14]->rawvalue)) : ?>
<p><?php echo $this->item->jcfields[11]->label; ?>: <a href="<?php echo $this->item->jcfields[14]->rawvalue; ?>" target="_blank" rel="nofollow noopener noreferrer"><?php echo $this->item->jcfields[11]->value; ?></a></p>
<?php else : ?>
<p><?php echo $this->item->jcfields[11]->label. ': ' .$this->item->jcfields[11]->value; ?></p>
<?php endif; ?>
</div>
</div>
Der Code
<?php echo $this->item->jcfields[15]->value; ?>
der für das Feld „Foto“ zuständig ist, liefert automatisch den fertigen HTML für ein Image aus:
<img src="/cms-overrides/images/sampledata/parks/animals/180px_koala_ag1.jpg">
Wie beim URL würde „rawvalue“ nur den reinen Inhalt des Feldes ausgeben: „/cms-overrides/images/sampledata/parks/animals/180px_koala_ag1.jpg“
Da wir mit Protostar arbeiten, nutzen wir CSS Klassen von Bootstrap 2.
Die Profil-Seite des Mitglieds sieht jetzt so aus:
Sie haben sicher bemerkt, dass das Foto einen Rahmen hat. Das ist mit Bootstrap 2 einfach zu erzielen, in dem man dem Bild die Klasse „img-polaroid“ zuweist. Mit Custom Fields kann man ganz einfach jedem Feld eine Klasse geben:
Ausblick
Tabellen sind in Zeiten von „responsive Design“ ein bisschen verpönt, aber es gibt nun mal Inhalte, die tabellarisch angezeigt werden müssen. Dazu zählt die Liste von Mitglieder eines Vereins. Außerdem gibt es Möglichkeiten, eine Tabelle „responsive“ zu machen.
Die Kategorieliste bietet eine wunderbare Möglichkeit, Mitglieder einfach darzustellen und vor allem zu pflegen. Wenn ein Mitglied dazu kommt, erstellt man einen neuen Beitrag in der Kategorie „Mitglieder“ und er wird automatisch in der Tabelle richtig einsortiert. Wenn ein Mitglied ausscheidet, löscht man den Beitrag oder ändert seinen Status auf „versteckt“ und schon wird er nicht mehr in der Tabelle angezeigt.
Mit Custom Fields sind für weitere Informationen zum Mitglied fast keine Grenzen gesetzt: Man könnte z.B. noch ein Feld „E-Mail Adresse“ oder „Geburtsdatum“, usw. ergänzen.
Mit Hilfe von alternativen Layouts kann man die Darstellung der einzelnen Beiträgen beeinflussen und so perfekte Profil-Seiten erstellen.
Es wird immer wieder betont, dass Custom Fields kein CCK (Content Construction Kit) sind, aber es kommt dem sehr nah. Auf jedem Fall erweitern Custom Fields die Möglichkeiten der Inhalt-Darstellung in Joomla enorm.
Custom Fields sind suchbar, es gibt aber noch keine Möglichkeit im Joomla Core ein Filtersystem zu bauen. Es gibt aber schon einige Erweiterungen, die diese Funktionalität anbieten (z.B. JA Megafilter, EasyLayouts oder Articles Good Search). Damit kann man wunderbar z.B. ein Produktkatalog oder ein Firmenverzeichnis bauen, ohne große Komponente nutzen zu müssen.
Viel Spaß beim Nachbauen!
- Responsive Bilder in Joomla – Was kann man machen? - 12. Mai 2020
- Custom Fields für Fortgeschrittene: Parameter und alternative Layouts für Custom Fields - 3. April 2020
- Joomla! – Muss immer eine Joomla-Erweiterung sein? - 12. Februar 2019