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 %}
6
  • Is the end goal to one table for each event, or one big table listing all events? Commented Feb 20, 2015 at 22:27
  • The end output should be <h2>Day</h2><table><tr>event name + time</tr></table> Commented Feb 20, 2015 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. Commented Feb 20, 2015 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. Commented Feb 20, 2015 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. Commented Feb 20, 2015 at 22:41

3 Answers 3

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 %}
8
  • 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. Commented Feb 20, 2015 at 22:36
  • Ah I see. So you could have several consecutive 'event' blocks in a row? Commented Feb 20, 2015 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. Commented Feb 20, 2015 at 22:41
  • 1
    @AdamMcCombs Something like this then? craftcms.stackexchange.com/a/6739/9 Commented Feb 20, 2015 at 22:48
  • 1
    Nice! All set @AdamMcCombs? Commented Feb 20, 2015 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 %}
1
  • Would have been nice if you had posted the code adapted to match you question, Adam.
    – carlcs
    Commented Feb 21, 2015 at 0:27

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.