Search code examples
twigshopwareshopware6

shopware 6 twig add block inside of another block child div


i wanted to know if there is any solution to this problem in shopware 6. Many blocks have some child elements. E.g. if i want to add an checkbox to the checkout i need to replace the entire block. This causes complications to other plugins, which are using the same block too.

Shopware 6 twig:

{% block page_checkout_confirm_tos_control %}
                            <div class="form-check"> <!-- <-- child div -->
                                {% block page_checkout_confirm_tos_control_checkbox %}
                                    <input type="checkbox"
                                           class="checkout-confirm-tos-checkbox form-check-input{% if formViolations.getViolations('/tos') is not empty %} is-invalid{% endif %}"
                                           required="required"
                                           id="tos"
                                           form="confirmOrderForm"
                                           name="tos"/>
                                {% endblock %}

                                {% block page_checkout_confirm_tos_control_label %}
                                    <label for="tos"
                                           class="checkout-confirm-tos-label custom-control-label">
                                        {{ "checkout.confirmTermsText"|trans({
                                            '%url%': path('frontend.cms.page',{ id: config('core.basicInformation.tosPage') })
                                        })|raw }}
                                    </label>
                                {% endblock %}
                                <!-- add content/other block here -->
                            </div>
                        {% endblock %}

My twig:

{% extends '@Storefront/storefront/page/checkout/confirm/index.html.twig' %}

{% block page_checkout_confirm_tos_control %}
    {{ parent() }}

    <!-- ! This isn't inside the child div of the block page_checkout_confirm_tos_control -->
    {% block page_checkout_confirm_shippingdata_control_checkbox %}
        <input type="checkbox"
               class="checkout-confirm-shippingdata-checkbox form-check-input{% if formViolations.getViolations('/shippingdata') is not empty %} is-invalid{% endif %}"
               required="required"
               id="shippingdata"
               form="confirmOrderForm"
               name="shippingdata"/>
    {% endblock %}

    {% block page_checkout_confirm_shippingdata_control_label %}
        <label for="shippingdata"
               class="checkout-confirm-shippingdata-label custom-control-label">
            {{ "checkout.confirmShippingdataText"|trans({
                '%url%': path('frontend.cms.page',{ id: config('core.basicInformation.tosPage') })
            })|raw }}
        </label>
    {% endblock %}

{% endblock %}

Is there any solution to do that without js?

Thank you very much.


Solution

  • In that specific case, why not just append the last block inside .form-check?

    {% block page_checkout_confirm_tos_control_label %}
        {{ parent() }}
    
        {% block page_checkout_confirm_shippingdata_control_checkbox %}
            ...
        {% endblock %}
    
        {% block page_checkout_confirm_shippingdata_control_label %}
            ...
        {% endblock %}
    {% endblock %}
    

    In my opinion that's a valid approach to get inside .form-check. On the other hand I could see why it might not feel "clean" to append to the specific block for a label of another element. If you feel that way and there is no hurry, you could open a pull request that adds a block that covers the inside of .form-check.

    {% block page_checkout_confirm_tos_control %}
        <div class="form-check">
            {% block page_checkout_confirm_tos_control_form_check %}
                ...
            {% endblock %}
        </div>
    {% endblock %}
    

    Once this is merged and released the forthcoming updates of your plugin may use that new block instead then.