Redmineのカレンダーを流用する
Redmine2.0.3をAptanaに入れてカレンダーを流用することを目的とします。
へっだーだけ
ひとまず動くところに持って行きたい。
redmine203/app/controllers/calendar.rbから一部抜粋してapp_root/app/controllers/hoges_controller.rbに貼り付け
def calendar if params[:year] and params[:year].to_i > 1900 @year = params[:year].to_i if params[:month] and params[:month].to_i > 0 and params[:month].to_i < 13 @month = params[:month].to_i end end @year ||= Date.today.year @month ||= Date.today.month end
redmine203/app/views/calendar/show.html.erbから一部抜粋してapp_root/app/views/hoges/calendar.html.erbに貼り付ける
<div class="calendar_label"> <%= link_to_previous_month(@year, @month) %> <%= select_year(@year, :prefix => "year", :discard_type => true) %> <%= select_month(@month, :prefix => "month", :discard_type => true) %> <%= link_to_next_month(@year, @month) %> </div>
これが動くようになるように改造する。
redmine203/lib/redmine/i18n.rbをコピーしてapp_root/lib/redmine/i18n.rbに貼り付ける。
app_root/app/helpers/application_helper.rbに追記
module ApplicationHelper include Redmine::I18n #追記
redmin203/app/helpers/calendars_helper.rbから一部抜粋して、app_root/app/helpers/application_helper.rbに追記
def link_to_previous_month(year, month, options={}) target_year, target_month = if month == 1 [year - 1, 12] else [year, month - 1] end name = if target_month == 12 "#{month_name(target_month)} #{target_year}" else "#{month_name(target_month)}" end # \xc2\xab(utf-8) = « link_to_month(("\xc2\xab " + name), target_year, target_month, options) end def link_to_next_month(year, month, options={}) target_year, target_month = if month == 12 [year + 1, 1] else [year, month + 1] end name = if target_month == 1 "#{month_name(target_month)} #{target_year}" else "#{month_name(target_month)}" end # \xc2\xbb(utf-8) = » link_to_month((name + " \xc2\xbb"), target_year, target_month, options) end def link_to_month(link_name, year, month, options={}) link_to_content_update(h(link_name), params.merge(:year => year, :month => month)) end
redmin203/app/helpers/application_helper.rbから一部抜粋して、app_root/app/helpers/application_helper.rbに追記
private def link_to_content_update(text, url_params = {}, html_options = {}) link_to(text, url_params, html_options) end
これで表示された。
ほんたい
controllerにあったこれがわからん。
@calendar = Redmine::Helpers::Calendar.new(Date.civil(@year, @month, 1), current_language, :month)
やっと見つけた
redmine203/lib/redmine/helpers/calendar.rb を app_root/lib/redmine/helpers/calendar.rbにコピー
current_languageはi18nにあったけど通らないので"ja"で代用
まだエラーがでる。
lib/redmine/helpers/calendar.rb:68:in `first_wday' case Setting.start_of_week.to_i #げんいん
Settingなんて用意しない。
app_root/lib/redmine/helpers/calendar.rb
週の始まりは「月曜日」にきまっている。(偏見)
# Return the first day of week # 1 = Monday ... 7 = Sunday def first_wday @first_dow ||= (1 - 1)%7 + 1 =begin case Setting.start_of_week.to_i when 1 @first_dow ||= (1 - 1)%7 + 1 when 6 @first_dow ||= (6 - 1)%7 + 1 when 7 @first_dow ||= (7 - 1)%7 + 1 else @first_dow ||= (l(:general_first_day_of_week).to_i - 1)%7 + 1 end =end end
retrieve_queryは redmine203/app/helpers/queries_helper.rbにある。
idで絞りこんでいる。ページ遷移したときにsessionのidを見たりしている。謎要素多いけど使わないでおこう。たぶんいらない。
とりあえず表示されるようになったので続く。
redmine203/app/views/calendar/show.html.erbの28行目にあった
<%= error_messages_for 'query' %>
application_helper.rbの967行目ぐらいにあった
def error_messages_for(*objects) html = "" objects = objects.map {|o| o.is_a?(String) ? instance_variable_get("@#{o}") : o}.compact errors = objects.map {|o| o.errors.full_messages}.flatten if errors.any? html << "<div id='errorExplanation'><ul>\n" errors.each do |error| html << "<li>#{h error}</li>\n" end html << "</ul></div>\n" end html.html_safe end
いらないとおもう。
次の謎はコントローラーの「issues」
events += @query.issues(:include => [:tracker, :assigned_to, :priority], :conditions => ["((start_date BETWEEN ? AND ?) OR (due_date BETWEEN ? AND ?))", @calendar.startdt, @calendar.enddt, @calendar.startdt, @calendar.enddt] )
redmine203/app/models/query.rbの584行目あたりにあった
# Returns the issues # Valid options are :order, :offset, :limit, :include, :conditions def issues(options={}) order_option = [group_by_sort_order, options[:order]].reject {|s| s.blank?}.join(',') order_option = nil if order_option.blank? joins = (order_option && order_option.include?('authors')) ? "LEFT OUTER JOIN users authors ON authors.id = #{Issue.table_name}.author_id" : nil issues = Issue.visible.scoped(:conditions => options[:conditions]).find :all, :include => ([:status, :project] + (options[:include] || [])).uniq, :conditions => statement, :order => order_option, :joins => joins, :limit => options[:limit], :offset => options[:offset] if has_column?(:spent_hours) Issue.load_visible_spent_hours(issues) end issues rescue ::ActiveRecord::StatementInvalid => e raise StatementInvalid.new(e.message) end
普通のfindやwhereで十分っぽいので使う必要はなさそう。
次の謎はコントローラーの「versions」
events += @query.versions(:conditions => ["effective_date BETWEEN ? AND ?", @calendar.startdt, @calendar.enddt])
redmine203/app/models/query.rbの634行目あたりにあった
# Returns the versions # Valid options are :conditions def versions(options={}) Version.visible.scoped(:conditions => options[:conditions]).find :all, :include => :project, :conditions => project_statement rescue ::ActiveRecord::StatementInvalid => e raise StatementInvalid.new(e.message) end
こっちも普通のfindやwhereで十分っぽいので使う必要はなさそう。
コントローラの締めくくり
@calendar.events = events
app_root/lib/redmine/helpers/calendar.rbのコレ
# Sets calendar events def events=(events) @events = events @ending_events_by_days = @events.group_by {|event| event.due_date} @starting_events_by_days = @events.group_by {|event| event.start_date} end
これはモデルごとに作りなおしかなー?面倒なのでコントローラーにぶち込む。
@calendar = Redmine::Helpers::Calendar.new(Date.civil(@year, @month, 1), "ja", :month) events = Iftb.where("dtstart between ? AND ?",@calendar.startdt, @calendar.enddt) @ending_events_by_days = events.group_by {|event| event.dtend} @starting_events_by_days = events.group_by {|event| event.dtstart}
viewも追加
<div class="calendar_label"> <%= link_to_previous_month(@year, @month) %> <%= select_year(@year, :prefix => "year", :discard_type => true) %> <%= select_month(@month, :prefix => "month", :discard_type => true) %> <%= link_to_next_month(@year, @month) %> </div> <% unless @calendar.nil? %> <%= render :partial => 'calendar', :locals => {:calendar => @calendar} %> <% end %>
redmine203/app/views/common/_calendar.html.erbをコピーしてapp_root/app/views/hoges/_calendar.html.erbに貼り付ける
とりあえず表示されるようになった。
_calendar.html.erbの
<% calendar.events_on(day).each do |i| %>
これで悩む。
app_root/lib/redmine/helpers/calendar.rbのevents_on(day)を参照してくれるけど中身が表示されない。。。。
app_root/lib/redmine/helpers/calendar.rbを改造する
def events_hoge=(events) @events = events @ending_events_by_days = events.group_by {|event| event.dtend.to_s(:date)} @starting_events_by_days = events.group_by {|event| event.dtstart.to_s(:date)} end
dtendとdestartはdatetime型なので文字列にしてからconfig/initalizers/datetime_formats.rbの「:date」パワーを使って「%Y-%m-%d"」に変換する。
_calendar.html.erbの
<% calendar.events_on(day.to_s).each do |i| %>
文字列に合わせてあげるとなんとかなった。
プルダウンメニューの年月が動いていいない(20121024追記)
いまさら気がついた。
アップデートする仕掛けが入っていない。
redmine203/app/views/calendar/show.html.erb
#3行目 <%= form_tag({:controller => 'calendars', :action => 'show', :project_id => @project}, :method => :get, :id => 'query_form') do %> #23行目 <%= link_to_function l(:button_apply), '$("query_form").submit()', :class => 'icon icon-checked' %>
変更してから、ボタンを押すことでフォームの値を送信する・・・あまりやりたくない。
こんなのを見つけた。
Rails select_tag の onchangeイベントによる form_tag action属性の変更
<%= form_tag :controller => "index", :action => "index" do %> <%= select_tag(:area_id, options_from_collection_for_select(@areas, :id, :area_name, @area_id), \:onchange => "this.form.submit()") %> <% end %>
このまま仕込むとNGだったので調べる。
http://www.ruby-forum.com/topic/176963
select_year(date, options = {}, html_options = {})
こんな感じに改造
<%= form_tag :action => "calendar" do %> <div class="calendar_label"> <%= link_to_previous_month(@year, @month) %> <%= select_year(@year, {:prefix => "year", :discard_type => true}, {:onchange => 'this.form.submit()'}) %> <%= select_month(@month, {:prefix => "month", :discard_type => true}, {:onchange => 'this.form.submit()'}) %> <%= link_to_next_month(@year, @month) %> </div> ・・・ <% end %>