2017年1月11日 星期三

製作月曆

製作月曆來顯示相對應日期的文章(未完成)
railscast PRO #213+
老實說因為block我還不熟,有些東西實在不是很懂怎樣跑的囧
總之先看到哪就先筆記到哪
code: https://github.com/telsaiori/ckeditor_test/blob/calendar/app/helpers/calendar_helper.rb
view:
  <%= calendar current_date do |date| %>
    <% date_key = date.strftime %>
    <% if posts_by_date[date_key] %> 
      <%= link_to date.day, posts_path(posts_by_date: date_key) %>
    <% else %>
      <%= date.day%>
    <% end %>
  <% end %>
code:
def calendar(date = Date.today, &block)
  Calendar.new(self, date, block).table
end

 class Calendar < Struct.new(:view, :date, :callback)
     Calendar.new(self, date, block).table
 end
這裡使用Struct.new(:view, :date, :callback)和設定attr_accessor :view, :date, :callback效果是一樣的
然後把self: 本來網頁的view
date: 當日日期
block:本來view裡面的block丟給Calendar然後由table method建出月曆
delegate主要是用來讓A class也可以使用別的class的method,這邊的話就是讓Calandar裡面也可以使用content_tag這個helper
不然會出現
undefined method `content_tag’ for CalendarHelper::Calendar:0x007fb442119330
   class Calendar < Struct.new(:view, :date, :callback)
      HEADER = %w[ 日 一 二 三 四 五 六]
      START_DAY = :sunday

      delegate :content_tag, to: :view

      def table
        content_tag :table, class: "calendar" do
          year_header + header + week_rows
        end
      end
下面生成table的過程就比較單純
生成星期幾的部分,因為前面已經定義好HEADER,這邊只是把它變成[“日“, “一“, “二“, “三“, “四“, “五“, “六“]然後再靠join轉成字串在用html_safe讓他可以正常輸出到view
   def header
        content_tag :tr do
          HEADER.map { |day| content_tag :th, day}.join.html_safe
        end
      end
生成一個星期的row,先用一開始代進來的date算出這星期的第一天和最後一天,然後和上面一樣轉成html
def week_rows
    weeks.map do |week|
      content_tag :tr do
        week.map { |day| day_cell(day) }.join.html_safe
      end
    end.join.html_safe
  end


  def weeks
    first = date.beginning_of_month.beginning_of_week(START_DAY)
    last = date.end_of_month.end_of_week(START_DAY)
    (first..last).to_a.in_groups_of(7)
  end
中間會先把日期丟給day_cell處理
capture可以把模板保留成string方便之後在需要的地方處理
以這邊的view.capture(day, &callback)就是會把目前正在處理的日期回傳給view裡面的block
比方如果目前處理到“Wed, 11 Jan 2017”
如果沒有文章,capture的結果會是”\n 11\n”
有文章的話會得到
“\n      <a href=\"/posts?posts_by_date=2017-01-11\">11</a>\n”
 <%= calendar current_date do |date| %>  
    <% date_key = date.strftime %>  
    <% if posts_by_date[date_key] %> 
      <%= link_to date.day, posts_path(posts_by_date: date_key) %>
    <% else %>
      <%= date.day%>
    <% end %>
  <% end %>




 def day_cell(day)
    content_tag :td, view.capture(day, &callback), class: day_classes(day)
  end

  def day_classes(day)
    classes = []
    classes << "today" if day == Date.today
    classes << "notmonth" if day.month != date.month
    classes.empty? ? nil : classes.join(" ")
  end
Written with StackEdit.

沒有留言:

張貼留言