Ankündigung

Einklappen
Keine Ankündigung bisher.

Symfony Routing Prefix

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Symfony Routing Prefix

    Moin,

    kann man einem globalen Symfony (3.4) Routing-Prefix (Annotation) einen Default-Value null oder notfalls einen leeren String mitgeben?

    Ich habe es bislang nicht zum Laufen bekommen und auch über Google / Stackoverflow keine hilfreichen Antworten gefunden, dort haben die Beispiele zwar alle einen Default-Value, aber der Fall null wird nicht abgedeckt (auch nicht in der Symfony-Doku).

    Zur Verdeutlichung hier ein einfaches Beispiel einer Annotation eines Controllers, der einen optionalen Parameter mit den 3 möglichen Werten one, two, three und eben null entgegennimmt und in allen 4 Fällen die Controller-Methode ausführt:

    PHP-Code:
    /**
     * @Route("/{param}", name="route_name", requirements={"param": "one|two|three"})
     *
     * @param Request $request
     * @param string  $param
     *
     * @return Response
     */
    public function exampleAction(Request $request$param null) {
        ...

    Ist so etwas für einen globalen Routing-Prefix möglich?


  • #2
    Du kannst einer Action auch mehrere Routen zuweisen:
    PHP-Code:
    /**
     * @Route("/{param}", requirements={"param": "one|two|three"})
     * @Route("/")
     *
     * @param Request $request
     * @param string  $param
     *
     * @return Response
     */
    public function exampleAction(Request $request$param null) {
        ...

    Oder meinst du als Prefix für die ganze Klasse, dann kannst du die Route Annotation einfach über die Klasse schreiben, dann wird diese als Prefix für deine Methoden in der Klasse genommen.

    Kommentar


    • #3
      Hi, dank dir für deine Antwort.

      Wie es für die ganze Klasse eines Controllers funktioniert ist mir bekannt.

      Ich meine einen globalen Prefix in der routing.yml an der Stelle wo auf das Verzeichnis der Controller eines Bundles verwiesen wird. Und dann - in meinem Fall ganz wichtig - muss dieser Prefix nullable sein, wie eben in meinem Beispiel für die einzelne Controller-Methode gezeigt.

      Im Endeffekt suche ich nach einer Lösung analog dazu wie bspw. Apple auf seiner Websites Locales einbindet. Ein Nullwert des URL-Parameters www.example.com/{locale}/ wird nicht angezeigt und liefert die Standardversion der Seite in Englisch aus, ein Wert in einer gültigen Locale wird hingegen angezeigt und liefert die Seite eben in der gewünschten Sprache aus.

      Um Missverständnissen vorzubeugen: Ich weiß selbst, wie man eine Symfony-App mehrsprachig gestaltet, mir geht es in dem Apple-Beispiel nur um die Veranschaulichung dessen, dass der Prefix null sein darf / kann.

      Kommentar


      • #4
        Wenn dein Routing mit dem Prefix bereits funktioniert, dann könntest du in der YAML Datei den "defaults" Parameter versuchen.

        Code:
        controllers:
            resource: '../src/Controller/'
            type: annotation
            prefix: '/{param}'
            defaults:
                param: null

        Kommentar


        • #5
          Genau das Setup aus deinem Beispiel hatte ich gestern versucht (plus Requirements).

          Wenn ich param mit einem Wert mitgebe, dann funktioniert es.

          Lasse ich param leer / null, dann liefert meine App nicht mehr die Startseite aus, sondern schmeißt einen 404er mit Symfony\Component\Routing\Exception\NoConfiguratio nException, und sagt dass keine Index-Route definiert wurde (No route found for "GET /"). Im Dev-Modus sieht man dann die Startseite, die auch nach einem frischem Setup einer Symfony-App Out of the box kommt.

          Kommentar


          • #6
            Wie sehen deine konkrete Requirements denn aus? Wenn du wirklich etwas requirements={"param": "one|two|three"} stehen hast, dann funktioniert es natürlich nicht. Du musst dort dann auch einen leeren Wert erlauben. Sprich dein RegEx müsste sagen
            "one,two,three" oder leer ist erlaubt.

            Kommentar


            • #7
              Ne, auch wenn ich die Requirements komplett weglasse funktioniert es nicht.

              Kommentar


              • #8
                Ich habe gerade selber noch mal die Dokumentation durchgelesen, da steht folgendes dazu:
                http://symfony.com/doc/current/routi...ceholders.html

                Of course, you can have more than one optional placeholder (e.g. /blog/{slug}/{page}), but everything after an optional placeholder must be optional. For example, /{page}/blog is a valid path, but page will always be required (i.e. simply /blog will not match this route).
                Um das jetzt also zu lösen, müsstest du meiner Meinung zwei Routen definieren. Einmal mit optionalen Prefix einmal ohne. Das könnte funktionieren, indem du in deiner routing.yaml einfach den Block kopierst und einmal mit prefix einmal ohne prefix anlegst. Wichtig dabei ist dann, dass du den Parameter name in deiner Annotation weglässt, damit dieser automatisch vergeben wird.

                Kommentar


                • #9
                  Ich habe es zwar noch nicht getestet, aber es sollte genau so funktionieren wie du es vorgeschlagen hast.

                  Die Access Control im Symfony-Security-System arbeitet zur Authentifizierung über die security.yml ja genauso, sie geht einfach alle Pfade von oben nach unten durch und nimmt den ersten, der matched. Ob man da nur einen oder fünf Admin-Pfade untereinander schreibt ist vollkommen egal, der matchende Admin-Pfad wird genommen.

                  Das sollte beim Routing ja genauso funktionieren, man kann ja genauso gut auch ohne Prefixing zwei identische Routen, die sich nur in der Anfrage-Methode, bspw. GET und POST unterscheiden, untereinander setzen und das Framework nimmt die, die matched.

                  Dank dir für deine Hilfe, ich habe das selbst nicht so aus der Doku rauslesen können bzw. vor lauter Verpeiltheit den oben beschriebenen Rückschluss nicht mehr ziehen können .

                  Kommentar


                  • #10
                    Hallo,

                    also das mit dem Default Wert klingt doch nach einem praktikablem Weg, findest du nicht? Denn wenn null übergeben wird, dann ist der Wert immer der Default Wert und das kann man mit einem if prüfen.

                    Außerdem finde ich dein Use Case ist nicht ganz richtig. Eine Sprachschlüssel ist meistens kein Prefix, sondern irgendwo im URL ein Unterpfad. Also z. B. so hier:
                    www.example.com/article/de/1
                    und www.example.com/article/1 würde dann auf die Fallback-Sprache verweisen.

                    Edit: ich vergas, leere Teile matchen deinen URL ja nicht. Packe doch einfach einen von den Slashes mit in den Paramter hinein, sodass so dort steht:
                    PHP-Code:
                    /**
                     * @Route("article{param}{id}", name="route_name", requirements={"param": "\/one|\/two|\/three", "id": "\d+"})
                     *
                     * @param Request $request
                     * @param string  $param
                     *
                     * @return Response
                     */
                    public function exampleAction(Request $request$param null$id) {
                        ...


                    MFG

                    derwunner

                    Kommentar


                    • #11
                      Es ging nicht um die Konfiguration einer einzelnen Controller-Methode, sondern um Prefixing, um alle Controller-Methoden eines Projektes effizient mit einem Parameter in der URL auszustatten.

                      Inwiefern ist der Ansatz des Prefixings dazu falsch? Genau dafür gibt es doch Prefixes. Man sollten so einen globalen "App-Parameter" imho sicher nicht a) über jede Controller-Methode, b) über jeden Controller oder über c) einen Event-Listener zwischen Host und Rest des Pfades der URL schreiben. Alles Möglichkeiten, die über die Doku oder Stackoverflow zu finden sind, aber imho auch alles zu umständlich.

                      Den Parameter nur einmal zu Beginn zu ziehen und in Session oder Cookie zu schreiben irritiert den User, da sich die App dauerhaft anders verhält (Sprache), dies aber nicht dauerhaft über die URL kenntlich wird - steht zum Locale-Prefixing grundsätzlich so in den Google Best Practices, ebenso wie dass Subdomains zu vermeiden sind.

                      Konkret ging es darum, dass die routing.yml in meinem Use-Case eben nicht ganz genauso zu konfigurieren ist wie eine einzelne Controller-Methode oder ein einzelner Controller über Annotations (siehe Posts 1. und 3.). Da es für eine einzelne Methode oder einen einzelnen Controller ja genau so funktioniert wie gewünscht, aber eben nicht global über die routing.yml.

                      Kommentar


                      • #12
                        Zitat von wario Beitrag anzeigen
                        Es ging nicht um die Konfiguration einer einzelnen Controller-Methode, sondern um Prefixing, um alle Controller-Methoden eines Projektes effizient mit einem Parameter in der URL auszustatten.

                        Inwiefern ist der Ansatz des Prefixings dazu falsch? Genau dafür gibt es doch Prefixes. Man sollten so einen globalen "App-Parameter" imho sicher nicht a) über jede Controller-Methode, b) über jeden Controller oder über c) einen Event-Listener zwischen Host und Rest des Pfades der URL schreiben. Alles Möglichkeiten, die über die Doku oder Stackoverflow zu finden sind, aber imho auch alles zu umständlich.

                        Den Parameter nur einmal zu Beginn zu ziehen und in Session oder Cookie zu schreiben irritiert den User, da sich die App dauerhaft anders verhält (Sprache), dies aber nicht dauerhaft über die URL kenntlich wird - steht zum Locale-Prefixing grundsätzlich so in den Google Best Practices, ebenso wie dass Subdomains zu vermeiden sind.

                        Konkret ging es darum, dass die routing.yml in meinem Use-Case eben nicht ganz genauso zu konfigurieren ist wie eine einzelne Controller-Methode oder ein einzelner Controller über Annotations (siehe Posts 1. und 3.). Da es für eine einzelne Methode oder einen einzelnen Controller ja genau so funktioniert wie gewünscht, aber eben nicht global über die routing.yml.
                        Ok, anhand diesen Posts verstehe ich nicht mehr, was du überhaupt willst. Erkläre das doch bitte mal genauer, was dein Ziel und was aktuell nicht geht. Am besten mit Beispielen.

                        Kommentar


                        • #13
                          Steht doch alles in diesem Thread.

                          Kommentar

                          Lädt...
                          X