1

Within my matrix I have two blocks: Day and Event. Day is just a date field while the event block has two text fields.

What's the best way to wrap the event data, which needs to show up as a table format within this loop?

This currently spills everything out in the correct order but the table doesn't open and close correctly around the event block.

The final output should look something like

Title (h2)

Table open
TR
TR
TR
Table close

{% for block in entry.scheduleMatrix %}

{% switch block.type %}

{% case 'day' %}
            <h2>{{ block.day.format('l - F j, Y') }} </h2>
<table><tbody>

{% case 'event' %}
            <tr><td>{{ block.eventTime }}</td>
            <td>{{ block.eventName }}</td></tr>

{% endswitch %}
        </tbody>
</table>
{% endfor %}
  • Is the end goal to one table for each event, or one big table listing all events? – Aaron Berkowitz Feb 20 '15 at 22:27
  • The end output should be <h2>Day</h2><table><tr>event name + time</tr></table> – Adam McCombs Feb 20 '15 at 22:32
  • Just an idea, but it sounds like it might be better to just include the date field in the event block as well (even though it's a bit redundant). You can then use the date field to group the blocks for output. It should also help maintain data integrity, and will allow you to return events by date, for use elsewhere, etc. – Douglas McDonald Feb 20 '15 at 22:33
  • @DouglasMcDonald I understand but this is a schedule where there are multiple events per day. The events will also have assets, links etc. so I need the ability to loop events over and over again. – Adam McCombs Feb 20 '15 at 22:37
  • Yes. That's what I'm suggesting — multiple blocks, one event per block, with same date on each block. Then group by date, display the date once, and all the events in a table for that day. – Douglas McDonald Feb 20 '15 at 22:41
2

I think the opening and closing tags in the table are in the wrong spot. Try opening and closing the table inside the event case.

{% for block in entry.scheduleMatrix %}

{% switch block.type %}

{% case 'day' %}
    <h2>{{ block.day.format('l - F j, Y') }} </h2>    
{% case 'event' %}
    <table>
        <tbody>
            <tr><td>{{ block.eventTime }}</td>
            <td>{{ block.eventName }}</td></tr>
        </tbody>
    </table>    
{% endswitch %}

{% endfor %}
  • Close but the event time and name loop over and over again. This ouputs table tr /table and I need something like table tr tr tr tr tr /table. – Adam McCombs Feb 20 '15 at 22:36
  • Ah I see. So you could have several consecutive 'event' blocks in a row? – Aaron Berkowitz Feb 20 '15 at 22:39
  • Correct. That's why I'm thrown off. I don't know how to inject the opening and closing of the table between the cases. – Adam McCombs Feb 20 '15 at 22:41
  • 1
    @AdamMcCombs Something like this then? craftcms.stackexchange.com/a/6739/9 – Brandon Kelly Feb 20 '15 at 22:48
  • 1
    Nice! All set @AdamMcCombs? – Aaron Berkowitz Feb 20 '15 at 22:53
2

An alternate solution would be to add a date field to each event block, you can then group blocks by date on output, and wouldn't have to worry about the client accidentally putting an event in the wrong order. Something like the following (although my syntax might be off a bit).

{% set blocksByDate = entry.scheduleMatrix|group(day|date("Y-m-d") ) %}
{% for day, blocks in blocksByDay %}
    {{ day.format('l - F j, Y') }}
    <table>
        <tbody>
            {% for block in blocks %}
                <tr>
                    <td>{{ block.eventTime }}</td>
                    <td>{{ block.eventName }}</td>
                </tr>
            {% endfor %}
        </tbody>
     </table>
{% endfor %}

Not tested.

1

Brandon sent over another post that answer this exact problem: Solution for Matrix-within-Matrix (or More Robust Table Fields)

{% for block in entry.myMatrixField %}

{# Find out if this is the first/last consecutive block of this type #}
{% set type = block.type.handle %}
{% set isFirstConsecutiveBlockOfType = (loop.first or type != block.getPrev().type.handle) %}
{% set isLastConsecutiveBlockOfType = (loop.last or type != block.getNext().type.handle) %}

{% switch type %}

    {% case 'stat' %}

        {% if isFirstConsecutiveBlockOfType %}
            <div class="stats">
        {% endif %}

        <!-- Stat block HTML -->

        {% if isLastConsecutiveBlockOfType %}
            </div>
        {% endif %}

    {% case 'quote' %}

        {% if isFirstConsecutiveBlockOfType %}
            <div class="quotes">
        {% endif %}

        <!-- Quote block HTML -->

        {% if isLastConsecutiveBlockOfType %}
            </div>
        {% endif %}

{% endswitch %}{% endfor %}
  • Would have been nice if you had posted the code adapted to match you question, Adam. – carlcs Feb 21 '15 at 0:27

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.