🐞 Falsche URL bei Überage von Twig an JS mit seoUrl

Hallo,

ich will gern die SEO URL meines Produktes an ein JS Plugin weitergeben. Im Grunde ja nicht so schwierig, dachte ich :smiley:

Das ganze wollte ich Ă€hnlich wie in der Doku beschrieben ist, machen. Also als Json im data-options Attribut ĂŒbergeben. Dazu erstelle ich im Twig ein Objekt

    {% set options = {
        url: seoUrl('frontend.detail.page', { productId: product.id })
    } %}

soweit sogut, dass funktioniert auch. Wenn ich das dumpe dann erhalte ich, wie ich es erwarte:

{{ dump(options) }}
array:1 [▌
  "url" => "http://localhost:9998/Haupt-Product"
]

Um das ganze zu ĂŒbertragen muss das ganze noch mit json_encode umgewandelt werden. Aber nun sieht das ganze so hier aus

{{ dump(options|json_encode) }}
"{"url":"http://localhost:9998/\/detail\/f895e22ba1e446508d3c956c684c20ce"}"

Wie kann ich die seoUrl an mein Plugin ĂŒbertragen?

Ausehen sollte es so:

{% set options = {
    url: seoUrl('frontend.detail.page', { productId: product.id })
} %}

{% block page_product_detail_content %}
    {{ parent() }}

    <template data-example-plugin data-example-plugin-options='{{ options|json_encode }}'></template>
{% endblock %}

Das Beispiel hab ich aus der offizellen Doku von Shopware

Wird ganz normal in die options Variable geschrieben!

example.plugin.js

import Plugin from 'src/plugin-system/plugin.class';

export default class ExamplePlugin extends Plugin {
    static options = {
        url: null
    };

    ...
}

main.js

import ExamlePlugin from './example.plugin';

window.PluginManager.register('Example', ExamplePlugin , '[data-example-plugin]');

if (module.hot) {
    module.hot.accept();
}

@Moorleiche Jup genau danke, genau so wird das gemacht, dass stimmt. Nur ist das keine Lösung fĂŒr mein oben beschriebenes Problem, denn wenn ich im JS nun die URL aufrufen will, zb. mit

 init() {
        console.log(this.options.url)       
  }

kommt dummerweise
http://localhost:9998/detail/f895e22ba1e446508d3c956c684c20ce
raus.

Ich brauche aber die SEO Url, ich wĂŒrde gern die
http://localhost:9998/Haupt-Product

Ich hatte auf das JS verzichtet, da ich vermutete das hier im Entwicklerforum dump auch akzeptiert wird

Existiert fĂŒr das Produkt denn eine SEO URL? Eventuell mĂŒsstest du zuerst die Indizes neu bauen?

@abdullah ja, diese wird auch ausgegeben nur, komischerweise, sobald ich das Objekt mit json_encode Umwandle kommt auf einmal die andere Shopware interne URL

   {% set options = {
        url: seoUrl('frontend.detail.page', { productId: product.id })
    } %}
{{ dump(options) }}
{{ dump(options|json_encode) }

Ausgabe:

array:1 [▌
  "url" => "http://localhost:9998/Haupt-Product"
]
"{"url":"http://localhost:9998/\/detail\/f895e22ba1e446508d3c956c684c20ce"}"

Interessantes Verhalten. FĂŒr mich macht es aber kein Sinn, warum ein json_encode die nicht SEO URL erzeugt.

Eventuell wird das durch den Watcher verursacht?

Aber am Ende sollte beim URL Aufruf automatisch durch den Controller die SEO URL aufgerufen werden.

Interessantes Verhalten. FĂŒr mich macht es aber kein Sinn, warum ein json_encode die nicht SEO URL erzeugt.

Es macht ĂŒberhaupt keinen Sinn :smiley:.

Eventuell wird das durch den Watcher verursacht?

Hab ich getestet
 Leider ist es nicht nur im Watcher :frowning:

Aber am Ende sollte beim URL Aufruf automatisch durch den Controller die SEO URL aufgerufen werden.

Blöderweise soll das, was ich machen will fĂŒr Social Media sein und ich wĂŒrde schon gern die richtige URL nach außen kommunizieren, auch wenn der Controller die „kryptische“ Url auflösen kann.

So muss ich wohl einen Workaround machen 
 das es am json_encode scheitert, hÀtte ich nicht gedacht :smiley:

Der Workaround wĂŒrde jetzt so aussehen, wĂŒrde zwar lieber ĂŒber das options Objekt die Info ĂŒbergeben, aber so geht es auch.

Im Twig:

    ...
    {% set productUrl = seoUrl('frontend.detail.page', { productId: product.id }) %}

    {% set options = {
        url: productUrl
    } %}


    <div class="share-dropdown" 
         data-product-share-button 
         data-url="{{ productUrl }}"
         data-product-share-button-options='{{ options|json_encode }}'>
     ...

Im JS:

    ...
    init() {

        console.log(this.options)
        console.log(this.el.dataset.url)
    }
    ...

Ausgabe:

{url: 'http://localhost:9998//detail/f895e22ba1e446508d3c956c684c20ce', title: null, text: null}
text: null
title: null
url: "http://monsterzeug.ddev.site:9998//detail/f895e22ba1e446508d3c956c684c20ce"
[[Prototype]]: Object

product-share-button.js?3382:14 http://localhost:9998/Haupt-Product

Falls jemand weiß, wie man es korrekt macht oder eine bessere Lösung hat, dann sehr gern :slight_smile:

Das liegt daran, weil die SEO Urls im Template erst ersetzt werden, nachdem das gesamte Template gerendert wurde. Sonst hÀtte man viele Datenbankabfragen bei jedem Produkt. json_encode() maskiert aber die Slashes und deshalb kann die RAW Url nicht mehr im Template gefunden und ersetzt werden.

1 „GefĂ€llt mir“

Ahh okay
 danke fĂŒr die AufklĂ€rung @Moorleiche

Dann ist wohl meine Lösung, wie ich das Problem umgehe, doch nicht so verkehrt. Trotzdem fĂŒr mehr Ideen bin ich Dankbar

Hallo @olli.k, zwar schon ein paar Tage her, aber ich habe mir beholfen, in dem ich dem json_encode die Option ĂŒbergebe, die Slashes nicht zu maskieren. Vll hilft Dir das ja auch weiter, dann werden die SEO Urls ausgegeben.

|json_encode(constant('JSON_UNESCAPED_SLASHES'))