Brett vorm Kopf? Kleinbuchstaben bei URLs

Dachte ich könnte so URLs in Kleinbuchstaben ausgeben, aber reagiert gar nicht:

{% set ServiceURL = seoUrl('frontend.navigation.page',{navigationId: data.id}) %}
{{ ServiceURL|lower }}

Übersehe ich etwas?

Die seoUrl wird seht wahrscheinlich ein Objekt und kein String sein.

Ne, die wird ja ganz normal angezeigt, nur eben nicht in Kleinbuchstaben. Bei einem Objekt sollte ja nichts angezeigt werden.

Konnte es in einer lokalen Dockware-Umgebung und auf einem Server (Mitwald) nachstellen.

Das ist irgendein Zeichensatz-Problem mit der Methode mb_strtolower, die von der Twig-Funktion aufgerufen wird. Scheinbar wird von seoUrl-Funktion irgendein anderer Zeichensatz zurückgegeben, daher werden die Sonderzeichen in der URL (z.B. /) nicht erkannt und die Umwandlung klappt nicht.

Übergebe ich z.B.

{% set ServiceURL = seoUrl('frontend.navigation.page',{navigationId: data.id}) %}
Klappt nicht: {{ ServiceURL|lower }}
Klappt: {{ 'http://domain/Test/'|lower }}

Ebenso funktioniert es, wenn ich hardcoded in der SeoUrlFunctionExtension eine URL als String zurückgebe:

public function seoUrl(string $name, array $parameters = []): string
    {
       
       return 'http://domain/Test/';
       // return $this->seoUrlReplacer->generate($name, $parameters);
    }

Habe es jetzt mal mit verschiedenen Workarounds versucht (z.B. convert_encoding - Documentation - Twig - The flexible, fast, and secure PHP template engine), aber bisher ohne Erfolg.

Ah ok, hatte schon kurz selber an mir gezweifelt.

Irgendwas passt in dem Fall an irgendeiner Stelle in der Kette der Funktions-/Filterbearbeitung in Twig/Symfony/Shopware nicht. Gebe ich folgendes an:

{% set ServiceURL = seoUrl('frontend.navigation.page',{navigationId: '018e56d3fdf776a081a44f2bfc7253aa'}) %}
{{ dump(ServiceURL) }}

erhalte wie erwartet ich einen String als Ausgabe

"http://localhost/Test/"

Wende ich einen Filter auf meine String-Rückgabe an

{{ dump(ServiceURL  |  split('/')) }}

würde ich folgendes erwarten:

array:3 [▼
  0 => "http:"
  1 => ""
  2 => "localhost"
  3 => "Test"
  4 => ""
]

Ausgegeben wird mir aber

array:3 [▼
  0 => "http://localhost/"
  1 => "navigation"
  2 => "018e56d3fdf776a081a44f2bfc7253aa"
]

Das wäre ja die rohe URL ohne SEO. Daher klappt wohl auch das lower nicht.

Warum sollte das nicht klappen, wenn das Ganze einfach nur ein String ist? In PHP würde das auch gehen. Ich kann das gegenwärtig (noch) nicht nachvollziehen.

Eigentlich ist/sollte es ein String sein - aber irgendwie auch doch nicht :wink:

Vielleicht habe ich morgen auf der Fahrt nach Duisburg mal Zeit und Laune die Kette der Funktions- und Filteraufrufe in Twig/Shopware mal genauer anzuschauen. Irgendwo lauert da der Fehler.

Wenn es ein String ist, dann klar, aber irgendwas stimmt da nicht. Interessanterweise bekomme ich folgendes bei einem upper (mit einer Produkt-URL)

"124C71D524604CCBAD6042EDCE3AC799/DETAIL/018E914BB26C72C2B72B31B047EDFC82#"

Die Twig-Funktion seoUrl soll einen String zurückgeben, aber das Verhalten passt vorne und hinten nicht…

class SeoUrlFunctionExtension extends AbstractExtension
{
    /**
     * @internal
     */
    public function __construct(
        private readonly RoutingExtension $routingExtension,
        private readonly SeoUrlPlaceholderHandlerInterface $seoUrlReplacer
    ) {
    }

    public function getFunctions(): array
    {
        return [
            new TwigFunction('seoUrl', $this->seoUrl(...), ['is_safe_callback' => $this->routingExtension->isUrlGenerationSafe(...)]),
        ];
    }

    public function seoUrl(string $name, array $parameters = []): string
    {
        return $this->seoUrlReplacer->generate($name, $parameters);
    }
}

und seoUrlReplacer->generate gibt einen String zurück, allerdings nicht den, den man erwarten würde…

    final public const DOMAIN_PLACEHOLDER = '124c71d524604ccbad6042edce3ac799';

    /**
     * @param string $name
     */
    public function generate($name, array $parameters = []): string
    {
        $path = $this->router->generate($name, $parameters, RouterInterface::ABSOLUTE_PATH);

        $request = $this->requestStack->getMainRequest();
        $basePath = $request ? $request->getBasePath() : '';
        $path = $this->removePrefix($path, $basePath);

        return self::DOMAIN_PLACEHOLDER . $path . '#';
    }

man beachte den DOMAIN_PLACEHOLDER, das erklärt die upper-URL oben

Nachtrag: Ich habe ja den Verdacht, das die URL nachträglich per JS umgewandelt wird, kann das sein?

Wenn ich das jetzt richtig interpretiere.

  1. Die Twig-Funktion seoUrl gibt die Zeichenkette self::DOMAIN_PLACEHOLDER . $path . '#' zurück
  2. Alle Filter/etc. greifen auf diese Zeichenkette
  3. Am Ende läuft über den ganzen Content noch die Funktion SeoUrlPlaceholderHandler::replace drüber, die die richtige, contextabhhängige URL austauscht

Zum Ausgangsproblem zurück @R4M: Um das gewünschte Ergebnis zu erzielen, musst du die Klasse SeoUrlPlaceholderHandler::replace (die zumindest public ist) überschreiben und dort die Kleinschreibung erzwingen. Über einen einfachen Filter ist es in dem Fall leider nicht möglich.

Hast Du eine Idee, warum man das so macht und nicht direkt die URL zurückgibt? Hat das was mit dem Caching zu tun?

Bevor ich jetzt noch Tage damit verbringe nach einer Lösung zu suchen, habe ich nun die URLs händisch eingetragen und auf diese Funktion verzichtet. Für mich ist das Thema somit erledigt. Danke aber für das Feedback!

1 „Gefällt mir“

Es geht nur um die Kleinschreibung? Warum passt du nicht einfach das SEO-Template an?

In diesem Fall ja damit das einheitlich und sauber aussieht.

Du kennst jetzt nicht die Hintergründe, aber das ging hier nicht. Will ich jetzt auch nicht weiter erläutern und ausbauen. Ich muss bei den Projekten vorwärts kommen und will mich damit nicht länger befassen :slight_smile:

Also mich würds mal interessieren in welchem Use-Case die SEO URL Templates nicht zum gewünschten Ergebnis führen. Alles andere macht doch garkeinen Sinn.

Du kannst den SeoUrlPlaceholderHandler neu Dekorieren/ersetzen, weil der Service auf ein Interface basiert. Aber auch in diesem Fall wären auch alle URLs klein → Selbes Resultat also.

Und wenn du die URL mit kleinen Buchstaben in die Browseradresse eingibst, wird eh auf die URL mit den großen Buchstaben umgeleitet :smiley:

Dieses Thema wurde automatisch 30 Tage nach der letzten Antwort geschlossen. Es sind keine neuen Antworten mehr erlaubt.