Artikel
von
© Copyright bei Patrick Froch und easy Solutions IT. Dieses Werk ist lizenziert unter Creative Commons BY-NC-SA.

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:

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.

Da wir neue Felder angelegt haben, müssen wir nun die Datenbank aktualisieren!

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.

Backend

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.

Das Umspeichern des Titels ist nur nötig, weil wir im DCA bereits ein Feld mit diesem Namen hatten. Wir hätten ebenso gut das Feld "title" in "name" (o.ä.) umbenennen können.

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.

Backend

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.

Zurück

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()). In ContentProductDetails->insertImage() verwendest Du dann fetchAllAssocc() statt fetchAssoc(). Dann kannst Du die Datensätze durchlaufen, den Pfad zum entsprechende Bild in dem Array speichern. Du kannst dann leider nicht die Methode addImageToTemplate() 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

Bitte rechnen Sie 2 plus 1.