Written by Sean Behan on Sun Jun 17th 2012

There are a number of terrific calendar plugins for Rails. But it's almost as easy, if not easier, to implement your own calendar.

The steps are pretty simple. First get the @beginning_of_month and @end_of_month and iterate over the days in between. In the loop we check if the day matches the @beginning_of_month and if it does we get the offset ( 0 - 6 ) because if the month doesn't start on a Sunday all our days won't match up correctly. We print out the offset number as table cells <td class='offset'></td>. We then need to consider that weeks 'restart' and restart our row if we're at the beginning of the week... this is accomplished with </tr><tr>. Then we just output the date contained in table cells <td>#{d.day}</td>. The code is below and it's pretty simple.

In this example I use haml, but you could just as easily use ERB (at the bottom). If you're not familiar with haml, check it out at http://haml-lang.com/ Haml automatically handles wrapping your html so you don't have to! The end result is that it cuts your html in half and makes it look pretty, which in turns makes it a lot more manageable long term.


    - @beginning_of_month = Date.civil(2009,12,1)
    - @end_of_month       = Date.civil(2009, 12, -1)
- (@beginning_of_month..@end_of_month).each do |d|
  - if d == @beginning_of_month
    - (d.wday).times do # offset beginning of calendar
     &lt; td class='offset'&gt; &lt;/td&gt;
  -if d.wday == 0 #restart the week

  == &lt;td class='#{d}'&gt; #{d.day} &lt;/td&gt;</pre>

Here it is in ERB

<table id='calendar'>
  <% @beginning_of_month = Date.civil(2009, 12, 1) %>
  <% @end_of_month = Date.civil(2009, 12, -1) %>

<% (@beginning_of_month..@end_of_month).each do |d| %> <% if d == @beginning_of_month %> <% d.wday.times do %> <td class='offset'></td> <% end %> <% end %>

&lt;% if d.wday == 0 %&gt; &lt;/tr&gt;&lt;tr&gt; &lt;% end %&gt;
&lt;td&gt; &lt;%= d.day %&gt; &lt;/td&gt;

<% end %> </tr> </table>

Tagged with..
#calendar #erb #haml #plugins #Ruby on Rails

Just finishing up brewing up some fresh ground comments...