Magento mit AngularJS

AngularJS: Daten der Magento API darstellen

In jeder dynamischen Webanwendung werden Datensätze abgerufen und aufbereitet. Das kann verschiedene Ausprägungen haben. Im Fall von einem Magento Webshop sind es z.B. Produktlisten. Das klassische Vorgehen beim Aufruf durch einen Besucher folgt, unabhängig von der Webanwendung, oft dem gleichen Schema. Der Abruf von Daten durch die Anwendung steht am Anfang, gefolgt vom Laden der Vorlagen und die Darstellung der Daten. Das funktioniert, ist aber suboptimal. Anhand einer vereinfachten Produktliste zeigt dieser Artikel,  wie es AngularJS  effizienter geht.

AngularJS im Überblick

AngularJS ist ein Javascript-Framework, den oben beschriebenen Ablauf effizienter gestalten kann. HTML ist nicht für dynamische Dokumente geschaffen worden. Dieser Tatsache begegnen Skriptsprachen mit der Nutzung von Techniken wie simplen PHP-Schleifen bis hin zu ausgefeilteren Template-Sprachen. Am Ende läuft es auf das gleiche Ergebnis hinaus. Die Anwendung ruft die Daten ab, durchläuft diese und stellt fertige HTML Dokumente zur Verfügung. Die Verarbeitung der dynamischen Datensätze findet auf dem Server statt.

AngularJS geht einen anderen Weg. Ein gravierender Unterschied ist die Verlagerung der Datenverarbeitung und Aufbereitung in den Client. Die Template-Sprache ist das HTML Dokument, dessen Syntax durch das Framework erweitert wird. Die Datenverarbeitung erfolgt nicht auf dem Server, sondern im Browser. Für eine Liste (»<ul>«) wird zum Beispiel ein Template mit nur einem Element (»<li>«)an den Browser gesendet. Die Inhalte sind im JSON-Format verfügbar, werden im Browser durch AngularJS abgerufen und auf Basis der Vorlage für die Liste aufbereitet.

Warum AngularJS und Magento verwenden?

Sinnvoll ist bei AngularJS die klare Trennung von dynamischen und statischen Inhalten. Bei einem Magento Webshop wird zum Beispiel die Skalierung der Frontend-Performance einfacher. Statt den kompletten Shop über mehrere Systeme bereitstellen zu müssen, könnte zum Beispiel die REST-API nur lesend auf mehreren Servern bereitgestellt werden. Produktlisten und Kategorien liest AngularJS von dort.

Genauso spannend ist die Tatsache, dass die Möglichkeiten zum Caching verbessert werden können. Durch die Trennung der Inhalte im Rahmen und der Inhalte im Katalog gibt es weniger kundenspezifische HTML-Dokumente.

Die Performance kann mit AngularJS ebenfalls verbessert werden. Konzeptbedingt werden die Daten zur Darstellung bspw. im JSON-Format abgerufen. Volltextsuche innerhalb einer konkreten Ansicht, zum Beispiel einer Kategorie, arbeitet nahezu ohne Verzögerung. Die Filter werden auf die lokal vorhandenen Produktdaten angewandt und die Ansicht aktualisiert. Das funktioniert natürlich nur, wenn die Datenmengen nicht zu umfassend sind. Zumindest alles in allem Grund genug, um sich etwas mit AngularJS zu beschäftigen.

Was ist mit der Sicherheit?

Als Richtlinie kann empfohlen werden, dass ohnehin öffentlich verfügbare Daten auch über eine API abrufbar sein dürfen, ohne ein Risiko zu erzeugen. Den Produktkatalog gleichzeitig im REST-Format auch Gästen anzubieten, erzeugt keine Sicherheitslücke. Ein williger Angreifer kann auch problemlos HTML Dokumente einlesen.

Es gibt eindeutig Grenzen. Werden Daten von externen APIs abgerufen, muss das über eigene Server passieren. Sie sollten nicht ihre Zugangsdaten, die für Webseitenbetreiber gedacht sind, per Javascript an den Browser eines Besuchers senden. Beispiele könnten zum Beispiel APIs wie mobile.de oder vergleichbare Seiten sein.

AngularJS und Magento verbinden

Es gibt viele Webprojekte, die von AngularJS profitieren können. Magento Webshops zählen dazu. Es gleich mehrere Szenarien, in denen Abläufe optimiert werden können. In diesem Artikel wird mit AngularJS eine Produktliste aus der REST-API von Magento ausgelesen und dargestellt. Mit Liebe für die Details kann man auf der Basis eine gesamte Kategorieansicht erstellen.

Bevor mit der REST-API gearbeitet werden kann, muss noch der lesende Zugriff ermöglicht werden. Wie dies geht, kann meinem Artikel über die REST-API entnommen werden. Dort muss der Gast-Zugriff auf den Knoten »Catalog« erlaubt werden.

Installation und Vorbereitungen

Im ersten Schritt wird eine Magento Extension angelegt. Darauf gehe ich nicht ein. Bei Frage oder Problemen stehe ich gerne zur Verfügung. Ich habe meine Experimente in der Extension Luckyduck_Angularlist  hinterlegt. Die erstellt eine zugegeben schlichte Liste, was zur Demonstration jedoch ausreicht.

AngularJS installiere ich im »js« Ordner von Magento. In der minified-Version ist das eine einzelne Datei. Eingebunden wird diese über Layout-Dateien:

Zusätzlich fehlen noch Konfiguration und Vorbereitung der Extension. Der Frontend-Controller heißt bei mir ListingController, die verwendete Action ist die indexAction(). Dort passiert nichts Aufregendes:

Damit der Controller die passenden Layout-Dateien lädt, muss per XML definiert werden welche dies sind:

Die Layout-Datei wird in der config.xml referenziert:

Anschließend kann die Funktion von AngularJS getestet werden. Dazu wird in dem Template »list.phtml« Folgendes angegeben:

Darin finden sich zwei Angaben. Zum einen wird der  Container der AngularJS-App mit dem Attribut »ng-App« gesetzt. Es gibt viele Beispiele und Applikationen, die dies auf dem »<html>-Knoten« setzen. Das ist nicht zwingend notwendig. Der Test findet bei der zweiten Angabe statt. In den geschweiften Klammern wird Text zusammengefügt. Arbeitet AngularJS korrekt, wird »Nothing here yet!« auf der URL (BaseURL + »/angularlist/listing/index«) ausgegeben, nicht die Klammern.

Eine statische Liste

Bevor die dynamische Liste ausgebaut wird, sollte das Gerüst statisch aufgebaut werden. Daran orientieren wir uns im nächsten Schritt. In der Datei »list.phtml« könnte zum Beispiel folgender Code hinterlegt werden:

Nun wird eine einfache Liste mit Produkten angezeigt.

Abruf von Produkten aus der REST-API

Deutlich spannender ist es Produkte von der REST-API abzurufen. Angepasst werden muss erneut die Datei »list.phtml«. Wir erstellen zum einen eine Vorlage für die Daten. Außerdem benötigen wir einen AngularJS-Controller, der für uns die Daten von der API abruft.

Die Javascript-Anweisungen erzeugen unsere »angularlistApp« und einen Controller »ProductListCtrl«. Dass diese genutzt werden, definieren die Attribute »ng-app« und »ng-controller«. Der Controller hat die Aufgabe per HTTP auf die REST-API von Magento zuzugreifen. Das kann über einen eigenen AngularJS-Service (ein Resource-Model) gelöst werden. Da dieses Beispiel nicht schreibend auf die API zugreift, ist das überflüssig. Über das Attribut »ng-repeat« wird schließlich eine Schleife gestartet. Wir befinden uns im Controller »ProductListCtrl«. Nach erfolgreichem HTTP Abruf werden die Produktdaten in der Variable »products« gespeichert. Auf die können wir, da wir im gleichen Gültigkeitsbereich (scope) sind, wieder zugreifen. Genau das passiert mittels »ng-repeat«.

Fazit und Erweiterungen

Dieser Artikel kratzt an der Oberfläche. Ziel ist es zu zeigen, dass AngularJS und Magento ein gutes Paar sind. Mit etwas Aufwand und Liebe zum Detail könnte mit der Lösung oben eine Kategorieansicht realisiert werden. Beim Blättern werden nur noch Produktdaten per REST-API abgerufen, nicht zusätzlich gesamte Rahmen. Die Server werden entlastet, da Arbeit auf die Clientseite verlagert werden kann. AngularJS bietet noch die Möglichkeit die Vorlagen in eigenen Dateien unterzubringen. Zusätzlich wären ggf. Filter für Kategorieansichten sinnvoll. Zur Ausnutzung von den zahlreichen Fähigkeiten, die AngularJS bietet, ist jeder herzlich eingeladen.