Redmineの「XX日前」を「yyyy/MM/dd」日付表現で表示するプラグインを書いた
Redmineのチケットは作成日、更新日をちゃんと残してくれるけど、「XX日前」とか表示されていて分かりづらい気がします。特に古いチケットになると「XXヶ月前」とかなってしまって、いったいいつ発行したのかわからなくなってしまうことがあります。*1
やっぱり分かりづらいので見慣れた「yyyy/MM/dd」形式の表示で置き換えるプラグインを作りました。
環境
Redmine 1.0.X で動きます。
以前のバージョンは未確認です。
インストール
1. https://github.com/suer/redmine_absolute_dates からgit cloneして、vendor/plugins に置くか、以下を実行する
2. Redmineを再起動
ruby script/plugin install git@github.com:suer/redmine_absolute_dates.git
技術的な話
Redmine本体の機能を変えるプラグインなので、本体コードの改変が必要になりますが、基本的に本体コードには手を出さないのがRedmine プラグインプログラマの作法です。
ちょっとした魔術が必要です。
日付を表示している部分は以下のような感じです。
<!-- app/view/issues/show.rhtml --> <p class="author"> <%= authoring @issue.created_on, @issue.author %>. <% if @issue.created_on != @issue.updated_on %> <%= l(:label_updated_time, time_tag(@issue.updated_on)) %>. <% end %> </p>
authoring メソッドで 「XXXがYYY日前に作成しました」と表示し、time_tagメソッドで更新日時を「XXX日前」に変換して表示しているようです。
ここで authoringメソッドは
# app/helpers/application_helper.rb module ApplicationHelper def authoring(created, author, options={}) l(options[:label] || :label_added_time_by, :author => link_to_user(author), :age => time_tag(created)) end end
のように、こちらでもやはり time_tagメソッドを使用しています。
なので authoring メソッドと、 time_tagメソッドを書き換えてやる必要があります。
プラグインでは以下のようなモンキーパッチをあてます。
alias_method_chain で日付の文字列を変更するようにラップしています。
module AbsoluteDateHelperPatch def self.included(base) # :nodoc: base.send(:include, InstanceMethods) base.class_eval do alias_method_chain :authoring, :absolute_date alias_method_chain :time_tag, :absolute_date end end module InstanceMethods # Adds a rates tab to the user administration page def authoring_with_absolute_date(created, author, options={}) l(options[:label] || :label_added_absolute_time_by, :author => link_to_user(author), :age => time_tag(created)) end def time_tag_with_absolute_date(time) text = format_date(time) if @project link_to(text, {:controller => 'projects', :action => 'activity', :id => @project, :from => time.to_date}, :title => text) else content_tag('acronym', text, :title => text) end end end end
もとの動作を完全に捨てているので、単にalias_methodでもいいと思います。
alias_method_chain にしてるのは単に使ってみたかったからです:)
alias_method_chain の動作はメタプログラミングRubyを読めば分かると思います。
Redmine本家でも本体のコードを上書きするようプラグインを書く場合は、alias_method_chain でラップするといい、と言っています。
http://www.redmine.org/wiki/redmine/Plugin_Internals#Wrapping-an-existing-method
:label_added_absolute_time_by などはプラグイン内のローカライズ用のファイル(config/locales/ja.yaml) に書いておきます。(もとのやつを使うと yyyy/MM/dd前 とか表示されていやなので)
これをプラグインの init.rb で ApplicationHelperにincludeしてやります
ApplicationHelper.send(:include, AbsoluteDateHelperPatch)
*1:マウスオーバーで表示されるTipには日付が表示されますが....