views:

204

answers:

2

I'm trying to render a calendar with Rails and Haml.

The dates used come from a variable called @dates. It is a Date range that contains the first and last days to be presented on the calendar. The first day is always Sunday and the last one is always Monday.

I'm planning to render a typical calendar, with one column per weekday (Sunday is going to be the first day of the week) using an HTML table.

So, I need to put a %tr followed by a %td on Sundays, but the rest of the days I just need a %td.

I'm having trouble modelling that in Haml. This seems to require different levels of indentation, and that's something it doesn't like. Here's my failed attempt:

%table
  %tr
    %th= t('date.day_names')[0] # Sunday
    %th= t('date.day_names')[1]
    %th= t('date.day_names')[2]
    %th= t('date.day_names')[3]
    %th= t('date.day_names')[4]
    %th= t('date.day_names')[5]
    %th= t('date.day_names')[6] # Monday
  [email protected] do |date|
    - if(date.wday == 0) # if date is sunday
      %tr
        %td=date.to_s
    - else
      %td=date.to_s

This doesn't work the way I want. The %tds for the non-Sunday days appear outside of the %tr:

      <tr>
        <td>2010-04-24</td>
      </tr>
      <td>2010-04-25</td>
      <td>2010-04-26</td>
      <td>2010-04-27</td>
      <td>2010-04-28</td>
      <td>2010-04-29</td>
      <td>2010-04-30</td>
      <tr>
        <td>2010-05-01</td>
      </tr>
      <td>2010-05-02</td>
      <td>2010-05-03</td>
      ...

I tried adding two more spaces to the else but then Haml complained about improper indentation.

What's the best way to do this?

Note: I'm not interested on rendering the calendar using unordered lists. Please consider using a table as one of the problem's constraints.

+1  A: 
%table
  %tr
    %th= t('date.day_names')[0] # Sunday
    %th= t('date.day_names')[1]
    %th= t('date.day_names')[2]
    %th= t('date.day_names')[3]
    %th= t('date.day_names')[4]
    %th= t('date.day_names')[5]
    %th= t('date.day_names')[6] # Monday
  %tr
    [email protected] do |date|
      %td=date.to_s

This should give you

<tr>
  <td>2010-04-24</td>
  <td>2010-04-25</td>
  <td>2010-04-26</td>
  <td>2010-04-27</td>
  <td>2010-04-28</td>
  <td>2010-04-29</td>
  <td>2010-04-30</td>
</tr>
Evgeny Shadchnev
I believe that will work only with the first row of days (first week).@dates contains several weeks, not just one. I want to put one %tr per week.
egarcia
You cannot do it in haml in a normal way. There are two options. First, slice your array into an array of weeks and iterate each of them as shown in my answer (that'd be my preferred solution). Second, actually print tags manually: = "<tr>" when you need them (that's an ugly solution). If you need an example of the first approach, I can sketch it.
Evgeny Shadchnev
I've found a way of doing this using in_groups_of (adding answer). Thanks for the help, I was really blocked by this indentation stuff.
egarcia
+1  A: 

Evgeny's comment put me on the right track.

Here's a solution that works, using rails' in_groups_of(link is dead right now):

%table(cellspacing="0" cellpadding="0")
  %tr
    %th= t('date.day_names')[0]
    %th= t('date.day_names')[1]
    %th= t('date.day_names')[2]
    %th= t('date.day_names')[3]
    %th= t('date.day_names')[4]
    %th= t('date.day_names')[5]
    %th= t('date.day_names')[6]

  - @dates.to_a.in_groups_of(7) do |week|
    %tr
      - week.each do |day|
        %td=day.to_s

Notice that I had to convert the Range into an Array - ranges don't seem to implement in_groups_of.

egarcia