Contao-Camp 2024
Ergebnis 1 bis 21 von 21

Thema: Back End Routes / Module

  1. #1
    Contao-Nutzer
    Registriert seit
    09.03.2020.
    Beiträge
    32

    Standard Back End Routes / Module

    Moin,
    ich bin gerade dabei und möchte ein neues Module im Backend von Contao hinzufügen. Habe hierfür die Dokumentation abgearbeitet (https://docs.contao.org/dev/guides/backend-routes/).
    Jedoch heißt es nun von wegen
    None of the chained routers were able to generate route: Route 'app.backend-route' not found
    Woran kann dies liegen?

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

    Standard

    Arbeitest du im Debug-Modus? Wenn nicht, hast du ein composer install gemacht? Wenn doch: poste deinen Code.

  3. #3
    Contao-Nutzer
    Registriert seit
    09.03.2020.
    Beiträge
    32

    Standard

    Zitat Zitat von Spooky Beitrag anzeigen
    Arbeitest du im Debug-Modus? Wenn nicht, hast du ein composer install gemacht? Wenn doch: poste deinen Code.
    Composer install gemacht. Nichts geändert. Ich arbeite nicht im Debug Modus, weiß nicht wie man in den Debug Mode kommt ohne das Backend.

    src/Controller/BackendController.php
    PHP-Code:
    <?php

    namespace App\Controller;

    use 
    Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
    use 
    Symfony\Component\Routing\Annotation\Route;
    use 
    Symfony\Component\HttpFoundation\Response;
    use 
    Twig\Environment as TwigEnvironment;

    /**
    * @Route("/contao/my-backend-route",
    *     name=App\Controller\BackendController::class,
    *     defaults={
    *         "_scope" = "backend",
    *         "_token_check" = true,
    *         "_backend_module" = "my-module"
    *     }
    * )
    */
    class BackendController extends AbstractController
    {
    private 
    $twig;

    public function 
    __construct(TwigEnvironment $twig)
    {
    $this->twig $twig;
    }

    public function 
    __invoke()
    {
    return new 
    Response($this->twig->render(
    'my_backend_route.html.twig',
    []
    ));
    }
    }
    config/routing.yml
    Code:
    app.controller:
      resource: '../src/Controller'
      type: annotation
    templates/my_backend_route.html.twig
    Code:
    {% extends "@ContaoCore/Backend/be_page.html.twig" %}
    
    {% block headline %}
        Not only the content of the `title`-tag but also the title of the content section.
    {% endblock %}
    
    {% block error %}
        Will be placed within the error block.
    {% endblock %}
    
    {% block main %}
        <div class="tl_listing_container">
            Main Content.
        </div>
    {% endblock %}

    src/EventListener/BackendMenuListener.php
    PHP-Code:
    <?php
    namespace App\EventListener;

    use 
    Contao\CoreBundle\Event\MenuEvent;
    use 
    Symfony\Component\HttpFoundation\RequestStack;
    use 
    Symfony\Component\Routing\RouterInterface;

    class 
    BackendMenuListener
    {
        protected 
    $router;
        protected 
    $requestStack;

        public function 
    __construct(RouterInterface $routerRequestStack $requestStack)
        {
            
    $this->router $router;
            
    $this->requestStack $requestStack;
        }

        public function 
    onBuild(MenuEvent $event): void
        
    {
            
    $factory $event->getFactory();
            
    $tree $event->getTree();

            if (
    'mainMenu' !== $tree->getName()) {
                return;
            }

            
    $contentNode $tree->getChild('content');

            
    $node $factory
                
    ->createItem('my-modules')
                ->
    setUri($this->router->generate('app.backend-route'))
                ->
    setLabel('My Modules')
                ->
    setLinkAttribute('title''Title')
                ->
    setLinkAttribute('class''my-modules')
                ->
    setCurrent($this->requestStack->getCurrentRequest()->get('_backend_module') === 'my-modules');

            
    $contentNode->addChild($node);
        }
    }
    config/services.yml
    Code:
    services:
      App\EventListener\BackendMenuListener:
        arguments:
          - "@router"
          - "@request_stack"
        tags:
          - { name: kernel.event_listener, event: contao.backend_menu_build, method: onBuild, priority: -255 }

    Verzeichnis.PNG

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

    Standard

    Da war noch ein Fehler in der Dokumentation. Ist nun behoben: https://github.com/contao/docs/commi...229055c9add2d8


    Zitat Zitat von JLN Beitrag anzeigen
    Ich arbeite nicht im Debug Modus, weiß nicht wie man in den Debug Mode kommt ohne das Backend.
    Über den Contao Manager oder, wenn du Lokal arbeitest, über die .env bzw. .env.local
    Siehe https://docs.contao.org/manual/de/sy...4-8-und-hoeher

  5. #5
    Contao-Nutzer
    Registriert seit
    09.03.2020.
    Beiträge
    32

    Standard

    Zitat Zitat von Spooky Beitrag anzeigen
    Da war noch ein Fehler in der Dokumentation. Ist nun behoben: https://github.com/contao/docs/commi...229055c9add2d8


    Über den Contao Manager oder, wenn du Lokal arbeitest, über die .env bzw. .env.local
    Siehe https://docs.contao.org/manual/de/sy...4-8-und-hoeher
    Ok das hat soweit funktioniert, jedoch sobald ich nun das Module auswähle in dem Menü:
    Code:
    The controller for URI "/contao/my-backend-route" is not callable. Controller "App\Controller\BackendController" has required constructor arguments and does not exist in the container. Did you forget to define the controller as a service?

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

    Standard

    Hm, einen Fehler habe ich noch in der Doku gefunden: https://github.com/contao/docs/commi...3973bdd641406b
    Hat aber nichts mit deinem Fehler zu tun.

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

    Standard

    Ändere deine services.yml mal auf folgendes:
    Code:
    services:
        _defaults:
            autowire: true
            autoconfigure: true
            public: false
    
        App\:
            resource: ../src
            exclude: ../src/{Entity,Migrations,Resources,Model,Tests}
        
        App\Controller\:
            resource: ../src/Controller
            public: true
    
        App\EventListener\BackendMenuListener:
            tags:
                - { name: kernel.event_listener, event: contao.backend_menu_build, method: onBuild, priority: -255 }

  8. #8
    Contao-Nutzer
    Registriert seit
    09.03.2020.
    Beiträge
    32

    Standard

    Zitat Zitat von Spooky Beitrag anzeigen
    Ändere deine services.yml mal auf folgendes:
    Code:
    services:
        _defaults:
            autowire: true
            autoconfigure: true
            public: false
    
        App\:
            resource: ../src
            exclude: ../src/{Entity,Migrations,Resources,Model,Tests}
        
        App\Controller\:
            resource: ../src/Controller
            public: true
    
        App\EventListener\BackendMenuListener:
            tags:
                - { name: kernel.event_listener, event: contao.backend_menu_build, method: onBuild, priority: -255 }

    Das Problem wurde behoben, jedoch wird das neue Module nicht als "active" angezeigt in der Navigationsleiste.

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

  10. #10
    Contao-Nutzer
    Registriert seit
    09.03.2020.
    Beiträge
    32

    Standard

    Perfekt, danke vielmals!

    Im $GLOBALS['BE_MOD']-Array befindet sich nun jedoch nicht mein neuer Menüeintrag. Wie füg ich den hinzu bzw. ist es überhaupt notwendig/relevant?

    Wenn ich nun eine komplett neue Kategorie erstellen möchte, müsste ich lediglich den 'BE_MOD'-Array erweitern, richtig?
    Code:
    $GLOBALS['BE_MOD']['new-category']
    Und dann bei BackendMenuListener folgendes:
    Code:
    $contentNode = $tree->getChild('new-cateogry');

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

    Standard

    Das sollte nicht notwendig sein. Du solltest in der Lage sein den Tree dort entsprechend zu ändern.

  12. #12
    Contao-Nutzer
    Registriert seit
    09.03.2020.
    Beiträge
    32

    Standard

    Zitat Zitat von Spooky Beitrag anzeigen
    Das sollte nicht notwendig sein. Du solltest in der Lage sein den Tree dort entsprechend zu ändern.
    Wo meinst du genau, dass ich den Tree ändern kann?

    Und wie kann ich mein Template ein Stylesheet zuweisen? (Wollte Bootstrap implementieren). Mein Template "extends" aktuell von der be_page.html.twig, jedoch befindet sich dort kein Block für die Stylesheets/JS.

    Grüße

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

    Standard

    Stylesheets kannst du mit
    PHP-Code:
    $GLOBALS['TL_CSS'][] = '…'
    in deinem Controller hinzufügen lassen.

  14. #14
    Contao-Nutzer
    Registriert seit
    09.03.2020.
    Beiträge
    32

    Standard

    Zitat Zitat von Spooky Beitrag anzeigen
    Stylesheets kannst du mit
    PHP-Code:
    $GLOBALS['TL_CSS'][] = '…'
    in deinem Controller hinzufügen lassen.
    Ich möchte meinem neuen BE-Module nun ein neues Model zuweisen. Hab die Dokumentation dazu verfolgt und das Model auch in der DCA registriert.
    Muss ich die DB-Tabelle jetzt noch von Hand anlegen?

    Grüße
    Geändert von JLN (17.03.2020 um 15:33 Uhr)

  15. #15
    Contao-Nutzer
    Registriert seit
    30.07.2015.
    Beiträge
    140

    Standard

    Zitat Zitat von JLN Beitrag anzeigen
    Moin,
    ich bin gerade dabei und möchte ein neues Module im Backend von Contao hinzufügen. Habe hierfür die Dokumentation abgearbeitet (https://docs.contao.org/dev/guides/backend-routes/).
    funktioniert das Beispiel aus der Doku nicht bei einer 4.13 Installation? Dort bekomme ich immer den Routing-Fehler:

    HTML-Code:
    An exception has been thrown during the rendering of a template ("None of the chained routers were able to generate route: Route 'MeinBundle\Controller\BackendController' not found, Route 'Route 'MeinBundle\Controller\BackendController' not found' not found").
    obwohl ich das 1:1 übernommen habe. Natürlich sind die Namespaces entsprechend angepasst.
    Wir sind Contao-Sponsor :-)

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

    Standard

    Poste den gesamten Code deines Bundles.
    » sponsor me via GitHub or PayPal or Revolut

  17. #17
    Contao-Nutzer
    Registriert seit
    30.07.2015.
    Beiträge
    140

    Standard

    src/Controller/BackendController.php

    PHP-Code:
    <?php

    declare(strict_types=1);

    namespace 
    KT\MyBundle\Controller;

    use 
    Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
    use 
    Symfony\Component\Routing\Annotation\Route;
    use 
    Symfony\Component\HttpFoundation\Response;
    use 
    Twig\Environment as TwigEnvironment;

    /**
     * @Route("%contao.backend.route_prefix%/my-backend-route",
     *     name=BackendController::class,
     *     defaults={"_scope": "backend"}
     * )
     */
    class BackendController extends AbstractController
    {
        private 
    $twig;
        
        public function 
    __construct(TwigEnvironment $twig)
        {
            
    $this->twig $twig;
        }

        public function 
    __invoke(): Response
        
    {
            return new 
    Response($this->twig->render(
                
    'my_backend_route.html.twig'
                []
            ));
        }
    }
    src/EventListener/BackendMenuListener.php

    PHP-Code:
    <?php

    namespace KT\MyBundle\EventListener;

    use 
    KT\MyBundle\Controller\BackendController;
    use 
    Contao\CoreBundle\Event\MenuEvent;
    use 
    Symfony\Component\HttpFoundation\RequestStack;
    use 
    Symfony\Component\Routing\RouterInterface;

    class 
    BackendMenuListener
    {
        protected 
    $router;
        protected 
    $requestStack;

        public function 
    __construct(RouterInterface $routerRequestStack $requestStack)
        {
            
    $this->router $router;
            
    $this->requestStack $requestStack;
        }

        public function 
    onBuild(MenuEvent $event): void
        
    {
            
    $factory $event->getFactory();
            
    $tree $event->getTree();

            if (
    'mainMenu' !== $tree->getName()) {
                return;
            }

            
    $contentNode $tree->getChild('content');

            
    $node $factory
                
    ->createItem('my-module')
                    ->
    setUri($this->router->generate(BackendController::class))
                    ->
    setLabel('My Modules')
                    ->
    setLinkAttribute('title''Title')
                    ->
    setLinkAttribute('class''my-module')
                    ->
    setCurrent($this->requestStack->getCurrentRequest()->get('_controller') === BackendController::class)
            ;

            
    $contentNode->addChild($node);
        }
    }
    src/Resources/config/routing.yml

    PHP-Code:
    app:
        
    resource: ../../Controller
        type
    annotation 
    src/Resources/config/services.yml

    PHP-Code:
    services:
        
    _defaults:
            
    autoconfiguretrue
            autowire
    true

        KT
    \MyBundle\EventListener\BackendMenuListener:
            
    arguments:
                - 
    "@router"
                
    "@request_stack"
            
    tags:
                - { 
    namekernel.event_listenereventcontao.backend_menu_buildmethodonBuildpriority: -255 
    das Template liegt in src/Resources/contao/templates/my_backend_route.html.twig

    Ich habe in dem Bundle noch Cronjobs usw. d.h. der Rest funktioniert. Oder soll ich zwingend alles posten?
    Geändert von paddibr (01.11.2022 um 11:00 Uhr)
    Wir sind Contao-Sponsor :-)

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

    Standard

    %contao.backend.route_prefix% beinhaltet bereits den Leading Slash, du hast in deiner Route aber nochmal einen Leading Slash, wodurch die Route dann vermutlich //contao/my-backend-route statt /contao/my-backend-route lautet. Dies kannst du auch über debug:router prüfen.
    » sponsor me via GitHub or PayPal or Revolut

  19. #19
    Contao-Nutzer
    Registriert seit
    30.07.2015.
    Beiträge
    140

    Standard

    stimmt. Vor lauter rum probieren ist das davor gelandet. Habe es gerade weg genommen und immer noch die Exception :-/

    Die Route ist auch nicht unter debug:router aufgelistet.
    Wir sind Contao-Sponsor :-)

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

    Standard

    Dann musst du noch den Rest deines Codes posten (bspw. wie lässt du deine routing.yaml laden?).
    » sponsor me via GitHub or PayPal or Revolut

  21. #21
    Contao-Nutzer
    Registriert seit
    30.07.2015.
    Beiträge
    140

    Standard

    src/ContaoManager/Plugin.php

    PHP-Code:
    <?php

    declare(strict_types=1);

    namespace 
    KT\MyBundle\ContaoManager;

    use 
    Contao\CoreBundle\ContaoCoreBundle;
    use 
    Contao\ManagerPlugin\Bundle\BundlePluginInterface;
    use 
    Contao\ManagerPlugin\Bundle\Config\BundleConfig;
    use 
    Contao\ManagerPlugin\Bundle\Parser\ParserInterface;
    use 
    KT\MyBundle\MyBundle;
    use 
    Symfony\Component\Config\Loader\LoaderResolverInterface;
    use 
    Symfony\Component\HttpKernel\KernelInterface;
    use 
    Symfony\Component\Routing\RouteCollection;

    class 
    Plugin implements BundlePluginInterface {

        
    /**
         * {@inheritdoc}
         */
        
    public function getBundles(ParserInterface $parser): array
        {
            return [
                
    BundleConfig::create(MyBundle::class)
                    ->
    setLoadAfter([ContaoCoreBundle::class]),
            ];
        }

        
    /**
         * {@inheritdoc}
         */
        
    public function getRouteCollection(LoaderResolverInterface $resolverKernelInterface $kernel): ?RouteCollection
        
    {
            return 
    $resolver
                
    ->resolve(__DIR__ '/../Resources/config/routing.yml')
                ->
    load(__DIR__ '/../Resources/config/routing.yml')
            ;
        }
    }
    src/DependencyInjection/MyBundleExtension.php

    PHP-Code:
    <?php

    declare(strict_types=1);

    namespace 
    KT\MyBundle\DependencyInjection;

    use 
    Symfony\Component\Config\FileLocator;
    use 
    Symfony\Component\DependencyInjection\ContainerBuilder;
    use 
    Symfony\Component\DependencyInjection\Extension\Extension;
    use 
    Symfony\Component\DependencyInjection\Loader\YamlFileLoader;

    class 
    MyBundleExtension extends Extension
    {
        public function 
    load(array $configsContainerBuilder $container): void
        
    {
            
    $loader = new YamlFileLoader($container, new FileLocator(__DIR__ '/../Resources/config'));
            
    $loader->load('services.yml');
            
    $loader->load('listeners.yml');
        }
    }
    und eine listerns.yml habe ich noch:

    PHP-Code:
    services:
        
    _defaults:
            
    autowiretrue 
    EDIT: Mist, mir fehlte das entsprechende Interface in der Plugin.php. Und das Twig-Template benötigt noch min. den Namespace @Contao.
    Geändert von paddibr (02.11.2022 um 07:53 Uhr)
    Wir sind Contao-Sponsor :-)

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
  •