3

My matrix field has a block type called photo. When looping through entries I only want to output the first instance of this block type (although it will have been used multiple times), i.e. the first photo.

The code below loops through the entries, but for each entry it's outputting every photo for the entry - not just the first.

What do I need to change to get just the first photo of each entry output.

{% for entry in craft.entries.section('mySection') %}

    {% for block in entry.tactics %}

        {% if block.type == "photo" %}

            <a href="{{ entry.Url }}">

                {% set photo = block.photo.first() %}

                <img src="{{ photo.getUrl }}" width="{{ photo.getWidth() }}" height="{{ photo.getHeight() }} alt="{{ entry.title }}"/>

                {{ entry.title }}
            </a>

        {% endif %}

    {% endfor %}

{% endfor %}
5

You can output the first matrix block of it's type using .type(blockHandle):

{% for entry in craft.entries.section('mySection') %}
    {% set photoBlock = entry.tactics.type('photo').first %}

    {% if photoBlock %}
        <a href="{{ entry.Url }}">
            {% set photo = photoBlock.photo.first() %}

            {% if photo %}
                <img src="{{ photo.getUrl }}" width="{{ photo.getWidth() }}" height="{{ photo.getHeight() }} alt="{{ entry.title }}"/>
            {% endif %}

            {{ entry.title }}
        </a>
    {% endif %}
{% endfor %}
  • Thanks for a great answer Mike! I'm assuming that you didn't use a "for block..." loop because using ".first" doesn't return an array? – user1070143 Sep 29 '14 at 11:16
  • 1
    Yep, ".first" will return either a single MatrixBlockModel or null, in which case the {% if photoBlock %} check will fail and nothing will be output. Same thing for the photo inside it, although if tactics.photo is a required field you can probably skip that check. – Mike Pepper Sep 29 '14 at 12:57
1

You can exit the loop on some condition:

{% for entry in craft.entries.section('mySection') %}

    {% set exitLoop = 0 %}
    {% for block in entry.tactics if exitLoop == 0 %}

        {% if block.type == "photo" %}

            <a href="{{ entry.Url }}">

                {% set photo = block.photo.first() %}

                <img src="{{ photo.getUrl }}" width="{{ photo.getWidth() }}" height="{{ photo.getHeight() }} alt="{{ entry.title }}"/>

                {{ entry.title }}
            </a>

            {% set exitLoop = 1 %} 
            {# so as this loop will no longer be executed until new entry found #}

        {% endif %}

    {% endfor %}

{% endfor %}

Alternatively, you can use this plugin to break the loop. In this case you can just add

{% break %}

to the end of your if statement.

  • Thank you for the answer Nicael - I Learnt something new, but will go with Mikes answer because it's more crafty. – user1070143 Sep 29 '14 at 11:47
  • @user1070143 sure, it is better (because of length). – nicael Sep 29 '14 at 11:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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