Variable referencePrice mit Wert füllen wenn leer/null [Grundpreis in Shopware 6 immer anzeigen]

Hallo zusammen,

price.referencePrice enthält, soweit ich das verstehe, den im Core berechneten Grundpreis (korrigiert mich bitte, wenn ich falsch liege). So steht z.B. in /page/product-detail/buy-widget-price.html.twig folgendes:

{% if price.referencePrice is not null %}
{% block page_product_detail_price_unit_reference_content %}
<span class="price-unit-reference-content">
({{ price.referencePrice.price|currency }}{{ "general.star"|trans|sw_sanitize }} / {{ price.referencePrice.referenceUnit }} {{ price.referencePrice.unitName }})
</span>
{% endblock %}
{% endif %}

Also wenn „price.referencePrice“ was enthält, dann…

Jetzt ist das Problem, das price.referencePrice wohl nichts enthält, wenn Inhalt und Verkauseinheit gleich sind. Dann sollte der Wert wohl null sein, wenn ich das „is not null“ richtig verstehe.

Ich möchte nun erreichen, das in diesem Fall price.referencePrice mit dem Artikelpreis gefüllt wird, welcher wiederum price.unitPrice sein dürfte.

Ich habe folgendes probiert:

{% if price.referencePrice is not null %}
{% block page_product_detail_price_unit_reference_content %}
<span class="price-unit-reference-content">
({{ price.referencePrice.price|currency }}{{ "general.star"|trans|sw_sanitize }} / {{ price.referencePrice.referenceUnit }} {{ price.referencePrice.unitName }})
</span>
{% endblock %}
{% elseif price.referencePrice == null %}
{% set price.referencePrice = price.unitPrice %}
<span class="price-unit-reference-content">
({{ price.referencePrice.price|currency }}{{ "general.star"|trans|sw_sanitize }} / {{ price.referencePrice.referenceUnit }} {{ price.referencePrice.unitName }})
</span>
{% endblock %}
{% endif %}

Also ich habe „{% elseif price.referencePrice == null %} {% set price.referencePrice = price.unitPrice %}“ hinzugefügt.

Das einzige was dann passiert, ist, das die Produkt-Detailseite nicht mehr öffnet „Leider ist etwas schief gelaufen“.

Ich vermute, ich habe einen Syntax oder einen Logikfehler beim befüllen von price.referencePrice.

Hat jemand eine idee? Kann ich sowas über die buy-widget-price.html.twig überhaupt machen?

Ich freue mich auch Vorschläge und Ideen!

{% if price.referencePrice is defined && price.referencePrice is not null && price.referencePrice !=„0“ %}

so in etwa?

Meintest du dann z.B. so?

{% if price.referencePrice is not null %}
{% block page_product_detail_price_unit_reference_content %}
<span class="price-unit-reference-content">
({{ price.referencePrice.price|currency }}{{ "general.star"|trans|sw_sanitize }} / {{ price.referencePrice.referenceUnit }} {{ price.referencePrice.unitName }})
</span>
{% endblock %}
{% endif %}
 
{% if price.referencePrice is defined && price.referencePrice is not null && price.referencePrice !=„0“ %}
{% set price.referencePrice = price.unitPrice %}
{% block page_product_detail_price_unit_reference_content %}
<span class="price-unit-reference-content">
({{ price.referencePrice.price|currency }}{{ "general.star"|trans|sw_sanitize }} / {{ price.referencePrice.referenceUnit }} {{ price.referencePrice.unitName }})
</span>
{% endblock %}
{% endif %}

versuchs mal.
Oftmal s werden Werte, beim löschen wieder auf null gesetzt sondern auf 0. Daher mach ich oftmals alle 3 abfragen…

Habs probiert, es kommt leider nur „Leider ist etwas schief gelaufen“.

Mal ins Logfile (z.B. var/log/prod-2024-03-09.log für den 09.03.2024) schauen, da steht normalerweise die komplette Fehlermeldung, aus der wird man deutlich schlauer…

Ich habe mal die Fehlermeldungen durchgesehen, ich denke das könnte die relevante Fehlermeldung sein:
[2024-03-28T14:48:11.303939+00:00] request.CRITICAL: Uncaught PHP Exception Shopware\Storefront\Controller\Exception\StorefrontException: „Can not render @Storefront/storefront/page/product-detail/index.html.twig view: Unknown „endif“ tag. with these parameters: {„ratingSuccess“:null,„themeIconConfig“:}“ at StorefrontException.php line 29 {„exception“:„[object] (Shopware\Storefront\Controller\Exception\StorefrontException(code: 0): Can not render @Storefront/storefront/page/product-detail/index.html.twig view: Unknown "endif" tag. with these parameters: {"ratingSuccess":null,"themeIconConfig":} at /var/www/vhosts/MEINSERVER.de/html/Shop/vendor/shopware/storefront/Controller/Exception/StorefrontException.php:29)“}

Da ist ein endif an der falschen Stelle bzw. zu viel. Sind die Gänsefüßchen beim zweiten if auch im „echten“ Code so angeordnet? „0“ ist falsch, es muss „0“ sein. Aber vielleicht auch nur hier so formatiert.

Ich seh schon, er formatiert die Gänsefüßchen um…

Nachtrag: Vielleicht beim Vergleich gegen 0 mal ganz auf die Anführungszeichen verzichten.

{% if price.referencePrice is defined && price.referencePrice is not null && price.referencePrice != 0 %}

Danke dir - ich hab es so probiert, leider Fehlermeldung.

Can not render @Storefront/storefront/page/product-detail/index.html.twig view: Unexpected token "punctuation" of value "." ("end of statement block" expected). with these parameters: {"ratingSuccess":null,"themeIconConfig":[]}

Vorher übersehen, das funktioniert so nicht. Man kann in Twig leider keine Array-Werte direkt setzen, nur über einen Umweg mit merge

{% set price = price|merge({ 'referencePrice': price.unitPrice }) %}

Ich habe es gerade so probiert:

{% sw_extends '@Storefront/storefront/page/product-detail/buy-widget-price.html.twig' %}
{% if price.referencePrice is not null %}
{% block page_product_detail_price_unit_reference_content %}
<span class="price-unit-reference-content">
({{ price.referencePrice.price|currency }}{{ "general.star"|trans|sw_sanitize }} / {{ price.referencePrice.referenceUnit }} {{ price.referencePrice.unitName }})
</span>
{% endblock %}
{% endif %}
 
{% if price.referencePrice is defined && price.referencePrice is not null && price.referencePrice !=„0“ %}
{% set price = price|merge({ 'referencePrice': price.unitPrice }) %}
{% block page_product_detail_price_unit_reference_content %}
<span class="price-unit-reference-content">
({{ price.referencePrice.price|currency }}{{ "general.star"|trans|sw_sanitize }} / {{ price.referencePrice.referenceUnit }} {{ price.referencePrice.unitName }})
</span>
{% endblock %}
{% endif %}

Ergibt leider folgende Fehlermeldung:

Shopware\Storefront\Controller\Exception\StorefrontException:
Can not render @Storefront/storefront/page/product-detail/index.html.twig view: The block 'page_product_detail_price_unit_reference_content' has already been defined line 3. with these parameters: {"ratingSuccess":null,"themeIconConfig":[]}

The block 'page_product_detail_price_unit_reference_content' has already been defined line 3.

Du kannst nicht zwei mal den gleichen Namen für Blocks vergeben. Die müssen unterschiedlich benannt sein.

Mein neuester Versuch:

{% sw_extends '@Storefront/storefront/page/product-detail/buy-widget-price.html.twig' %}
{% block page_product_detail_price_unit_content %}
{% if price.referencePrice is not null %}
<span class="price-unit-content">
{{ page.product.purchaseUnit }} {{ page.product.unit.translated.name }}
</span>
{% else %}
{% set price = price|merge({ 'referencePrice': price.unitPrice }) %}
<span class="price-unit-reference-content">
({{ price.referencePrice.price|currency }}{{ "general.star"|trans|sw_sanitize }} / {{ price.referencePrice.referenceUnit }} {{ price.referencePrice.unitName }})
</span>
{% endif %}
{% endblock %}

Ergibt folgende Fehlermeldung:

Can not render @Storefront/storefront/page/product-detail/index.html.twig view: The merge filter only works with arrays or "Traversable", got "object" for argument 1. with these parameters: {"ratingSuccess":null,"themeIconConfig":[]}

price ist eine Entity, da funktioniert merge nicht. Brauchst du doch auch gar nicht, du kannst auch einfach price.referencePrice ersetzen.

<span class="price-unit-reference-content">
({{ price.unitPrice.price|currency }}{{ "general.star"|trans|sw_sanitize }} / {{ price.unitPrice.referenceUnit }} {{ price.unitPrice.unitName }})
</span>

price.referencePrice kannst du sonst über einen Subscriber überschreiben.

Ich habe folgendes probiert:

{% sw_extends '@Storefront/storefront/page/product-detail/buy-widget-price.html.twig' %}
{% block page_product_detail_price_unit_content %}
{% if price.referencePrice is not null %}
<span class="price-unit-content">
{{ page.product.purchaseUnit }} {{ page.product.unit.translated.name }}
</span>
{% else %}
<span class="price-unit-reference-content">
({{ price.unitPrice.price|currency }}{{ "general.star"|trans|sw_sanitize }} / {{ price.unitPrice.referenceUnit }} {{ price.unitPrice.unitName }})
</span>
{% endif %}
{% endblock %}

Er zeigt dann leider nur „Inhalt: (0,00 €* / )“ an statt z.B. „Inhalt: 1 Liter (6,47 €* / 1 Liter)“, wie es gewünscht wäre.

Ich bin jetzt davon ausgegangen, dass price.unitPrice, das ist was du brauchst, da du damit ja referencePrice überschreiben wolltest.

Schau dir doch die Variablen im dump an, und dann gib die Werte so aus wie du sie brauchst.

{{ dump(price) }}

Aber ich glaube am einfachsten ist es wirklich, wenn du einen Subscriber hast, der price.referencePrice befüllt.

Im Standard ist es so, das Shopware, wenn referenceprice „0“ ist, also z.B. der Grundpreis dem Produktpreis entspricht, kein Grundpreis angezeigt wird.

Ich weiß, das es hier eine Ausnahme in der Preisangabenverordnung gibt. Ich finde es halt schlecht umgesetzt, denn der eigentliche Inhalt des Produkts wird nur auf der Detailseite ausgegeben. Weder in der Produktübersicht, noch in der Suche oder schon gar nicht im Warenkorb sieht der Kunde bei einem Grundpreisangabenpflichtigen Produkt wenigstens den Inhalt. IMHO rechtlich zumindest sehr fragwürdig.

Daher wollte ich das so umbauen, das einfach immer ein Grundpreis angezeigt wird, auch wenn der Inhalt 1 Liter oder 1kg ist, und ich hatte mir gedacht, wenn referencPrice 0 ist, diesen mit dem Artikelpreis (unitPrice) zu ersetzen, sodass für den Shop doch ein Grundpreis da ist, den er anzeigen kann.

Wie das mit einem Subscriber geht weiß ich leider nicht.

{% block page_product_detail_price_unit %}
    <div class="product-detail-price-unit">
        {% block page_product_detail_price_unit_label %}
            <span class="price-unit-label">
                {{ "detail.priceUnitName"|trans|sw_sanitize }}
            </span>
        {% endblock %}

        {% block page_product_detail_price_unit_content %}
            <span class="price-unit-content">
                {{ page.product.purchaseUnit }} {{ page.product.unit.translated.name }}
            </span>
        {% endblock %}

        {% if price.referencePrice is not null %}
            {% block page_product_detail_price_unit_reference_content %}
                <span class="price-unit-reference-content">
                    ({{ price.referencePrice.price|currency }}{{ "general.star"|trans|sw_sanitize }} / {{ price.referencePrice.referenceUnit }} {{ price.referencePrice.unitName }})
                </span>
            {% endblock %}
        {% elseif page.product.unit %}
            {% block page_product_detail_price_unit_reference_content_2 %}
                <span class="price-unit-reference-content">
                    ({{ price.unitPrice|currency }}{{ "general.star"|trans|sw_sanitize }} / {{ page.product.referenceUnit }} {{ page.product.unit.translated.name }})
                </span>
            {% endblock %}
        {% endif %}
    </div>
{% endblock %}

Blöd hier, daß das if um den Block page_product_detail_price_unit_reference_content steht und nicht innerhalb, hätte Code gespart, aber was soll’s. Und genauso macht man es mit der Listen-Ansicht (component/product/card/price-unit.html.twig).

1 Like

Ich danke dir vielmals @Anotherone !

Hast du zufällig einen Vorschlag, wie man das in den Warenkorb übertragen kann?

Ich denke, hier wird die Verfügbarkeit einer Grundpreisangabe in /component/product/feature/item.html.twig abgefragt, der Code ist allerdings vollständig anders - und nach meinen bisherigen Versuchen bekomme ich den Inhalt und die Inhaltsbezeichnung (also purchaseUnit und page.product.unit.translated.name) nur, wenn ohnehin ein Grundpreis angezeigt wird - siehe mein Problem im Beitrag
> Variablen im Offcanvas-Warenkorb ausgeben lassen