Home

Awesome

LaterDude

Build Status

LaterDude is a small calendar helper plugin for Rails with i18n support.

It was heavily inspired by "Jeremy Voorhis'/Geoffrey Grosenbach's calendar_helper plugin":http://topfunky.net/svn/plugins/calendar_helper/. Here's what's different:

Installation

You can use LaterDude either as a gem (preferred) or as a Rails plugin.

To use the gem version, put the following gem requirement in your environment.rb:

config.gem 'later_dude', :source => 'http://gemcutter.org'

Or with Rails 3, add the gem requirement to your Gemfile:

gem 'later_dude', '>= 0.3.1' # 0.3.0 was broken!

To install it as a plugin, fire up your terminal, go to your Rails app and type:

$ ruby script/plugin install git://github.com/clemens/later_dude.git

To use the CalendarHelper, put this in a controller:

helper LaterDude::CalendarHelper

Examples

There are two basic ways of outputting a calendar: via the presenter itself or by using the helper method:

<%= calendar_for(2009, 1) %> and
<%= LaterDude::Calendar.new(2009, 1).to_html %>

both yield the same results. This is similar to what Rails does with RedCloth/BlueCloth filters.

In addition to year and month which are required parameters you can optionally supply an options hash:

<%= calendar_for(2009, 1, :calendar_class => "my_calendar", :first_day_of_week => 1)

Possible options are:

You can also pass in a block to mark days according to your own set of rules. The block gets passed each day of the current month (i.e. days of the previous and following month are not yielded):

<%= calendar_for(2009, 1) do |day|
  if Calendar.has_events_on?(day)
    [link_to(day.day, events_path(day.year, day.month, day.day)), { :class => "dayWithEvents" }]
  else
    day.day
  end
end %>

The block can either return an array containing two elements or a single value. If an array is returned, the first element will be the content of the table cell and the second will be used as HTML options for the table cell tag. If a single value is returned, it will be used as the content of the table cell.

Hint: You can avoid cluttering up your views and move the block to a helper:

# app/helpers/calendar_helper.rb
def calendar_events_proc
  lambda do |day|
    if Calendar.has_events_on?(day)
      [link_to(day.day, events_path(day.year, day.month, day.day)), { :class => "dayWithEvents" }]
    else
      day.day
    end
  end
end

# app/views/calendar/show.html
<%= calendar_for(2009, 1, &calendar_events_proc)

Formatting the header section

You can customize the calendar's header section (i.e. the first table row) by using one or more of the following options:

All of these can either take a single value or an array of two values:

# simple string
:next_month => "&raquo;"

# strftime string
:next_month => "%b"

# proc - will evaluate the proc
:next_month => lambda { |date| link_to "&raquo;", calendar_path(date.year, month.year) }

# simple string and proc - will evaluate the proc and use it for link_to, e.g. link_to("&raquo;", calendar_path(date.year, month.year))
:next_month => ["&raquo;", lambda { |date| calendar_path(date.year, month.year) }]

# strftime string and proc - will evaluate the proc and use it for link_to, e.g. link_to("Jan", calendar_path(date.year, month.year))
:next_month => ["%b", lambda { |date| calendar_path(date.year, month.year) }]

If you use a proc it gets passed a Date object carrying the respective month, i.e. the proc for :previous_month gets passed a Date object representing the previous month etc.

You can do all kinds of mighty stuff with a proc. Imagine a situation where you want to show the abbreviated month name and then the number of events for the given month:

# depending on your routes, this outputs something like <a href="/calendar/2009/1">Jan (3 events)</a>
:next_month => lambda { |date| link_to I18n.localize(date, :format => "%b (#{pluralize(Event.in_month(date))})", calendar_path(date.year, date.month) }

The option :next_and_previous_month can be used as a shortcut if you want to use the same formatting for the next and previous month. Both, :next_month and :previous_month override the :next_and_previous_month if given.

i18n

You can define the following keys in your locale files to customize output:

Of course, you can also put other configuration options in the locale and then pass them in manually:

# somewhere in a locale
date:
  calendar:
    calendar_class: my_cool_calendar

# in the view
<%= calendar_for(2009, 1, :calendar_class => I18n.translate(:'date.calendar.calendar_class', :default => "my_calendar"))

Note that you should always pass in a default in case a translation can't be found since your options override the default options which might result in weird exceptions if the translation is missing.

Bugs & Feedback

You can send me feedback, bug reports and patches via "GitHub":http://github.com/clemens.

Copyright (c) 2009-2012 Clemens Kofler clemens@railway.at, released under the MIT license.