Contao: Ausgabe für eingenen Menüpunkt

von Patrick Froch (Kommentare: 0)

Nach dem im letzten Artikel eine kleine Produktdatenbank aufgebaut wurde, wird es nun Zeit, die Daten auch im Frontend anzuzeigen. In diesem Artikel soll deshalb ein Inhaltselement für die Anzeige der Produkte erstellt werden. Im Prinzip funktioniert es genau so, wie im Artikel "Contao: Ein eigenes Inhaltselement" beschreiben. Der einzige Unterschied ist, dass die Daten nun nicht mehr direkt aus dem Inhaltselement kommen, sondern aus der Produktdatenbank geladen werden müssen.

Ordnerstruktur

Da wir die Produktdatenbank aus dem letzten Artikel erweitern beginnen wir auch mit der gleichen Dateistruktur. (Die Dateien aus dem letzten Artikel werden natürlich weiterhin benötigt!)

easy_extension/
├── assets/
│   └── img/
├── classes/
│   └── elements/
├── config/
├── dca/
├── languages/
│   └── de/
└── templates/

Wir erweitern die vorhandenen Ordner um die Verzeichnisse classes und templates.

Config

Damit unsere Inhaltselement in Contao zur Verfügung steht, ergänzen wir die Datei config/config.php.

// config/config.php
$GLOBALS['TL_CTE']['esit']['myproduct'] = '\\esit\\easy_extension\\classes\\elements\\ContentProduct';

DCA

Im Artikel "Contao: Ein eigenes Inhaltselement" wurde das DCA der Tabelle tl_content um die Felder für die Produktdaten erweitert. Da diese Daten jetzt in einer eigenen Tabelle gepflegt werden, sind diesmal keine Änderungen am DCA nötig. Damit aber wenigstens die Standard-Contao-Felder angezeigt werden, erstellen wir trotzdem eins. Wir legen die Datei dca/tl_content.php mit folgendem Inhalt an:

// dca/tl_content.php
/**
 * Set Tablename: tl_content
 */
$strName = 'tl_content';

/* Palettes */
$GLOBALS['TL_DCA'][$strName]['palettes']['myproduct'] = '{type_legend},type,headline;{protected_legend:hide},protected;{expert_legend:hide},guests,cssID,space;{invisible_legend:hide},invisible,start,stop';

Languages

Wir erstellen nun die Datei languages/de/default.php, um unserem Inhaltselement in der Auswahlbox für den Typ einen schönen Titel zu verpassen.

// languages/de/default.php
/**
 * Content Elements
 */
$GLOBALS['TL_LANG']['CTE']['esit']      = array('easy Solutions IT');
$GLOBALS['TL_LANG']['CTE']['myproduct'] = array('Produkt');

Autoload

Damit unsere Klasse für das Inhaltselement auch angespreochen werden kann, legen wir die Datei config/autoload.php mit einem entsprechenden Eintrag an. Wenn wir schon dabei sind, fügen wir auch noch einen Eintrag für das Templte hinzu. Beides erstellen wir gleich.

// config/autoload.php
/**
 * Variables
 */
$strFolder      = 'easy_extension';
$strNamespace   = 'esit\\' . $strFolder;
 
/**
 * Register the namespaces
 */
ClassLoader::addNamespaces(array
(
    $strNamespace
));
 
/**
 * Register the classes
 */
ClassLoader::addClasses(array
(
    // Elements
    $strNamespace . '\\classes\\elements\\ContentProduct' => "system/modules/$strFolder/classes/elements/ContentProduct.php"
));
 
/**
 * Register the templates
 */
TemplateLoader::addFiles(array
(
    'ce_product' => "system/modules/$strFolder/templates"
));

Die Ausgabeklasse

Nun kommt das Herzstück unseres Inhaltselements, die Klasse für die Ausgabe. Die Datei heißt in diesem Fall classes/elements/ContentProduct.php.

// classes/elements/ContentProduct.php
namespace esit\easy_extension\classes\elements;
 
/**
 * Class ContentProduct
 * @package easy_extension\classes\elements
 */
class ContentProduct extends \ContentElement
{
 
    /**
     * Template
     * @var string
     */
    protected $strTemplate = 'ce_product';
 
    /**
     * Compile the content element
     */
    protected function compile()
    {
        if (TL_MODE == 'BE') {
            $this->genBeOutput();
        } else {
            $this->genFeOutput();
        }
    }
 
    /**
     * Erzeugt die Ausgebe für das Backend.
     * @return string
     */
    private function genBeOutput()
    {
        $this->strTemplate          = 'be_wildcard';
        $this->Template             = new \BackendTemplate($this->strTemplate);
        $this->Template->title      = $this->headline;
        $this->Template->wildcard   = "### ContentProduct ###";
    }
 
    /**
     * Erzeugt die Ausgebe für das Frontend.
     * @return string
     */
    private function genFeOutput()
    {
        $objProducts = $this->loadProducts();

        if ($objProducts) {
            $this->Template->objProducts = $objProducts;
        }
    }

    /**
     * Lädt alle Einträge aus der Produktdatenbank
     * @return \Database\Result|object
     */
    private function loadProducts()
    {
        $objDb      = \Contao\Database::getInstance();
        $strQuery   = "SELECT * FROM tl_products";
        $objResult  = $objDb->execute($strQuery);
        return $objResult;
    }
}

In Zeile 47 rufen wir die Methode für das Laden der Produkte auf. Wenn diese ein Ergebnis liefert, wird es in Zeile 50 an das Template übergeben. Das Laden der Einträge geschieht in den Zeilen 60-62. Der Einfachheit halber habe ich hier die Datenbankklasse von Contao verwendet. Auf das Erstellen eines Models verzeichte ich in diesem Artikel erst einmal. Nun können wir im Template auf die Produktdaten zugreifen.

Template

Wir erstellen die Datei templates/ce_product.html5

<div class="<?php echo $this->class; ?> block"<?php echo $this->cssID; ?><?php if ($this->style): ?> style="<?php echo $this->style; ?>"<?php endif; ?>>

    <!-- Überschrift aus dem Inhaltselement-->
    <?php if ($this->headline): ?>
        <<?php echo $this->hl; ?>><?php echo $this->headline; ?></<?php echo $this->hl; ?>>
    <?php endif; ?>
    
    <!-- Produktdaten -->
    <?php while ($this->objProducts->next()): ?>
        <div class="product">
            <h2>
                <?php echo $this->objProducts->title; ?>
            </h2>
        
            <div class="price">
                Preis: <?php echo $this->objProducts->price; ?> €
            </div>
        
            <div class="description">
                <?php echo $this->objProducts->description; ?>
            </div>
        </div>
    <?php endwhile; ?>
</div>

Nun wird eine Liste unserer Produkte ausgegeben. Die Eigenschaften stehen in den Zeilen 12, 16 und 20. Die Ausgabe kann leicht um weitere Details erweitert werden. Es müssen nur neue Felder in DCA eingefügt und dann über das Template ausgegeben werden. Die Klasse selber muss nicht mehr angepasst werden, da wir einfach alle Daten der Produkte an das Template übergeben. Wenn man ganz geschickt sein will, kann man auch ins Inhaltselement eine Auswahl der Felder einfügen. So könnte dort entschieden werden, welche Daten ausgegeben werden und in welcher Reihenfolge. Aber dazu komme ich vielleicht in einem spätere Artikel.

Zurück

Einen Kommentar schreiben