In vielen Fällen brauch man bei der Pluginentwicklung einen Controller, welcher die entsprechenden Models „organisiert“ – hier zeige ich euch in einem einfachen Beispiel wie das ab SW 5.2 geht…
URL Aufbau
Bei den meisten MVC Frameworks ist der Aufbau gleich TLD/controller/action ein Beispiel dafür in CakePHP ist zum Beispiel.
http://www.meinshop.de/users/index – welches alle meine User auflisten würde.
In Shopware steht vor dem controller und der action noch das module.
Zum Beispiel http://www.meinshop.de/frontend/index/index
Module
Es gibt aktuell 4 Module:
- Frontend
- Backend
- Widgets
- API
Bis auf Widgets ist eigentlich alles selbsterklärend. Widgets sind wiederverwendbar und sind durch ESI Tags auch unabhängig „cachebar“ (ESI Tags)
Auf Controller und Action gehe ich ebenfalls nicht ein, dazu schaut euch am besten mal das MVC Konzept im ganzen an.
Controller
Um jetzt einen Controller anzulegen erstellen wir in unserem Plugin einen Ordner Controllers in dem wir den/die jeweils nötigen Modulordner anlegen – in unserem Fall Frontend.
cd /var/www/shopware/custom/plugins/MiHoDetailPageExtension mkdir Controllers && cd Controllers && mkdir Frontend cd Frontend && nano Video.php
<?php class Shopware_Controllers_Frontend_Video extends Enlight_Controller_Action { public function indexAction() { exit('Videos will be here soon!'); } }
Wir können hier noch kein Text ausgeben, z.B. durch ein echo oder var_dump. Das liegt am fehlenden View – wie in jedem MVC Framework brauch der Controller einen View wenn man Ihn im Frontend aufrufen möchte. Also packen wir’s
mkdir Views && mkdir Views/frontend && mkdir Views/frontend/video && cd Views/frontend/video nano index.tpl
{extends file="parent:frontend/index/index.tpl"} {block name="frontend_index_content"} <div style="margin-left: 16.25rem;"> <h3>Shopware Demo Controller</h3> <iframe width="424" height="238" src="https://www.youtube.com/embed/SvIRoxBidHE" frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen></iframe> </div> {/block}
Funktioniert nicht? Ja, das ist mir erst auch passiert – wenn du noch der Shopware Doku gehst ist dir das sicher auch passiert.
Template View
Wir müssen für eine richtige Verlinkung von Controller und Template dieses in der serivce.xml registieren:
<service id="mi_ho_detail_page_extension.subscriber.template_registration" class="MiHoDetailPageExtension\Subscriber\TemplateRegistration"> <argument>%mi_ho_detail_page_extension.plugin_dir%</argument> <argument type="service" id="template"/> <tag name="shopware.event_subscriber"/> </service>
danach fügen wir in den Ordner Subscriber noch eine TemplateRegistration.php ein
<?php namespace MihoDetailPageExtension\Subscriber; use Enlight\Event\SubscriberInterface; class TemplateRegistration implements SubscriberInterface { /** * @var string */ private $pluginDirectory; /** * @var \Enlight_Template_Manager */ private $templateManager; /** * @param $pluginDirectory * @param \Enlight_Template_Manager $templateManager */ public function __construct($pluginDirectory, \Enlight_Template_Manager $templateManager) { $this->pluginDirectory = $pluginDirectory; $this->templateManager = $templateManager; } /** * {@inheritdoc} */ public static function getSubscribedEvents() { return [ 'Enlight_Controller_Action_PreDispatch' => 'onPreDispatch' ]; } public function onPreDispatch() { $this->templateManager->addTemplateDir($this->pluginDirectory . '/Views'); } }
Jetzt sollte es klappen 😉
Das ganze sollte dann ungefähr so aussehen:
Hallo,
ich habe ein Verstädnisproblem. Ich habe meinen service für SW 5.5.1 entsprechend erweitert. Das scheint zu funktionieren.
%gwen_move_menubar.plugin_dir%
entsprechend habe ich den Controller Video.php angelegt.
class Shopware_Controllers_Frontend_Video extends Enlight_Controller_Action {
public function indexAction() {
exit(‚Videos will be here soon!‘);
}
}
und wie beschrieben, den Subscriber und das Template.
Als Ausgabe bekomme ich unter 127.0.1.1:8080/video
den Exit Aufruf „Videos will be here soon!“
Ich möchte aber das Video sehen.
Entsprechend habe ich in der ActionIndex() den Exit Call durch $this->View()->loadTemplate(„frontend/video/index.tpl“);
ersetzt. Aber das ist schon vom Gefühl irgendwie falsch,
da die View in im Subscriber TemplateRegistration.php ausgeführt wird. Was auch zu entsprechender Fehlermeldung im Frontend führt, wenn die Exit() Funktion ersetzt wird:
Fatal error: Uncaught SmartyException: Unable to load template snippet ‚frontend/video/index.tpl|frontend/plugins/seo/index.tpl‘ in /shopware-5.5.1-0
Was muss ich in die IndexAction eintragen, damit ein Video angezeigt wird?
Vielen Dank.
Oh nein. Es hat die xml tags verschlungen samt den Quellcode. Also nochmal.
%gwen_move_menubar.plugin_dir%
grml…. Jedenfalls funktioniert der service aber die indexAction() will nicht.
ic habe noch folgendes gefunden. Scheint also veraltet zu sein.
https://scrutinizer-ci.com/g/shopware/shopware/code-structure/5.4/class/%2Bglobal%5CShopware_Controllers_Frontend_Ticket
* @deprecated Will be removed in 5.5.
*/
public function indexAction()
Es geht. Der Fehler lag im Unable to load template snippet ‚frontend/video/index.tpl. Ich hatte video.tpl statt index.tpl.
Was genau ist ein WIDGET Controller und wie benutzt man diesen am besten und wofür?
In sw dokus steht nix. 🙁
Vielen Dank für die Hilfe
Das kannst du dir unter shopware/engine/Shopware/Controllers/Widgets/Captcha.php
&
shopware/themes/Frontend/Bare/frontend/newsletter/index.tpl
anschauen.
Dort gibt es z.B. {url module=widgets controller=Captcha action=refreshCaptcha}
Widgets dienen zum einfachen holen von Daten