1

First of all: My solution works ... I can not see any problems.
But I'm very unsure whether my code ist a dirty hack or not.

Please don't care about details in my code ... I'm uncertain because:
There is a lot of logic inside {% set teaserItems %}.

Is there a "better" or "cleaner" or "more performant" solution for this?
If not: I'm fine. :)

{# Builds the individual teasers for the grid. #}
{% set teaserItems %}
    {% for item in items %}

        {% set teaser = {
            image: null,
            heading: null,
            text: null,
            button: null,
            link: null,
            overlay: null,
        } %}

        {# Creates the data structure on Teaser or Entry. #}
        {% switch item.type.handle %}

            {% case 'btcTeaserTeaser' %} {# Teaser #}

                {% if item.hasDescendants() %}
                    {% set teaser = teaser|merge({
                        image: {
                            image: item.children[0].assetImage,
                            altText: item.children[0].assetAltText
                        },
                    }) %}
                {% endif %}

                {% if item.heading %}
                    {% set teaser = teaser|merge({
                        heading: {
                            text: item.heading,
                            level: 4
                        },
                    }) %}
                {% endif %}

                {% if item.richTextSimple %}
                    {% set teaser = teaser|merge({
                        text: item.richTextSimple,
                    }) %}
                {% endif %}

                {% if item.linkField.getUrl() %}
                    {% set teaser = teaser|merge({
                        button: item.buttonText|default(_globals.get('moreText')),
                        link: {
                            url: item.linkField.getUrl(),
                            target: item.linkField.target
                        },
                    }) %}
                {% endif %}

            {% case 'btcTeaserEntry' %} {# Entry #}

                {% set entry = item.teaserEntryPreview.one() %}

                {% if entry.entryPreviewImage %}
                    {% set teaser = teaser|merge({
                        image: {
                            image: entry.entryPreviewImage,
                            altText: entry.assetAltText
                        },
                    }) %}
                {% endif %}

                {% if entry.entryPreviewHeading %}
                    {% set teaser = teaser|merge({
                        heading: {
                            text: entry.entryPreviewHeading,
                            level: 4
                        },
                    }) %}
                {% endif %}

                {% if entry.entryPreviewText %}
                    {% set teaser = teaser|merge({
                        text: entry.entryPreviewText,
                    }) %}
                {% endif %}

                {% if entry.url %}
                    {% set teaser = teaser|merge({
                        button: item.buttonText|default(_globals.get('moreText')),
                        link: {
                            url: entry.url,
                        },
                    }) %}
                {% endif %}

        {% endswitch %}

        {# For teaser variant "Overlay", both BockTypes have this field in common. #}
        {% if item.teaserOverlay %}
            {% set teaser = teaser|merge({
                overlay: item.teaserOverlay,
            }) %}
        {% endif %}

        {# Creates the teaser with the data structure. #}
        {# variant: Variant of the teaser and directory in the path to the template. #}
        <div id="" class="col {{ additionalClass|default }}">
            {% include '_ui/components/teaser/variant/' ~ variant ~ '/teaser-item.twig' with {
                id: pid ~ '-' ~ loop.index,
                variant: 'teaser-' ~ variant,
                teaser: teaser,
                colorSet: item.colorSet,
                ratio: ratio,
                additionalClass: 'h-100',
            } only %}
        </div>

    {% endfor %}
{% endset %}

{# Build the grid with the teasers. #}
{% include '_ui/components/grid/grid' with {
    gridItems: teaserItems,
    gridCols: gridCols,
    additionalClass: 'c-teaser teasergroup-' ~ variant,
} only %}

_ui/components/grid/grid

{# inheritance #}
{% set gridColsDefault = gridCols[0]|default(1) %}
{% set inheritGridColsSmall = gridCols[1]|default(gridColsDefault) %}
{% set inheritGridColsMedium = gridCols[2]|default(inheritGridColsSmall) %}
{% set inheritGridColsLarge = gridCols[3]|default(inheritGridColsMedium) %}
{% set inheritGridColsXLarge = gridCols[4]|default(inheritGridColsLarge) %}
{% set inheritGridColsXxLarge = gridCols[5]|default(inheritGridColsXLarge) %}

    <div class="row row-cols-{{ gridColsDefault }} row-cols-sm-{{ inheritGridColsSmall }} row-cols-md-{{ inheritGridColsMedium }} 
                row-cols-lg-{{ inheritGridColsLarge }} row-cols-xl-{{ inheritGridColsXLarge }} row-cols-xxl-{{ inheritGridColsXxLarge }}
                g-3 {{ additionalClass|default }}">
    
        {{ gridItems }}
    
    </div>

1 Answer 1

1

It's not bad the way you've done it, in my opinion. However I'd probably use an embed instead of an include - that way you can pass in a block of content without having to use set...endset, which sometimes comes with auto-escaping issues, and it just feels a bit cleaner to me:

{# ==================================
Calling template
===================================== #}

{% embed '_ui/components/grid/grid' with {    
    gridCols: gridCols,
    additionalClass: 'c-teaser teasergroup-' ~ variant,
} only %}
    {% block gridItems %}
        <p>All your stuff here</p>
    {% endblock %}
{% endembed %}

{# ==================================
_ui/components/grid/grid
===================================== #}

{% set gridColsDefault = gridCols[0]|default(1) %}
{% set inheritGridColsSmall = gridCols[1]|default(gridColsDefault) %}
...

<div class="row row-cols-...">
    {% block gridItems %}{% endblock %}
    {# or just {{ block('gridItems') }} if you don't need any default content. #}
</div>

https://twig.symfony.com/doc/3.x/tags/embed.html

1
  • Ahhh ... I see. Thank you, James, for explanation!
    – Marc
    Commented Oct 16, 2023 at 9:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.