0

I got the following code in an .erb document:

<% @blog.order("created_at DESC").each do |d| %>

       <!-- Blog Card -->
       <div class="col-12 mb-3 mb-sm-7">
        <article class="row align-items-lg-center">
          <div class="col-lg-8">
            <%= image_tag d.image.to_s, class:"img-fluid rounded" %>
          </div>

          <div class="col-lg-4">
            <div class="py-5 px-lg-3">
              <span class="d-block mb-2">
                <p class="small text-body font-weight-bold text-cap"><%= d.tag_list %></p>
              </span>
              <h2>
                <%= link_to d.title, d, class:"text-inherit" %>
              </h2>
              <p><%= d.summary.truncate(100) %></p>
              <%= link_to "read more", d %>
            </div>
          </div>
        </article>
      </div>
      <!-- End Blog Card -->

<% end %>

I want the code to change every nth time so i have multiple "layouts" (not in the ruby sense) in my blog. for this i added an if clause with following code:

<% if d.id % 5 == 0 %>

Unfortunately that does not work very well since i want to weave in the layout alternative into the regular layout like this:

┌─────────┐
└─────────┘
┌──┐┌──┐┌─┐
└──┘└──┘└─┘
┌─────────┐
└─────────┘
┌──┐┌──┐┌─┐
└──┘└──┘└─┘

So one large article, next row with three small ones etc.

Edit: The alternating layout looks like this:

      <div class="order-lg-1 col-sm-6 col-lg-4 mb-3 mb-sm-7">
        <!-- Blog -->
        <article
          class="card align-items-start flex-wrap flex-row h-380rem gradient-y-overlay-sm-dark bg-img-hero rounded-pseudo transition-3d-hover"
          style="background-image: url('<%= d.image.to_s %>');">
          <div class="card-header border-0 bg-transparent w-100">
            <p class="small text-white font-weight-bold text-cap mr-2"><%= d.tag_list %></p>
          </div>

          <div class="card-footer border-0 bg-transparent mt-auto">
            <%= link_to d do %>
            <h3 class="text-white"><%= d.title %></h3>
            <span class="text-white-70">Read more<i class="fas fa-angle-right fa-sm ml-1"></i></span>
            <% end %>
          </div>
        </article>
        <!-- End Blog -->
      </div>

How do i implement such a layout?

SOLUTION

I managed to do what i wanted with a combination of .each_with_index and using partials. like this:

<% @blog.order("created_at DESC").each_with_index do |d, index| %>

<%= index % 4 == 0 ? render("blog/var1", d: d) : render("blog/var2", d: d) %>

<% end %>
  • so it is every other row has 3 in it, right? – Rockwell Rice Sep 13 '20 at 13:33
  • @RockwellRice yes, every other row should contain article elements with `col-4` as class.. – GabrielTheCoder Sep 13 '20 at 13:39
  • I would use `each_with_index` and then you can just do every even row as the three blocks. So change `.each` to `.each_with_index` and then you can get the index in the loop, so change `|d|` to `|d, idx|` and then you can just use the modulo operator to test for even – Rockwell Rice Sep 13 '20 at 14:07

1 Answers1

1

You can do something like this:

<% @blog.order("created_at DESC").each_with_index do |d, index| %>

       <!-- Blog Card -->
       <div class="col-#{index % 4 == 0 ? '12' : '4'} mb-3 mb-sm-7">
        <article class="row align-items-lg-center">
          <div class="col-lg-8">
            <%= image_tag d.image.to_s, class:"img-fluid rounded" %>
          </div>

          <div class="col-lg-4">
            <div class="py-5 px-lg-3">
              <span class="d-block mb-2">
                <p class="small text-body font-weight-bold text-cap"><%= d.tag_list %></p>
              </span>
              <h2>
                <%= link_to d.title, d, class:"text-inherit" %>
              </h2>
              <p><%= d.summary.truncate(100) %></p>
              <%= link_to "read more", d %>
            </div>
          </div>
        </article>
      </div>
      <!-- End Blog Card -->

<% end %>

It means, for every 0, 4, 8, 12 .... index it'll add class col-12, otherwise it'll add class col-4

EDIT:

Yes, it is possible to insert whole partials as code:

Lets say, you created two separate files for small cards and big cards. _small_blog_card.html.erb and _big_blog_card.html.erb

<% @blog.order("created_at DESC").each_with_index do |d, index| %>

  <% if index % 4 == 0 %>
    <%= render partial: 'big_blog_card', locals: {pass your data} %>
  <% else %>
    <%= render partial: 'small_blog_card', locals: {pass your data} %>
  <% end %>

<% end %>
Emu
  • 5,763
  • 3
  • 31
  • 51
  • thank you! that indeed does work but unfortunately (i forgot to mention that) there are more changes than just the one column css class. is it possible to insert whole partials as code instead of just "12" and "4" ? – GabrielTheCoder Sep 14 '20 at 08:11
  • 1
    @GabrielTheCoder I updated my answer with your query. Please check. – Emu Sep 14 '20 at 09:20