Contao-Camp 2024
Ergebnis 1 bis 7 von 7

Thema: Eigenes Content Element mit Service Tagging als Fragment Controller

  1. #1
    Contao-Fan Avatar von Arno
    Registriert seit
    11.12.2009.
    Ort
    Potsdam-Babelsberg
    Beiträge
    290

    Standard Eigenes Content Element mit Service Tagging als Fragment Controller

    Liebes Forum,

    ich brauche eure Hilfe. Ich doktore hier gefühlt seit Tagen daran herum endlich mal ein eigenes Content Element nach der im Titel angegebenen Vorgehensweise zu erstellen.
    Ich habe mich an der Anleitung https://docs.contao.org/dev/framework/content-elements/ orientiert, wobei ich es in meinem Fall als eigenes Bundle angelegt habe. Aber das ist glaube ich nicht die Ursache meines Problems.

    Soweit ich das beurteilen kann bin ich glaube ich schon recht weit gekommen. Sprich: Die Dependency Injection funktioniert, services.yml wird verarbeitet, ich kann das Element im Backend anlegen, die Benennung aus der Sprachdatei wird korrekt verwendet, DCA Definition erscheint wie gewünscht. Nur beim Aufruf einer Seite im Frontend auf der ich das Element platziert habe, bekomme ich dann immer folgende Fehlermeldung:

    Code:
    The controller for URI "/notizen.html" is not callable. Method "getResponse" on class "Arno1979\GridBreak\ContentElement\GridBreak" should be public and non-abstract.
    Zum besseren Verständnis hier mal der relevante Code:

    #src/Resources/config/services.yml
    PHP-Code:
    services:
        
    _instanceof:
            
    Contao\CoreBundle\Framework\FrameworkAwareInterface:
                
    calls:
                    - [
    "setFramework", ["@contao.framework"]]

            
    Symfony\Component\DependencyInjection\ContainerAwareInterface:
                
    calls:
                    - [
    "setContainer", ["@service_container"]]

        
    arno1979.gridbreak.ce.gridbreak:
          class: 
    Arno1979\GridBreak\ContentElement\GridBreak
          tags
    :
              - 
                
    namecontao.content_element
                category
    texts
                method
    getResponse
                type
    ce_grid_break 
    #src/ContentElement/GridBreak.php
    PHP-Code:
    <?php

    namespace Arno1979\GridBreak\ContentElement;

    use 
    Contao\ContentModel;
    use 
    Contao\CoreBundle\Controller\ContentElement\AbstractContentElementController;
    use 
    Contao\CoreBundle\ServiceAnnotation\ContentElement;
    use 
    Contao\Template;
    use 
    Symfony\Component\HttpFoundation\Request;
    use 
    Symfony\Component\HttpFoundation\Response;

    class 
    GridBreak extends AbstractContentElementController
    {
        protected function 
    getResponse(Template $templateContentModel $modelRequest $request): ?Response
        
    {
            return 
    $template->getResponse();
        }
    }
    Die Ausgabe von
    Code:
    vendor/bin/contao-console debug:container grid
    ergibt folgendes:
    PHP-Code:
    Information for Service "arno1979.gridbreak.ce.gridbreak"
    =========================================================

     ---------------- ------------------------------------------------------------------------------------ 
      
    Option           Value                                                                               
     
    ---------------- ------------------------------------------------------------------------------------ 
      
    Service ID       arno1979.gridbreak.ce.gridbreak                                                     
      
    Class            Arno1979\GridBreak\ContentElement\GridBreak                                         
      Tags             contao
    .content_element (categorytextsmethodgetResponsetypece_grid_break)  
      
    Calls            setFragmentOptions                                                                  
      
    Public           yes                                                                                 
      Synthetic        no                                                                                  
      Lazy             no                                                                                  
      Shared           yes                                                                                 
      
    Abstract         no                                                                                  
      Autowired        no                                                                                  
      Autoconfigured   no                                                                                  
     
    ---------------- ------------------------------------------------------------------------------------ 
    Ich bin für jede Hilfe dankbar. Mir fehlt glaube ich einfach noch der Durchblick bei der ganzen Symfony Services Geschichte. Ist einfach so anders als es früher war und die dahinter liegende Logik erschließt sich mir einfach nicht vollständig. Mir ist z.B. überhaupt nicht klar nach welchem Muster die Service ID in der services.yml vergeben werden sollte und ob das überhaupt notwendig ist. Ich habe auch Beispiele gesehen in denen für die Angabe der tags Parameter einfach der Klassenname unter Berücksichtigung des Namespaces verwendet wurde. Der class Parameter fiel dann einfach weg. Die Variante habe ich übrigens natürlich auch probiert, aber das führt zum exakt gleichen Ergebnis.
    Cache ist übrigens immer brav geleert worden, bzw. ich arbeite eh mit dem Debug Modus.

    Danke!
    Arno

  2. #2
    Wandelndes Contao-Lexikon Avatar von BugBuster
    Registriert seit
    15.06.2009.
    Ort
    Berlin
    Beiträge
    10.494
    User beschenken
    Wunschliste

    Standard

    Code:
    The controller for URI "/notizen.html" is not callable. Method "getResponse" on class "Arno1979\GridBreak\ContentElement\GridBreak" should be public and non-abstract.
    Dann machen wir es doch public

    #src/Resources/config/services.yml
    PHP-Code:
    services:
        
    _instanceof:
            
    Contao\CoreBundle\Framework\FrameworkAwareInterface:
                
    calls:
                    - [
    "setFramework", ["@contao.framework"]]

            
    Symfony\Component\DependencyInjection\ContainerAwareInterface:
                
    calls:
                    - [
    "setContainer", ["@service_container"]]

        
    arno1979.gridbreak.ce.gridbreak:
          class: 
    Arno1979\GridBreak\ContentElement\GridBreak
          
    public: true
          tags
    :
              - 
                
    namecontao.content_element
                category
    texts
                method
    getResponse
                type
    ce_grid_break 
    Grüße, BugBuster
    "view source" is your guide.
    Danke an alle Amazon Wunschlisten Erfüller

  3. #3
    Contao-Fan Avatar von Arno
    Registriert seit
    11.12.2009.
    Ort
    Potsdam-Babelsberg
    Beiträge
    290

    Standard

    Zitat Zitat von BugBuster Beitrag anzeigen
    Dann machen wir es doch public
    Habe ich probiert, ändert nichts.
    Was mir aufgefallen war: Laut debug:container (siehe oben) ist der Service ohnehin public. Und wenn ich in der services.yml den Wert für public explizit auf false setze ändert das auch nichts, d.h. er bleibt immer public=yes.

  4. #4
    Wandelndes Contao-Lexikon Avatar von BugBuster
    Registriert seit
    15.06.2009.
    Ort
    Berlin
    Beiträge
    10.494
    User beschenken
    Wunschliste

    Standard

    na dann bleibt noch das
    PHP-Code:
    protected function getResponse(... 
    zu
    PHP-Code:
    public function getResponse(... 
    Grüße, BugBuster
    "view source" is your guide.
    Danke an alle Amazon Wunschlisten Erfüller

  5. #5
    Contao-Fan Avatar von Arno
    Registriert seit
    11.12.2009.
    Ort
    Potsdam-Babelsberg
    Beiträge
    290

    Standard

    Ja, klar, habe ich natürlich auch schon probiert.
    Das führt dann zu

    Code:
    Could not resolve argument $template of "arno1979.gridbreak.ce.gridbreak:getresponse()", maybe you forgot to register the controller as a service or missed tagging it with the "controller.service_arguments"?
    Wenn man sich die in meinem ersten Beitrag verlinkte Doku ansieht, ist ja eindeutig zu lesen, dass die Funktion getResponse protected sein soll. Sie leitet sich ja aus der abstrakten Funktion gleichen Namens in im AbstractContentElementController aus dem Core ab und übernimmt dann entsprechend auch die Argumente. In dem Augenblick wo ich sie public mache scheint das nicht mehr zu funktionieren. Deshalb glaube ich auch nicht, dass es jetzt der richtige Weg wäre in services.yml anzufangen die in der Fehlermeldung erwähnten controller.service_arguments zu setzen. Die sollten doch geerbt werden, wenn ich das richtig verstehe.

  6. #6
    Contao-Urgestein
    Registriert seit
    29.10.2009.
    Ort
    Magdeburg
    Beiträge
    2.020
    Partner-ID
    626
    User beschenken
    Wunschliste

    Standard

    Du brauchst in der Service Definition keine Methode anzugeben. Die Abstract Klasse hat eine __invoke Methode, die dann standardmäßig aufgerufen wird. GetResponse wird dann von der Methode aufgerufen.

  7. #7
    Contao-Fan Avatar von Arno
    Registriert seit
    11.12.2009.
    Ort
    Potsdam-Babelsberg
    Beiträge
    290

    Standard

    So, ich habs. webstars Hinweis traf zwar nicht genau den entscheidenden Punkt, hat mich aber dazu gebracht noch mal mit den Parametern method und type zu experimentieren. method kann in der Tat weg, vor allem wenn man (wie ich hier) ohnehin den gleichen Namen wie in der abstrakten Klasse verwendet.
    Das tatsächliche Problem lag aber darin begründet, dass ich den type Parameter auf ce_grid_break gesetzt hatte, weil ich irgendwie angenommen hatte damit den Template Namen festzulegen. Das ist aber natürlich Unsinn (der Parameter heisst ja auch nicht template!), sondern man legt halt den Content Element type fest. Und wenn man da ce_grid_break setzt sucht das System automatisch im DCA nach einem Elementtyp ce_ce_grid_break. Den gibt es aber natürlich nicht. Im Endeffekt bin ich irgendwann über die Fehlermeldung zu einem nicht gefundenen Template (der Templatename wird ja auch aus dem Klassennamen abgeleitet) drauf gekommen.

    Danke euch!

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
  •