Eine beliebte Frage in einer Magento-Schulung für Entwickler: Wie kann unter einer frei gewählten URL in Magento eigener PHP-Code ausgeführt werden?
Die Magento-Installation ist z. B. unter http://domain.de/shop/ erreichbar. Unter http://domain.de/shop/beliebiges-unterverzeichnis/landingpage.html soll ein PHP-Code ausgeführt werden und „Hallo Welt!“ ausgeben.
Eigenes virtuelles Unterverzeichnis in Magento
Der Router bestimmt das (virtuelle) Unterverzeichnis, bei dessen Aufruf der damit verknüpfte Controller ausgeführt wird.
Hierfür muss eine Magento-Erweiterung mit drei Dateien erstellt werden, damit wir beim Aufruf des Verzeichnisses http://127.0.0.1/custom/ unseren eigenen Code ausführen können:
app/etc/modules/Xonu_Controller.xml
<?xml version="1.0"?> <config> <modules> <Xonu_Controller> <active>true</active> <codePool>local</codePool> </Xonu_Controller> </modules> </config>
Durch diese Konfiguration wird der Code der Erweiterung im Verzeichnis app/code/<codePool>/<Namespace>/<Name>, also app/code/app/code/local/Xonu/Controller erwartet. Die Namen Xonu und Controller sind frei gewählt.
Um Fehler zu vermeiden, sollten der Namensraum und der Name der Erweiterung stets nur einen Großbuchstaben am Anfang enthalten (z. B. statt MyController, sollte Mycontroller verwendet werden).
app/code/local/Xonu/Controller/etc/config.xml
<?xml version="1.0"?> <config> <global> <!-- Der Router wird im Frontend und Backend berücksichtigt. --> </global> <admin> <!-- Der Router wird im Frontend und Backend berücksichtigt. --> </admin> <frontend> <!-- Der Router wird nur im Frontend berücksichtigt. --> <routers> <xonu_controller_router> <!-- Frei gewählter Name des XML-Knotens. --> <use>standard</use> <args> <!-- Hauptverzeichnis/Klassenprefix der Erweiterung. --> <module>Xonu_Controller</module> <!-- Frei gewählter Name für das erste virtuelle Unteverzeichnis. --> <frontName>custom</frontName> </args> </xonu_controller_router> </routers> </frontend> </config>
app/code/local/Xonu/Controller/controllers/IndexController.php
<?php class Xonu_Controller_IndexController extends Mage_Core_Controller_Front_Action { public function indexAction() { echo "Hallo Welt!"; } }
Die Benennungen des Unterverzeichnisses controllers, klein geschrieben, der Datei IndexController.php und des darin definierten Klassennamens Xonu_Controller_IndexController und ihre Ableitung von einer bestimmten Core-Klasse ist von Magento vorgeschrieben.
Nach dem der Konfigurationscache aktualisiert wurde, falls aktiv, wird bereits das registrierte Unterverzeichnis funktionieren:
http://127.0.0.1/custom
Hallo Welt!
Gleiches gilt für die virtuelle Unterverzeichnisse /custom/index und /custom/index/index. Das erste Unterverzeichnis index bezieht sich auf den Namen des Controllers IndexController.php. Das zweite Unterverzeichnis index bezieht sich auf den Präfix im Namen der darin definierten Methode indexAction(). Für die folgenden Aufrufe bekommen wir also die gleiche Ausgabe:
http://127.0.0.1/custom/index
http://127.0.0.1/custom/index/index
Durch Einführung einer weiteren Methode mit einem beliebigen Präfix, gefolgt vom Schlüsselnamen Action, können wir weitere virtuelle Unterverzeichnisse für die URL http://127.0.0.1/custom/index definieren:
app/code/local/Xonu/Controller/controllers/IndexController.php
<?php class Xonu_Controller_IndexController extends Mage_Core_Controller_Front_Action { public function indexAction() { echo "Hallo Welt!"; } public function anotherAction() { echo "Xonu_Controller_IndexController::anotherAction"; } }
Die zweite Methode anotherAction() kann durch die URL http://127.0.0.1/custom/index/another aufgerufen werden und liefert die folgende Ausgabe:
http://127.0.0.1/custom/index/another
Xonu_Controller_IndexController::anotherAction
Das erste Unterverzeichnis wird durch den Präfix im Namen der Controller-Klasse und der php-Datei bestimmt. Weiteres Unterverzeichnis /custom/second können wir durch die Definition einer weiteren Controller-Klasse registrieren:
app/code/local/Xonu/Controller/controllers/SecondController.php
<?php class Xonu_Controller_SecondController extends Mage_Core_Controller_Front_Action { public function indexAction() { echo "Xonu_Controller_SecondController::indexAction"; } public function anotherAction() { echo "Xonu_Controller_SecondController::anotherAction"; } }
Nun bekommen wir folgende Ausgaben:
http://127.0.0.1/custom/second
http://127.0.0.1/custom/second/index
Xonu_Controller_SecondController::indexAction
Noch tiefere Unterverzeichnisse können als Parameter über spezielle Methoden von Magento ausgelesen werden:
app/code/local/Xonu/Controller/controllers/DeeplinkController.php
<?php class Xonu_Controller_DeeplinkController extends Mage_Core_Controller_Front_Action { public function evaluateAction() { echo '<pre>'; echo "Xonu_Controller_DeeplinkController::indexAction\n"; echo "\n".'$_GET:'."\n"; print_r($_GET); echo "\n".'Mage::app()->getRequest()->getParams():'."\n"; print_r(Mage::app()->getRequest()->getParams()); } }
Beispielaufrufe und -Ausgaben:
http://127.0.0.1/custom/deeplink/evaluate/param1/value1/param2/value2
Xonu_Controller_DeeplinkController::indexAction $_GET: Array ( ) Mage::app()->getRequest()->getParams(): Array ( [param1] => value1 [param2] => value2 )
GET-Parameter können direkt über die GET-Variable als auch über die Methoden von Magento ausgelesen werden. Letzteres ist durch interne Filter sicherer und deshalb der Arbeit direkt mit der GET-Variable vorzuziehen:
http://127.0.0.1/custom/deeplink/evaluate/param1/value1/?param2=value2
Xonu_Controller_DeeplinkController::indexAction $_GET: Array ( [param2] => value2 ) Mage::app()->getRequest()->getParams(): Array ( [param1] => value1 [param2] => value2 )
http://127.0.0.1/custom/deeplink/evaluate/?param1=value1¶m2=value2
Xonu_Controller_DeeplinkController::indexAction $_GET: Array ( [param1] => value1 [param2] => value2 ) Mage::app()->getRequest()->getParams(): Array ( [param1] => value1 [param2] => value2 )
Das eigene Verzeichnis beliebig gestalten
Bei der Gestaltung virtueller Unterverzeichnisse ist man also an bestimmte Regeln von Magento gebunden. Durch das URL Rewrite Verwaltung lassen sich diese Verzeichnisstrukturen hinter einer beliebigen URL verbergen.
Im Backend, unter Katalog > URL Rewrite Verwaltung legen wir einen neuen URL Rewrite an. Im obersten Menü wählen wir Benutzerdefiniert aus und füllen das Formular aus:
- Store: Hier ist das StoreView gemeint, in dem die URL gelten soll. Es gibt keine Möglichkeit die URL mit einem Eintrag für alle StoreViews festzulegen; in diesem Fall muss die URL für jeden StoreView einzeln angelegt werden. Beachten Sie auch, dass die Spalte store_id in der Tabelle core_url_rewrite, wo die URL Rewrites verwaltet werden, niemals die 0 enthält.
- ID Pfad: Neben der automatisch vergebenen Id, muss dem Rewrite eine zusätzliche interne Id vergeben werden. Dies kann ein beliebiger eindeutiger Wert sein und wird in der Spalte id_path gespeichert.
- Anfragepfad: Das ist die URL, die frei gestaltet werden kann. Sie kann z.B. beliebige virtuelle Unterverzeichnisse enthalten. Die URL wird ohne führenden Slash und ohne Domainnamen eingegeben. Für die URL http://domain.de/beliebiges-unterverzeichnis/landingpage.html, wird als Anfragepfad beliebiges-unterverzeichnis/landingpage.html angegeben. Befindet sich die Magento-Installation in einem Unterverzeichnis, z.B. http://domain.de/shop, enthält der Anfragepfad dieses Unterverzeichnis nicht.
- Zielpfad: Dies ist das Verzeichnis unter dem ein Controller aufgerufen wird, welches an bestimmte Vorgaben geknüpft ist und deshalb nicht ganz frei gestaltet werden kann. Auch dieses Verzeichnis wird, wie Anfragepfad, ohne führenden Slash und ohne Domain (und Shop-Verzeichnis) eingetragen: custom/deeplink/evaluate/param1/value1/param2/value2.
- Weiterleitung: Für unseren Zweck ist Nein die optimale Einstellung. Wird die Weiterleitung aktiviert, wird der Nutzer zu dem Zielpfad weitergeleitet und sieht ihn in der Adressleiste des Browsers.
Nach der Speicherung des Rewrites bekommen wir unter der neuen URL die folgende Ausgabe:
http://127.0.0.1/beliebiges-unterverzeichnis/landingpage.html
Xonu_Controller_DeeplinkController::indexAction $_GET: Array ( ) Mage::app()->getRequest()->getParams(): Array ( [param1] => value1 [param2] => value2 )
Wir können weitere GET-Parameter übergeben, doch diese können ausschließlich über die GET-Variable ausgelesen werden:
http://127.0.0.1/beliebiges-unterverzeichnis/landingpage.html?param3=value3
Xonu_Controller_DeeplinkController::indexAction $_GET: Array ( [param2] => value3 ) Mage::app()->getRequest()->getParams(): Array ( [param1] => value1 [param2] => value2 )