Hier in unserem Blog verwenden wir gerne Custom Fields. Auch für die Generierung der Bildnachweise, denn wir haben jeden Artikel mit einem Bild versehen - und da wir diese Bilder kaufen, sind Bildnachweise ein Muss.
Der erste Schritt war natürlich, jedem Artikel ein Textfeld für den Bildnachweis beizugeben und dieses dann am Ende des Artikels zu zeigen. Aber ich wollte lieber die Bildnachweise gesammelt auf der Impressum-Seite haben, nicht beim Artikel selbst. Dafür bietet sich ein Modul an.
Was soll das Modul machen? Es soll für alle freigegebenen und veröffentlichten Artikel aus bestimmten Kategorien den Inhalt des Feldes zeigen, in dem der Bildnachweis steht, zusammen mit dem Artikelnamen. Hier ist das Ergebnis am Ende der Seite zu bewundern.
Ein Modul für Bildnachweise
Dies wird kein Tutorial über die Modulprogrammierung, dafür gibt es viele Dokumentationen und Anleitungen, hier geht es um die Datenbankzugriffe auf die Felder und Artikel. Aber für weniger erfahrene Programmierer sei doch kurz die Struktur erklärt. Ein einfaches Modul benötigt:
- eine Manifest-Datei. Sie enthält die Dateistruktur und definiert die Parameter des Moduls.
- Sprachdateien, zumindest englisch
- Das Modul selbst, das in unserem Fall noch eine Helper-Klasse verwendet. Hier im Helper findet der Datenbankzugriff statt. Das Ergebnis ist ein Array mit den gefundenen Bildnachweisen
- Das Layout für die Gestaltung der Ausgabe. Hier wird das Ergebnis des Datenbankzugriffs formatiert und der HTML-code erzeugt.
Parameter werden im Manifestfile definiert
Wir benötigen zwei Parameter: Erstens muss das Modul wissen, in welchem Feld der Bildnachweis steht. Dazu verwende ich ein einfaches SQL JFormField: Es baut eine Auswahl aller Textfelder zum Content auf.
<field name="imgref" type="sql" label="MOD_WICKEDIMAGEREFERENCE_FIELD_LABEL" description="MOD_WICKEDIMAGEREFERENCE_FIELD_DESC" query="SELECT id, title FROM #__fields where context = 'com_content.article' AND type = 'text'" key_field="id" value_field="title" required="true" />
Mit dem zweiten Parameter wird festgelegt, welche Beitragskategorien relevant sind. Alle, eine oder mehrere? Dafür gibt es das JFormField category:
<field name="catid" type="category" extension="com_content" multiple="true" default="*" label="MOD_WICKEDIMAGEREFERENCE_CATEGORY_LABEL" description="MOD_WICKEDIMAGEREFERENCE_CATEGORY_DESC" > <option value="*">MOD_WICKEDIMAGEREFERENCE_ALL</option> <field>
Der Datenbankzugriff (Helper)
Wir haben zwei Parameter: Die gewünschten Kategorien (catid) und die ID des Feldes, das den Bildnachweis enthält (imgref). Und nun geht es direkt auf die Datenbank.
Zur Erinnerung: Wir wollen
- nur das Custom field, das den Bildnachweis enthält
- nur veröffentlichte Artikel, die jetzt bereits veröffentlicht sind
- nur die Artikel bestimmter Kategorien
<?php defined('_JEXEC') or die; use Joomla\CMS\Factory; /** * Helper for mod_wickedimagereference */ abstract class ModWickedImagereferenceHelper { /** * Get a list of imagenames from fields and titles from article * * @param \Joomla\Registry\Registry &$params object holding the models parameters * * @return array */ public static function getList(&$params) { // Datenbank und Query Object $db = Factory::getDbo(); $query = $db->getQuery(true); // Datum für Datumsvergleiche $nullDate = $db->quote($db->getNullDate()); $date = Factory::getDate(); $nowDate = $db->quote($date->toSql()); // Wir wollen den Wert des Custom Field und den Titel des Artikels $query ->select( [ $query->qn('fv.value', 'image'), $query->qn('a.title', 'article') ]) // Das Custom Field, das die Bildnachweise enthält ->from($query->qn('#__fields_values', 'fv')) ->where($query->qn('fv.field_id') . '=' . (int) $params->get('imgref', '0')) // Artikel die jetzt veröffentlich sind ->where('(' . $query->qn('a.publish_up') . ' = ' . $nullDate . ' OR ' . $query->qn('a.publish_up') . '<=' . $nowDate . ')') ->where('(' . $query->qn('a.publish_down') . ' = ' . $nullDate . ' OR' . $query->qn('a.publish_down') . '>= ' . $nowDate . ')') ->where($query->qn('a.state') . ' = 1'); // Artikel, die in der gewählten Kategorie enthalten sind $categoryId = $params->get('catid', array()); if (is_array($categoryId) && (count($categoryId) > 0) && !in_array('*', $categoryId)) { $categoryId = implode(',', $categoryId); $query->where($query->qn('a.catid') . ' IN (' . $categoryId . ')'); } // Verknüpfung von Custom Fields mit Artikeln $query ->innerjoin( $query->qn('#__content', 'a') . ' ON (' . $query->qn('a.id') . ' = ' . $query->qn('fv.item_id') . ')' ) // Absteigend nach Aktualisierungsdatum des Artikels ->order($query->qn('a.modified' ) . ' DESC'); // Ergebnis holen return $db->setQuery($query)->loadObjectList(); } }
Das Ergebnis ist ein Array mit Bildnachweis und Artikel-Titel. Die Ausgabe ist denkbar einfach und wird, wie gewohnt, in der Datei tmpl/default.php erzeugt.
<?php defined('_JEXEC') or die; ?> <div class="wickedimagereference<?php echo $moduleclass_sfx; ?>"> <?php if (!empty($items)): ?> <p class="small"> <?php foreach ($items as $item) : ?> <?php if (!empty($item->image)): ?> <?php echo htmlspecialchars($item->image) . ' (' . htmlspecialchars($item->article) . ')'; ?><br> <?php endif; ?> <?php endforeach; ?> </p> <?php endif; ?> </div>
Fertig. Viel Spaß!