Blöcke, Templates, Layouts, Übersetzungen
Nachdem wir im ersten Teil der Blogserie den Grundstein für unser neues Magento 2 Modul gelegt haben, wird es nun Zeit, das eigentliche Modul zu entwickeln.
Vieles hat sich in Magento 2 geändert. Gerade als Magento Frontend-Entwickler ist der Umstieg auf Magento 2 allerdings gar kein so großer Sprung.
In diesem Teil wollen wir uns alles ansehen, was benötigt wird, um ein einfaches Magento 2 Modul mit Blöcken, Templates, Layouts und Übersetzungen zu erstellen.
Die Ordnerstruktur
Eine der Änderungen in Magento 2 ist, dass alle Dateien eines Moduls jetzt in einem Ordner sind. Das bedeutet, statt unsere Template Dateien irgendwo im Ordner app/design zu verstauen, werden Layout und Template Dateien jetzt im Ordner view im Modul abgelegt.
Auch die Übersetzungen für unser Modul werden wir direkt in das Modul packen können, in den Ordner i18n (internationalization).
Der erste Block
Unser erster Block soll die Aufgabe haben, bei den Produktinformationen auf der Artikeldetailseite einen Text darzustellen.
Wie auf dem Bild zu erkennen, soll der Block den Text „Hallo, (Produktname)! Wie geht es dir?“ ausgeben.
Hinweis:
Um die Nachricht in Deutsch anzuzeigen, muss Deutsch als Sprache für den Store gewählt sein.
Fangen wir mit der Block-Klasse an. Block-Klassen werden im Ordner Block angelegt. Starten wir mit einer Datei mit dem Namen HelloProduct.php:
<?php
namespace Tudock\HelloWorld\Block;
class HelloProduct extends \Magento\Catalog\Block\Product\View\AbstractView {
/**
* Get the name of the current product
* @return string
*/
public function getProductName() {
return $this->getProduct()->getName();
}
}
Alle Blöcke, die wir für unser Modul anlegen wollen, müssen diesen Regeln folgen:
- Die Dateien müssen im Ordner Block liegen. Der Name der Datei ist der Name des Blocks.
- Die Dateien müssen eine Klasse beinhalten, welche den Namen des Blocks trägt.
- Die Klassen müssen im Namespace {Vendor}\{Modul}\{Block} liegen.
- Liegt der Block in einem Unterordner (bspw. Block/Catalog/View.php), so müssen alle Unterordner an den Namespace angehängt werden ({Vendor}\{Modul}\{Block}\Catalog).
- Die Klassen müssen \Magento\Framework\View\Element\AbstractBlock oder eine Unterklasse erweitern.
Magento 2 stellt die Block-Klasse \Magento\Catalog\Block\Product\View\AbstractView zur Verfügung. Wir erweitern diese Klasse, denn sie beinhaltet die Methode getProduct(), welche wir nutzen, um in getProductName() den Namen des aktuellen Produktes zur Verfügung zu stellen.
Ein Layout-Eintrag für den Block
Jetzt wo unser Block angelegt ist, brauchen wir noch einen Layout-Eintrag und natürlich ein Template, das am Ende den von uns gewünschten Text ausgibt.
Beides wird im Ordner view angelegt. In diesem Ordner müssen die Unterordner frontend/templates und frontend/layout angelegt werden. Dort liegen Layouts und Templates für das Frontend.
Im Ordner Layout müssen wir nun ein neues Layout-Update anlegen, welches unseren Block an das Ende der Produktinformationen auf der ADS einfügt. Anders als in Magento 1 gibt es hierfür eine klare Naming-Convention.
Die Layout-Handles aus Magento 1 sind jetzt auf einzelne Dateien verteilt. Möchten wir, dass etwas auf der ADS angezeigt wird, so suchen wir nach dem Layout-Handle catalog_product_view. Dieses können wir in Magento 2 in der Datei view/frontend/layout/catalog_product_view.xml bearbeiten:
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceContainer name="product.info.main">
<block class="Tudock\HelloWorld\Block\HelloProduct" name="hello-product" template="helloproduct.phtml"/>
</referenceContainer>
</body>
</page>
Wer mit Layout-Dateien aus Magento 1 vertraut ist, wird feststellen, dass sich einige Dinge geändert haben:
Die erste Node in dieser XML-Datei ist nicht mehr das Layout-Handle (dieses wird wie gesagt über den Datei-Namen ermittelt), sondern der Bereich. In unserem Fall wollen wir eine Änderung innerhalb des body-Tags der Seite durchführen.
Als Nächstes referenzieren wir den Container product.info.main (referenceContainer). referenceContainer und referenceBlock ersetzen reference aus Magento 1.
Container sind ein neuer Typ in den Layouts von Magento 2. Sie bündeln eine Reihe von Blöcken auf der Seite.
Wir legen in dem Container product.info.main (dem Informationsbereich auf der ADS) einen neuen Block an, und zwar den Block, den wir zuvor erstellt haben.
Dafür geben wir unter class die Klasse unseres Blocks mit vollem Namespace-Pfad an und geben unserem Block einen Namen. Wir geben auch ein Template mit dem Namen helloproduct.phtml an, den wir in Kürze anlegen.
Hinweis:
Alternativ kann auch wie früher im Block selbst die Methode setTemplate() benutzt werden, um das Template des Blocks festzulegen.
Das Template für den Block
Unser neues Template liegt unter view/frontend/templates/helloworld.phtml:
<?php
/** @var $block \Tudock\HelloWorld\Block\HelloProduct */
?>
<p>
<?php echo __('Hello') ?> , <?php echo $block->getProductName(); ?>!
</p>
<p>
<?php echo __('How are you?') ?>
</p>
Templates funktionieren quasi wie in Magento 1 auch, allerdings kann die Blockklasse jetzt nicht mehr mit $this, sondern nur noch mit $block referenziert werden.
Unser Template verwendet die globale Funktion __(), die überall in Magento zur Übersetzung genutzt werden kann.
Übersetzung
Für die beiden Strings, die wir übersetzen wollen, legen wir die Datei i18n/de_DE.csv an:
"Hello", "Hallo"
"How are you?", "Wie geht es dir?"
Testen
Wenn wir die Änderungen jetzt speichern, einen Commit erstellen und dann im Shop diese drei Befehle ausführen, sollten wir auf der ADS unser Ergebnis bewundern können:
composer update
bin/magento setup:upgrade
bin/magento cache:flush
Ausblick
Im nächsten Teil geht es weiter mit Controllern, damit schließen wir das Thema Frontend-Entwicklung ab, ehe wir uns dann Models und Dependency Injection ansehen.
Es lohnt sich also, unserem Blog zu folgen!
Tipp:
Den Quellcode für diesen Blogeintrag gibt es auch bei github.
Die weiteren Beiträge der Serie
- Magento 2 Modulentwicklung – Teil 1: Vorbereitung
- Magento 2 Modulentwicklung – Teil 3: Controller und Actions
- Magento 2 Modulentwicklung – Teil 4: Models und Dependency Injection
- Magento 2 Modulentwicklung – Teil 5: Wichtige Objekte
- Magento 2 Modulentwicklung – Teil 6: Resource Models und Install-Scripts
- Magento 2 Modulentwicklung – Teil 7: Observer, Helper und Fazit