Heute komme ich zum vorerst letzten Teil der kleinen Produktdatenbank. In diesem Artikel wird sie so angepasst, dass man pro Produkt ein Bild hinterlegen kann, dies wird dann im Frontend ausgegeben. Der Beitrag baut auf die letzten letzten Posts auf und ich werde hier nicht mehr auf die Grundlagen eingehen. Es ist daher sinnvoll erst die anderen Beiträge der Reihe zu lesen:
- Contao: Ein eigenes Inhaltselement
- Contao: Eigenen Backend-Menüpunkt
- Contao: Ausgabe für eingenen Menüpunkt
- Contao: Detailseite für eigenen Menüpunkt
DCA
Als erstes erweitern wir das DCA für die Produktdaten um die Felder für die Bilder. Zu Erinnerung, die Datei heißt system/modules/easy_extension/dca/tl_products.php
.
In Zeile 20 wird die Palette erweitert und ab Zeile 34 werden die neuen Felder definiert. Es ist unbedingt darauf zu achten, dass die Einträge an der richtigen Stelle eingefügt werden.
Es müssen für das Bild eine ganze Reihe von Felder einfügt werden. Neben dem Feld für die Bildauswahl (singleSRC
), werden noch die Felder für die alternativ Bezeichnung (alt
), den Titel (imgtitle
), die Größe (size
), den Abstand (imagemargin
), die Anzeige in einer Lightbox (fullsize
) und die Bildunterschrift (caption
) angelegt.
Leider gibt es an dieser Stelle eine kleine Abweichung vom Standard. Da wir in unserer Tabelle bereits ein Feld titel
mit dem Namen des Produkts haben, müssen wir das Feld für den Title des Bildes imgtitle
nennen. Wir müssen dies nachher in der Ausgabeklasse berücksichtigen. Ich werde später genauer darauf eingehen.
Sprachdatei
Nun geben wir die Bezeichnungen für die Felder in die Datei system/modules/easy_extension/languages/de/tl_products.php
ein.
Hier wurden einfach die Standardbezeichnungen aus dem Contao-Core verwendet.
Nun können wir im Backend die Produktbilder einpflegen.
Ausgabeklasse
Jetzt müssen wir noch die Ausgabeklasse überarbeiten. Ich beschränke mich in diesem Beispiel darauf, das Bild auf der Detailseite auszugeben. Die entsprechende Datei heißt system/modules/easy_extension/classes/elements/ContentProductDetails.php
Die Methode genFeOutput
wurde ab Zeile 54 etwas angepasst. Das Laden des Produkts wurde geändert und ein Aufruf für unsere neue Methode ergänzt (Zeile 56). Am Ende wurde dann die Methode für das Einfügen des Bildes in das Template erstellt (insertImage
). In dieser Methode wandeln wir in Zeile 80 das Objekt vom Typ \Database\Result
in ein Array um. In Zeile 82 erzeugen wir aus der Uuid des datenbankgestützten Dateisystems den Pfad zur Originaldatei.
Die Methode aus dem Contao-Core, die wir in Zeile 83 aufrufen, um das Bild ins Template einzufügen, erwartet den Titel zwingend im Feld title
. In Zeile 81 speichern wir aus diesem Grund den Inhalt des Feldes imgtitle
in das Feld title
. Da es sich bei dem Array um eine lokale Kopie der Daten handelt, hat dies keinen Einfluss auf den übrigen Programmablauf.
Template
Hier bearbeiten wir das Template für die Detailseite system/modules/easy_extension/templates/ce_product_details.html5
.
Auch hierbei handelt es sich um die normale Ausgabe aus dem Contao-Core. In Zeile 22 beginnt der Image-Container. Das eigentliche Bild wird in Zeile 24 ausgegeben. In Zeile 27 wird die Bildunterschrift ausgegeben (falls vorhanden).
Nun wird das Bild im Forntend ausgegeben und kann in einer Lightbox vergrößert werden.
Fazit
Die Bildverarbeitung gehört sicher schon zu den etwas anspruchsvolleren Themen in Contao, weshalb dieses Tutorial auch schon um einiges fordernder war, als die ersten Teile der Serie. Die nächsten Beiträge zum Thema Contao werden vermutlich wieder etwas leichter verdaulich.
Kommentare
Kommentar von Sebastian Schreier |
Hallo,
ich hätte ein paar Anmerkungen für dich.
Ich würde bei der insertImage-Funktion in der Ausgabeklasse ContentProductDetails.php noch eine if - Prüfung setzen, damit es nicht zu einer Fehlermeldung kommt, wenn kein Bild verlinkt ist, also:
if($arrData['singleSRC']){
$arrData['title'] = $arrData['imgtitle']; // nur nötig, da das Feld title bereits vorhanden ist!
$arrData['singleSRC'] = \Contao\FilesModel::findByUuid($arrData['singleSRC'])->path;
$this->addImageToTemplate($this->Template, $arrData);
}
Um die Ergänzung der Template-Datei ce_product_details.html5 würde ich noch ein <?php if ($this->picture): ?> setzen, damit der Bereich nur angezeigt wird, wenn ein Bild verlinkt wurde.
Ich hätte aber selbst noch eine Frage: wie müsste die Ausgabeklasse ContentProduct.php ergänzt werden, damit man sich das Bild auch bei der Listenansicht anzeigen lassen kann?
Beste Grüße
Antwort von Patrick Froch
Hallo Sebastian,
danke für Deine Anmerkungen. Es gibt sicher noch viele Dinge zu optimieren. Ich habe in diesen Grundlagenartikeln bewusst darauf verzichtet, da es nur darum geht die Zusammenhänge zu erläutern. Im Prinzip hast Du aber recht, im Produktivcode würde ich es auch anders machen.
Damit das Bild in der Liste angezeigt wird, benötigst Du eigentlich nur die Methode "insertImage" und die Ausgabe im Template.
Kommentar von Sebastian Schreier |
Hallo Patrick,
meine Frage bezog sich darauf, dass wenn ich die insertImage - Funktion in der Listenansicht beispielsweise so implementiere:
private function genFeOutput(){
$objProducts = $this->loadProducts();
if ($objProducts) {
$this->Template->objProducts = $objProducts;
$this->Template->jumpTo = $this->makeLink($this->jumpTo);
$this->insertImage($objProducts);
}
}
er mir in der Liste nur noch den letzten Listeneintrag anzeigt (zwar mit Bild, aber nur noch den letzten Listeneintrag). Kommentiere ich die insertImage - Funktion wieder aus, werden wieder alle Listeneinträge angezeigt. Hast du eventuell einen Tipp, was ich falsch mache?
Beste Grüße
Sebastian
Antwort von Patrick Froch
Hallo Sebastian,
okay es ist doch etwas komplizierter als ich dachte. Vielleicht mache ich mal ein extra Beitrag dazu. Du musst eine
foreach
-Schleife verwenden und das Bild für jeden Datensatz erstellen. In diesem Fall lädst Du ja alle Produkte (s. hier unter Ausgabeklasse ->loadProducts()
). InContentProductDetails->insertImage()
verwendest Du dannfetchAllAssocc()
stattfetchAssoc()
. Dann kannst Du die Datensätze durchlaufen, den Pfad zum entsprechende Bild in dem Array speichern. Du kannst dann leider nicht die MethodeaddImageToTemplate()
verwenden, da sie nur ein Bild einfügt. Du kannst aber ganz einfach die Bilder manuell im Template ausgeben.Ich hoffe diese Kurzanleitung hilft Dir schon mal etwas weiter.
Viele Grüße,
Patrick
Einen Kommentar schreiben