Group_by in a template

It’s me again. I am still struggling with the group_by problem from Group within a list I am sorry to bother you with this. I am stuck to find a good solution for this trivial problem.

Here’s the current table:

And here is the table I want to render. Without the duplicate entries for “Osterferien 2022” and “Pfingstferien 2022” but with the new calculated days:

The template code:

<tbody class="bg-white divide-y divide-gray-200 dark:bg-gray-900 dark:divide-gray-600">
  <%= for {period, index} <- Enum.with_index(@school_vacation_periods) do %>
    <tr class={if rem(index, 2) == 0 do "bg-white dark:bg-black" else "bg-gray-50 dark:bg-black" end}>
      <td class="py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6 lg:pl-8 dark:text-gray-100"><%= period.colloquial %> <%= period.starts_on.year %></td>
      <td class="px-3 py-4 text-sm text-gray-500 whitespace-nowrap dark:text-gray-300 tabular-nums">
      <%= Calendar.strftime(period.starts_on, "%d.%m.") %><%= if period.starts_on != period.ends_on do %> - <%= Calendar.strftime(period.ends_on, "%d.%m.") %><% end %>
      </td>
      <td class="px-3 py-4 text-sm text-right text-gray-500 whitespace-nowrap dark:text-gray-300 tabular-nums"><%= period.days %> Tag<%= unless period.days == 1 do %>e<% end %></td>
    </tr>
  <% end %>
</tbody>

The data:

@school_vacation_periods = [
  %{
    colloquial: "Herbstferien",
    days: 13,
    ends_on: ~D[2021-10-23],
    holiday_or_vacation_type_slug: "herbst",
    starts_on: ~D[2021-10-11]
  },
  %{
    colloquial: "Weihnachtsferien",
    days: 8,
    ends_on: ~D[2021-12-31],
    holiday_or_vacation_type_slug: "weihnachten",
    starts_on: ~D[2021-12-24]
  },
  %{
    colloquial: "Winterferien",
    days: 8,
    ends_on: ~D[2022-02-05],
    holiday_or_vacation_type_slug: "winter",
    starts_on: ~D[2022-01-29]
  },
  %{
    colloquial: "Osterferien",
    days: 1,
    ends_on: ~D[2022-03-07],
    holiday_or_vacation_type_slug: "ostern-fruehjahr",
    starts_on: ~D[2022-03-07]
  },
  %{
    colloquial: "Osterferien",
    days: 13,
    ends_on: ~D[2022-04-23],
    holiday_or_vacation_type_slug: "ostern-fruehjahr",
    starts_on: ~D[2022-04-11]
  },
  %{
    colloquial: "Pfingstferien",
    days: 1,
    ends_on: ~D[2022-05-27],
    holiday_or_vacation_type_slug: "himmelfahrt-pfingsten",
    starts_on: ~D[2022-05-27]
  },
  %{
    colloquial: "Pfingstferien",
    days: 1,
    ends_on: ~D[2022-06-07],
    holiday_or_vacation_type_slug: "himmelfahrt-pfingsten",
    starts_on: ~D[2022-06-07]
  },
  %{
    colloquial: "Sommerferien",
    days: 44,
    ends_on: ~D[2022-08-19],
    holiday_or_vacation_type_slug: "sommer",
    starts_on: ~D[2022-07-07]
  }
]

I initially thought that it would be best to solve the problem in the controller (the reason for my initial question). But now I think the problem needs to be handled in the template because I actually need the data for an additional ical export in an other template.

I am stuck. The best solution I come up is something like this:

<%= if index + 1 != Enum.count(@school_vacation_periods) do %>
    <%= if Enum.at(@school_vacation_periods, index + 1).colloquial == period.colloquial do %>
       Whatever
    <% end %>
<% end %>

But that is not clean.

What is the best way to tackle this?

By not trying to implement the algorythm in the template.

<%= for {period, index} <- Enum.with_index(combine_by_type(@school_vacation_periods)) do %>
  …
<% end %>

… where combine_by_type uses some of the approaches of the other topic you opened.

2 Likes