Contao-Camp 2024
Ergebnis 1 bis 22 von 22

Thema: wie Contao (Core)-Modul extenden?

  1. #1
    Contao-Fan
    Registriert seit
    27.11.2009.
    Beiträge
    326

    Standard wie Contao (Core)-Modul extenden?

    Hallo,

    ich versuche, eine (immer noch) 3.5er Seite auf 4.9 zu bringen. Dort habe ich eigene FE-Module, die Core bzw. Calendar-Module extenden (Eventlist).

    Meine dcas etc habe ich in /contao/dca etc gepackt und wollte nun meine FE-Module als Controller in /src/Controller umschreiben.

    Aber wie kann ich das jetzt machen? Der Controller muss ja AbstractFrontendModuleController extenden? Wie kann ich (anders) die Funktionalität der Eventlist in meinen Controller bekommen? Oder muss ich das über /src/Recources/contao/modules (auf altem Wege) machen?

    Danke für Tipps & Gruß!

  2. #2
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    34.062
    Partner-ID
    10107
    » sponsor me via GitHub or PayPal or Revolut

  3. #3
    Contao-Fan
    Registriert seit
    27.11.2009.
    Beiträge
    326

    Standard

    Komplett nicht gesehen!!

    Danke!

  4. #4
    Contao-Nutzer Avatar von a-v-l
    Registriert seit
    20.09.2013.
    Ort
    Freiburg im Breisgau
    Beiträge
    88

    Standard Methode überschreiben

    Wenn ich also z.B. vendor/contao/core-bundle/src/Resources/contao/modules/ModuleLogin.php erweitern will, würde ich in src/Controller/FrontendModule/ eine Datei (z.B.) LoginController.php mit folgendem Inhalt anlegen:

    PHP-Code:
    // src/Controller/FrontendModule/LoginController.php
    namespace App\Controller\FrontendModule;

    use 
    Contao\CoreBundle\Controller\FrontendModule\AbstractFrontendModuleController;
    use 
    Contao\CoreBundle\ServiceAnnotation\FrontendModule;
    use 
    Contao\CoreBundle\Security\Exception\LockedException;
    use 
    Contao\ModuleModel;
    use 
    Contao\ModuleLogin;
    use 
    Symfony\Component\HttpFoundation\Response;

    class 
    LoginController extends ModuleLogin
    {
        public function 
    __construct() {}

        public function 
    __invoke(ModuleModel $modelstring $section): Response
        
    {
            
    parent::__construct($model$section);

            return new 
    Response($this->generate());
        }

        
    // override parent method compile()
        
    protected function compile()
        {
            
    $this->Template->helloWorld "Hallo Welt!";
            
    parent::compile();
        }

    und im Template mod_login.html5 irgendwo ausgeben:

    PHP-Code:
    <h1><?= $this->helloWorld ?></h1>
    Leider wird mein schönes „Hallo Welt!“ aber nicht ausgegeben… Muss ich den Controller noch irgendwo registrieren? Ist irgendwo ein Fehler im Code? (Und: wofür benötige ich die Methoden __construct() und __invoke() ?)

    Danke für eure Hinweise!

  5. #5
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    34.062
    Partner-ID
    10107

    Standard

    Ja, dir fehlt noch die Registrierung über die Annotation: https://docs.contao.org/dev/framewor...es/#annotation
    » sponsor me via GitHub or PayPal or Revolut

  6. #6
    Contao-Nutzer Avatar von a-v-l
    Registriert seit
    20.09.2013.
    Ort
    Freiburg im Breisgau
    Beiträge
    88

    Standard

    Also wenn ich meinen Code um die folgenden Zeilen erweitere, ändert das nichts… (Cache natürlich geleert)

    PHP-Code:
    use Contao\CoreBundle\ServiceAnnotation\FrontendModule;

    /**
     * @FrontendModule(category="miscellaneous")
     */
    class LoginController extends ModuleLogin … 
    Vielleicht ist auch die Kategorie falsch. Habe bisher allerdings noch keine Kategorien-Liste oder so was gefunden.

    Meinen Controller habe ich mit einer /contao/config/config.php zum Laufen gebracht:

    PHP-Code:
    $GLOBALS['FE_MOD']['user']['login'] = 'App\Controller\FrontendModule\LoginController'
    Allerdings gibt es jetzt Probleme mit dem Aufruf der Eltern-Methode: parent::compile();

  7. #7
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    34.062
    Partner-ID
    10107

    Standard

    Den Frontend Module Controller musst du per Service Tag (bzw. Annotation) registrieren, nicht über die config.php
    » sponsor me via GitHub or PayPal or Revolut

  8. #8
    Contao-Nutzer Avatar von a-v-l
    Registriert seit
    20.09.2013.
    Ort
    Freiburg im Breisgau
    Beiträge
    88

    Standard

    Ja, so hat's funktioniert!

    PHP-Code:
    # config/services.yaml
    services:
        
    App\Controller\FrontendModule\LoginController:
            
    tags:
                -
                    
    namecontao.frontend_module
                    category
    user 
    Danke!

  9. #9
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    34.062
    Partner-ID
    10107

    Standard

    Empfohlen wäre Annotation
    » sponsor me via GitHub or PayPal or Revolut

  10. #10
    Contao-Nutzer Avatar von a-v-l
    Registriert seit
    20.09.2013.
    Ort
    Freiburg im Breisgau
    Beiträge
    88

    Standard

    Zitat Zitat von Spooky Beitrag anzeigen
    Empfohlen wäre Annotation
    Das hatte ich ja schon die ganze Zeit versucht. Wenn ich das richtig verstanden habe, ist die Syntax dafür folgendermassen:

    PHP-Code:
    use Contao\CoreBundle\ServiceAnnotation\FrontendModule;

    /**
     * @FrontendModule(category="member")
     */
    class MyLoginController extends ModuleLogin
    {
        
    // hier wie unter https://docs.contao.org/dev/guides/fragment-controllers/
        // beschrieben, die __construct() & __invoke Methoden
        // und die zu überschreibende Methode der Eltern-Klasse.

    Leider wird das scheinbar nicht erkannt. BTW: Auch meine IDE (die sonst Annotations ordentlich formatiert) „erkennt“ @FrontendModule(category="member") nicht.

    Komplett verwirrt bin ich, seit ich meinen Controller von LoginController zu MyLoginController umbenannt habe: Seit dem wird er garnicht mehr erkannt – auch nicht mit der /contao/config/config.php oder der /config/services.yaml.

    Also, ich bin wirklich hoch erfreut, dass die Entwickler-Docu in den letzten Jahre so gut fortgeschrieben wurde! Aber wenn ich das Beispiel von der Doc eins zu eins mit meiner Contao-Version 4.9.20 umsetze, passiert einfach gar nichts – das sollte doch eigentlich nicht sein, oder?

  11. #11
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    34.062
    Partner-ID
    10107

    Standard

    Poste mal den gesamten Code (inkl. Pfadangaben und composer.json).
    » sponsor me via GitHub or PayPal or Revolut

  12. #12
    Contao-Nutzer Avatar von a-v-l
    Registriert seit
    20.09.2013.
    Ort
    Freiburg im Breisgau
    Beiträge
    88

    Standard

    Also bleiben wir mal bei dem Beispiel auf https://docs.contao.org/dev/guides/f...t-controllers/

    Ich habe in /src/Controller/FrontendModule/AppExampleController.php folgendes:

    PHP-Code:
    <?php
    // src/Controller/FrontendModule/AppExampleController.php
    namespace App\Controller\FrontendModule;

    use 
    Contao\CoreBundle\ServiceAnnotation\FrontendModule;
    use 
    Contao\ModuleModel;
    use 
    Contao\ModuleNewsList;
    use 
    Symfony\Component\HttpFoundation\Response;

    /**
     * @FrontendModule(category="news")
     */
    class AppExampleController extends ModuleNewsList
    {
        public function 
    __construct() {}

        public function 
    __invoke(ModuleModel $modelstring $section): Response
        
    {
            
    parent::__construct($model$section);

            return new 
    Response($this->generate());
        }

        
    /**
         * Generate the module
         */
        
    protected function compile()
        {
            
    $this->Template->hallo "Hallo Welt!";
            
    parent::compile();
        }
    }
    Und in /templates/mod_newslist.html5

    PHP-Code:
    <?php $this->extend('block_unsearchable'); ?>

    <?php $this->block('content'); ?>

      Test: <?= $this->hallo ?>
      <?php if (empty($this->articles)): ?>
        <p class="empty"><?= $this->empty ?></p>
      <?php else: ?>
        <?= implode(''$this->articles?>
        <?= $this->pagination ?>
      <?php endif; ?>

    <?php $this->endblock(); ?>
    Die composer.json sieht so aus (da habe ich nichts geändert):

    PHP-Code:
    {
        
    "name""contao/managed-edition",
        
    "type""project",
        
    "description""Contao Managed Edition",
        
    "license""LGPL-3.0-or-later",
        
    "require": {
            
    "contao/conflicts""*@dev",
            
    "contao/manager-bundle""4.9.*",
            
    "contao/news-bundle""^4.9",
            
    "madeyourday/contao-rocksolid-custom-elements""^2.3",
            
    "terminal42/contao-easy_themes""^2.2"
        
    },
        
    "conflict": {
            
    "contao-components/installer""<1.3"
        
    },
        
    "extra": {
            
    "contao-component-dir""assets"
        
    },
        
    "scripts": {
            
    "post-install-cmd": [
                
    "Contao\\ManagerBundle\\Composer\\ScriptHandler::initializeApplication"
            
    ],
            
    "post-update-cmd": [
                
    "Contao\\ManagerBundle\\Composer\\ScriptHandler::initializeApplication"
            
    ]
        }

    Im Frontend sehe ich natürlich Test:, aber das Hallo Welt! wird nicht ausgegeben…

  13. #13
    Contao-Fan
    Registriert seit
    27.11.2009.
    Beiträge
    326

    Standard

    Guck mal hier:
    https://docs.contao.org/dev/framewor...t-end-modules/

    unter Annotations.

    PHP-Code:
    /**
     * @FrontendModule("my_example",
     *   category="miscellaneous", 
     *   template="mod_some_example",
     *   renderer="forward"
     * )
     */
    class ExampleController extends AbstractFrontendModuleController
    {

    Bei mir funktioniert es so.

    Wird Dein Modul im Backend korrekt angezeigt?

  14. #14
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    34.062
    Partner-ID
    10107

    Standard

    Ah, ich weiß schon was das Problem ist. Wenn man von Legacy Klassen extended, wird diese Klasse nicht mehr automatisch als Service registriert vom Contao Manager Bundle. Das heißt man braucht zB. doch folgende Anweisungen in der services.yaml: https://docs.contao.org/dev/getting-...es-and-actions
    » sponsor me via GitHub or PayPal or Revolut

  15. #15
    Contao-Nutzer Avatar von a-v-l
    Registriert seit
    20.09.2013.
    Ort
    Freiburg im Breisgau
    Beiträge
    88

    Standard

    Da ich ja ein vorhandenes Modul (wir bleiben bei ModuleNewsList) erweitern will, kann ich nicht den AbstractFrontendModuleController erweitern. Das würde bei einem neuen Modul vielleicht funktionieren. Aber ich will ja die Methoden der Elternklasse (ModuleNewsList) überschreiben.

    Was die Annotations angeht, macht es auch keinen Unterschied, ob ich da alles ausschreibe:

    PHP-Code:
    /**
     * @FrontendModule("app_example",
     *   category="news", 
     *   template="mod_newslist",
     *   renderer="forward"
     * )
     */
    class AppExampleController extends ModuleNewsList … 
    Wird Dein Modul im Backend korrekt angezeigt?
    In dem vorangegangenem Beispiel wird das Backend gar nicht einbezogen:

    PHP-Code:
        protected function compile()
        {
            
    $this->Template->hallo "Hallo Welt!";
            
    parent::compile();
        } 
    Ich versuche lediglich die Variable "hallo" ans Template zu übergeben – quasi als Proof-of-Concept. Scheint leider nicht zu funktionieren…

  16. #16
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    34.062
    Partner-ID
    10107

    Standard

    Zitat Zitat von a-v-l Beitrag anzeigen
    Da ich ja ein vorhandenes Modul (wir bleiben bei ModuleNewsList) erweitern will, kann ich nicht den AbstractFrontendModuleController erweitern.
    Musst du ja auch nicht. Dein Code passt so wie er ist, es fehlt nur die Service Registrierung, weil hier wie gesagt die automatische Service Registrierung des Contao Manager Bundle nicht funktioniert.

    // edit: habe das nun auch in der Dokumentation erwähnt: https://github.com/contao/docs/commi...52ec964998de5e
    Geändert von Spooky (10.09.2021 um 09:45 Uhr)
    » sponsor me via GitHub or PayPal or Revolut

  17. #17
    Contao-Fan
    Registriert seit
    27.11.2009.
    Beiträge
    326

    Standard

    Ich meinte nur die Annotations & hätte dann wohl den Rest nicht mitkopieren sollen..

    Aber warum braucht es dort (Annotations) keinen Namen des Moduls? (+ abweichendes Template, falls gebraucht)?

  18. #18
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    34.062
    Partner-ID
    10107

    Standard

    Zitat Zitat von tlnewbie Beitrag anzeigen
    Aber warum braucht es dort (Annotations) keinen Namen des Moduls? (+ abweichendes Template, falls gebraucht)?
    Das ist alles optional (siehe auch die Doku dazu).
    » sponsor me via GitHub or PayPal or Revolut

  19. #19
    Contao-Nutzer Avatar von a-v-l
    Registriert seit
    20.09.2013.
    Ort
    Freiburg im Breisgau
    Beiträge
    88

    Standard

    Zitat Zitat von Spooky Beitrag anzeigen
    Ah, ich weiß schon was das Problem ist. Wenn man von Legacy Klassen extended, wird diese Klasse nicht mehr automatisch als Service registriert vom Contao Manager Bundle. Das heißt man braucht zB. doch folgende Anweisungen in der services.yaml: https://docs.contao.org/dev/getting-...es-and-actions
    1. Frage: Wie finde ich heraus, ob eine Klasse eine Legacy-Klasse ist?

    2. Frage: Warum wird in dem Beispiel auf https://docs.contao.org/dev/guides/f...t-controllers/ dann eine Legacy-Klasse mit Annotations angegeben – was ja nicht funktioniert…

    3. Frage: Warum läuft es immer noch nicht?

    Ich habe nun noch diese Dateien angelegt und sogar die composer.json angepasst (obwohl das in Contao 4.9 ja eigentlich nicht unbedingt nötig sein sollte):

    Code:
    # config/services.yaml
    services:
        _defaults:
            autowire: true
            autoconfigure: true
            public: false
    
        App\:
            resource: ../src
            exclude: ../src/{Entity,Migrations,Model,Resources,Tests,Widget}
        
        App\Controller\:
            resource: ../src/Controller
            public: true
    Zusätzlich habe ich auch noch diese Angabe mit ausprobiert (in der services.yaml):

    Code:
        App\Controller\FrontendModule\AppExampleController:
            tags:
                -
                    name: contao.frontend_module
                    category: news
    Dann die routes.yaml:

    Code:
    # config/routes.yaml
    app.controller:
        resource: ../src/Controller
        type: annotation
    Und in die composer.json:

    PHP-Code:
        "autoload": {
            
    "psr-4": {
                
    "App\\""src/"
            
    }
        } 
    Macht leider alles kein Unterschied… Wenn ich $this->Template->hallo = "Hallo Welt!"; direkt in die /vendor/contao/news-bundle/src/Resources/contao/modules/ModuleNewsList.php reinschreibe, wird es natürlich richtig angezeigt…

  20. #20
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    34.062
    Partner-ID
    10107

    Standard

    Zitat Zitat von a-v-l Beitrag anzeigen
    1. Frage: Wie finde ich heraus, ob eine Klasse eine Legacy-Klasse ist?
    Alle Klassen, die direkt im \Contao\ Namespace liegen im Prinzip.



    Zitat Zitat von a-v-l Beitrag anzeigen
    2. Frage: Warum wird in dem Beispiel auf https://docs.contao.org/dev/guides/f...t-controllers/ dann eine Legacy-Klasse mit Annotations angegeben – was ja nicht funktioniert…
    Doch, natürlich funktioniert das.



    Zitat Zitat von a-v-l Beitrag anzeigen
    Ich habe nun noch diese Dateien angelegt und sogar die composer.json angepasst (obwohl das in Contao 4.9 ja eigentlich nicht unbedingt nötig sein sollte):
    composer.json musst du nicht anpassen.



    Zitat Zitat von a-v-l Beitrag anzeigen
    Macht leider alles kein Unterschied… Wenn ich $this->Template->hallo = "Hallo Welt!"; direkt in die /vendor/contao/news-bundle/src/Resources/contao/modules/ModuleNewsList.php reinschreibe, wird es natürlich richtig angezeigt…
    All das alleine reicht ja noch nicht. Mit deinem Code erzeugst du ja ein neues Modul, mit eigener Palette etc. Du müsstest also noch die eigene Palette definieren und dein Modul im Backend entsprechend anlegen.
    Falls du das bestehende Nachrichtenlistenmodul (newslist) ersetzen willst, müsstest du noch den Typ mit angeben:
    Code:
    /**
     * @FrontendModule("newslist", category="news")
     */
    Das würde dann das bestehende Modul vom Typ "newslist" (also das Core Nachrichtenlistenmodul) mit deinem Modul überschreiben.
    » sponsor me via GitHub or PayPal or Revolut

  21. #21
    Contao-Nutzer Avatar von a-v-l
    Registriert seit
    20.09.2013.
    Ort
    Freiburg im Breisgau
    Beiträge
    88

    Standard

    Zitat Zitat von Spooky Beitrag anzeigen
    All das alleine reicht ja noch nicht. Mit deinem Code erzeugst du ja ein neues Modul, mit eigener Palette etc. Du müsstest also noch die eigene Palette definieren und dein Modul im Backend entsprechend anlegen.
    Falls du das bestehende Nachrichtenlistenmodul (newslist) ersetzen willst, müsstest du noch den Typ mit angeben:
    Code:
    /**
     * @FrontendModule("newslist", category="news")
     */
    Das würde dann das bestehende Modul vom Typ "newslist" (also das Core Nachrichtenlistenmodul) mit deinem Modul überschreiben.
    Ta-Da! Funktioniert! Vielen Dank!

    Das sollte aber dann unbedingt in die Docu: https://docs.contao.org/dev/guides/f...existing-class
    Dort steht nämlich nur @FrontendModule(category="news"). Ich bereite gleich mal ein Pull Request vor!

  22. #22
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    34.062
    Partner-ID
    10107

    Standard

    Zitat Zitat von a-v-l Beitrag anzeigen
    Das sollte aber dann unbedingt in die Docu: https://docs.contao.org/dev/guides/f...existing-class
    Dort steht nämlich nur @FrontendModule(category="news"). Ich bereite gleich mal ein Pull Request vor!
    Hold your horses . Die Doku zeigt nur, wie du ein Legacy Modul als Fragment extenden könntest. Ob du damit aber ein neues Modul machen willst oder das bestehende Modul quasi ersetzen willst, kommt auf deinen Use-Case an.
    Geändert von Spooky (10.09.2021 um 10:21 Uhr)
    » sponsor me via GitHub or PayPal or Revolut

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

Lesezeichen

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •