Blog Einträge

OXID SEO – under the hood

Da die SEO-Funktionalität in OXID nicht unbedingt selbsterklärend ist, hier ein kurzer technischer Einblick in die Erzeugung und „Archivierung“ von SEO-URLs am Beispiel von Kategorie-URLs im Shop :)

OXID SEO-URLs werden in der Tabelle „oxseo“ gespeichert. Kategorie-URLs werden aus dem Titel (OXTITLE) der Kategorie generiert, wobei Umlaute und Sonderzeichen natürlich ersetzt bzw. entfernt werden (Details dazu hier). Blättert man in Kategorien, werden für jede Seite eigene Einträge in „oxseo“ geschrieben.

Einträge mit Blätterlinks in der oxseo Tabelle

Die jeweilige Seitenzahl wird hier im Feld „OXPARAMS“ gespeichert. Wird der Titel einer Kategorie geändert, muss natürlich sinnvollerweise auch die SEO-URL dieser Kategorie geändert werden (plus die URLs aller Unterkategorien sowie die URLs der Artikel in diesen Kategorien – siehe oxcategory::_update() sowie oxseoencodercategory::markRelatedAsExpired()). Weiterlesen

Oxid Enterprise Caching

Der Oxid eShop bietet in der Enterprise Version eine ausgefeilte und flexible Caching Strategie an. Es gibt die Möglichkeit, verschiedene Caching-„Backends“ zu nutzen bzw. auch eigene Backends zu implementieren. Gecached werden können theoretisch sämtliche Shop-Klassen, um z.B. konkret Startseite, Kategorieübersichten oder Detailseiten usw. zu cachen und damit als (weitgehend) „statisches“ HTML auszuliefern, um die Shop-Performance zu steigern.

Die gewünschten Klassen können im Shop-Admin unter „Stammdaten – Caching“ eingetragen werden. Standardmäßig ist im Shop als Caching-Backend der „OXID eShop Disk Storage Cache“ verfügbar, der die Cache-Daten als „.cache“-Dateien im „/tmp“-Verzeichns des Shops ablegt und eine Referenz darauf in der „oxcache“-Datenbanktabelle einträgt. Hat man auf dem Server die „Zend Plattform“ installiert, so steht auch ein Zend Cache-Backend zur Verfügung. Es ist aber auch problemlos möglich, eigene Backends einzusetzen, die lediglich ein bestimmtes Interface implementieren müssen und damit Methoden zu bieten, Daten im Cache zu speichern, wieder auszulesen und schliesslich auch wieder zu löschen. Exemplarisch sei hier ein „Memcached„-Backend genannt, das Shoptimax für einen Kunden umgesetzt hat, um das Caching effizienter zu machen und für verteilte Shop-Server (Loadbalancer/Cluster) mit verteilten tmp-Verzeichnissen zu optimieren – hier hat man sonst eine hohe sog. „Cache Miss“-Rate (und dadurch letztlich eine schlechtere Performance), da die „.cache“-Dateien zwar in der Datenbank noch referenziert werden, teilweise aber im Dateisystem nicht gefunden werden, da sie unter Umständen nicht auf demselben Cluster-Server im dortigen „tmp“-Verzeichnis des Shops liegen, auf dem auch der Shop-Kunde aktuell mit dem Browser „gelandet“ ist.

Nicht immer sollen jedoch komplette Shop-Seiten gecached werden, Informationen wie Warenkorbinhalt, Login-Name, Verfügbarkeitsanzeigen usw. sollen natürlich immer aktuell sein. Zu diesem Zweck „injiziert“ der Oxid EE Shop in die gecachten Seiten dynamische „Snippets“, dafür sorgt die Smarty-Funktion „oxid_include_dynamic„. Diese inkludiert Smarty Template-Schnippsel (normalerweise aus dem „out/basic/tpl/dyn“ Verzeichnis) in die gewünschte Seite bzw. das gewünschte Template. Hier ein Beispiel das die Warenkorbinhalte dynamisch einbindet:

[{oxid_include_dynamic file=“dyn/mini_basket.tpl“ type=“basket“ extended=true testid=“RightBasket“}]

Wichtig ist hierbei, dass an ein solches „dynamisches“ Template kein Objekt als Argument übergeben werden kann, wie dies bei normalen Templates der Fall ist, also z.B. ein “ … product=$product …“ o.ä ist hier nicht möglich. Stattdessen muss in einem solchen Fall z.B. ein String oder Integer-Wert übergeben werden wie etwa die Produkt-Id, im Beispiel also etwa “ … productid=$product->oxarticles__oxid-value …“. Hintergrund ist, dass die Parameter-Werte per base64_encode() und base64_decode() umgewandelt und übertragen werden. Um den übergebenen Parameter dann auszuwerten und z.B. das gewünschte Objekt zu erzeugen/laden und wiederum im Template zur Verfügung zu stellen, ist es nötig, die Funktion oxCache::_processDynContent() per Modul zu überschreiben und mit der gewünschten Logik zu erweitern. Um auf die übergebenen Parameter direkt im inkludierten, dynamischen Template zugreifen zu können, muss man zudem einen Unterstrich (Underscore) „_“ davor setzen, im Beispiel also [{$_productid}], da in der Methode oxCache::_processDynContent() alle Variablen mit diesem Prefix versehen und wieder in das Template geschrieben werden.
Will man aus irgendwelchen Gründen Template-Logik nur bei aktivem Caching einbinden, kann man die Variable $_render4cache abfragen, die in diesem Falle in allen Templates verfügbar ist:

[{if $_render4cache}]
    Sie sehen eine gecachte Version der aktuellen Seite!
[{/if}]

Fazit: Für größere Shops mit sehr vielen Kategorien und/oder Artikeln ist Caching im OXID eShop eigentlich unerlässlich, wir konnten in manchen Shops und mit bestimmten Shop-Klassen eine Performance-Steigerung um den Faktor 5 feststellen – nicht nur im Hinblick auf Google-Ranking von Vorteil, sondern generell für die Usability und Akzeptanz des Shops durch die Kunden.