Calender Helper Plugin をいじってみる(2)

前回の日記ではCalendar Helper Plugin を日本語化してみようとがんばりました。とりあえず、表示形式をオプションで渡して処理をさせることにしました。今回は、ソースコードをいじってみます。

※ 注意: 初心者が修正したものなのでしょぼいかもしれませんよ

オリジナルソースコードを読んでみる

とりあえず、オリジナルのソースがどうなっているのか調べてみます。オリジナルのソースは、

railsapp/vendor/plugins/calendar_helper/lib

にあります。

エディタで開いて、少し読んでみたところ、以下の部分がHTML出力に関係ありそうです。

  76:    day_names = Date::DAYNAMES.dup
  77:    first_weekday.times do
  78:      day_names.push(day_names.shift)
  79:    end
  80:
  81:    cal = %(<table class="#{options[:table_class]}"
         border="0" cellspacing="0" cellpadding="0">) 
  82:    cal << %(<thead><tr class="#{options[:month_name_class]}">
         <th colspan="7">#{Date::MONTHNAMES[options[:month]]}</th></tr>
         <tr class="#{options[:day_name_class]}">)
  83:    day_names.each {|d| cal << "<th>#{d[options[:abbrev]]}</th>"}
  84:    cal << "</tr></thead><tbody><tr>"
  85:    beginning_of_week(first, first_weekday).upto(first - 1) do |d|
  86:      cal << %(<td class="#{options[:other_month_class]})
  87:      cal << " weekendDay" if weekend?(d)
  88:      cal << %(">#{d.day}</td>)
  89:    end unless first.wday == first_weekday
  90:    first.upto(last) do |cur|
  91:      cell_text, cell_attrs = block.call(cur)
  92:      cell_text  ||= cur.mday
  93:      cell_attrs ||= {:class => options[:day_class]}
  94:      cell_attrs[:class] += " weekendDay" if [0, 6].include?(cur.wday) 
  95:      cell_attrs = cell_attrs.map {|k, v| %(#{k}="#{v}") }.join(" ")
  96:      cal << "<td #{cell_attrs}>#{cell_text}</td>"
  97:      cal << "</tr><tr>" if cur.wday == last_weekday
  98:    end
  99:    (last + 1).upto(beginning_of_week(last + 7, first_weekday) - 1)  do |d|
 100:      cal << %(<td class="#{options[:other_month_class]})
 101:      cal << " weekendDay" if weekend?(d)
 102:      cal << %(">#{d.day}</td>)
 103:    end unless last.wday == last_weekday
 104:    cal << "</tr></tbody></table>"

処理を整理してみる

詳しく読んでみたら、大体こんな感じで処理をやっています。

  • 76行目で曜日(Suday, Monday)を配列で取得
  • 77-79行目で、指定した曜日が週の先頭に来るようにpush、shiftを繰り返す
  • 81行目でtableタグを出力
  • 82行目で該当月を出力(Date::MONTHNAMES で January とかを取得)
  • 83行目で曜日を出力
  • 後は、まぁ、がんばって

日本語化をするためには、上記の行で扱うデータを日本語のものにすり替えてしまえばいいですよね?日本語データとして必要なのは、

  • 月の名前(1月などの通常のもの、睦月などの陰暦)
  • 曜日の名前(日、月、火といった感じ)

ですね。

というわけでこれらを定数として定義します。

ソースコードの修正(追加も)

  ##----  通常の日本語月
  JAPANESE_NORMAL = ["", "1月", "2月", "3月", "4月", "5月", "6月",
                     "7月", "8月", "9月", "10月", "11月", "12月"]
  ##----  陰暦
  JAPANESE_LUNAR  = ["", "睦月", "如月", "弥生", "卯月", "皐月", "水無月",
                     "文月", "葉月", "長月", "神無月", "霜月", "師走"]
  ##----  曜日
  JAPANESE_WEEK   = ["日", "月", "火", "水", "木", "金", "土"]

定数名は適当です。気に入らなかったら変えてくださいな。で、後は前回の日記で指定した :options の値によってこれらの情報とすり替えてやればOKです。

月と曜日のすり替えはこんな感じです。

  ##----  月の表示
  month = options[:month]
  case options[:month_expression]
  when 'jp_normal'
    month_name = JAPANESE_NORMAL[month]
  when 'jp_lunar'
    month_name = JAPANESE_LUNAR[month]
  else
    month_name = Date::MONTHNAMES[month]
  end

  ##----  曜日らしい([Sunday, Monday, Tuesday, ... Saturday])
  case options[:week_expression]
  when 'jp'
    day_names = JAPANESE_WEEK
  else
    day_names = Date::DAYNAMES.dup
  end
  first_weekday.times do
    day_names.push(day_names.shift)
  end

で、出力部分も少しいじります。

82行目の
  cal << %(<thead><tr class="#{options[:month_name_class]}">
           <th colspan="7">#{Date::MONTHNAMES[options[:month]]}</th></tr>
           <tr class="#{options[:day_name_class]}">)
を
  cal << %(<thead><tr class="#{options[:month_name_class]}">
           <th colspan="7">#{month_name}</th></tr>
           <tr class="#{options[:day_name_class]}">)

単に直接 Date::MONTHNAMESってやってたのをmonth_nameに変えただけです。

動作確認

修正できたら、サーバを再起動して正しくできたか修正できたかを確認します。
カレンダーを埋め込みたいrhtmlにコードを書きます。

月を陰暦で、曜日を日本語で表示

<%=
calendar({:year => 2007, :month => 6, :month_expression => 'jp_lunar', :week_expression => 'jp'}) do |d|
  cell_text = "#{d.mday}<br/>"
  cell_attrs = {:class => 'hoge'}
  [cell_text, cell_attrs]
end

%>

月を1月2月で、曜日を英語で表示
<%=
calendar({:year => 2007, :month => 6, :month_expression => 'jp_normal'}) do |d|
  cell_text = "#{d.mday}<br/>"
  cell_attrs = {:class => 'hoge'}
  [cell_text, cell_attrs]
end
%>

実行結果は、それぞれ以下のようになりました。

以上でカレンダープラグインの導入と似非日本語かも終わりました。