later_dude 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +1 -0
- data/MIT-LICENSE +1 -1
- data/README +10 -2
- data/VERSION +1 -1
- data/lib/later_dude.rb +3 -204
- data/lib/later_dude/calendar.rb +194 -0
- data/lib/later_dude/calendar_helper.rb +7 -0
- data/lib/later_dude/rails2_compat.rb +7 -0
- data/tasks/distribution.rb +1 -1
- metadata +4 -1
data/CHANGELOG
CHANGED
data/MIT-LICENSE
CHANGED
data/README
CHANGED
@@ -16,12 +16,20 @@ You can use LaterDude either as a gem (preferred) or as a Rails plugin.
|
|
16
16
|
|
17
17
|
To use the gem version, put the following gem requirement in your environment.rb:
|
18
18
|
|
19
|
-
config.gem
|
19
|
+
config.gem 'later_dude', :source => 'http://gemcutter.org'
|
20
|
+
|
21
|
+
Or with Rails 3, add the gem requirement to your Gemfile:
|
22
|
+
|
23
|
+
gem 'later_dude', '>= 0.3.1' # 0.3.0 was broken!
|
20
24
|
|
21
25
|
To install it as a plugin, fire up your terminal, go to your Rails app and type:
|
22
26
|
|
23
27
|
$ ruby script/plugin install git://github.com/clemens/later_dude.git
|
24
28
|
|
29
|
+
To use the CalendarHelper, put this in a controller:
|
30
|
+
|
31
|
+
helper LaterDude::CalendarHelper
|
32
|
+
|
25
33
|
Examples
|
26
34
|
========
|
27
35
|
|
@@ -139,4 +147,4 @@ Bugs & Feedback
|
|
139
147
|
|
140
148
|
You can send me feedback, bug reports and patches via "GitHub":http://github.com/clemens.
|
141
149
|
|
142
|
-
Copyright (c) 2009 Clemens Kofler <clemens@railway.at>, released under the MIT license.
|
150
|
+
Copyright (c) 2009, 2010 Clemens Kofler <clemens@railway.at>, released under the MIT license.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.1
|
data/lib/later_dude.rb
CHANGED
@@ -1,204 +1,3 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
|
4
|
-
module CalendarHelper
|
5
|
-
def calendar_for(year, month, options={}, &block)
|
6
|
-
Calendar.new(year, month, options, &block).to_html
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
# TODO: Maybe make output prettier?
|
11
|
-
class Calendar
|
12
|
-
include ActionView::Helpers::CaptureHelper
|
13
|
-
include ActionView::Helpers::TagHelper
|
14
|
-
include ActionView::Helpers::UrlHelper
|
15
|
-
|
16
|
-
attr_accessor :output_buffer
|
17
|
-
|
18
|
-
def initialize(year, month, options={}, &block)
|
19
|
-
@year, @month = year, month
|
20
|
-
@options = options.symbolize_keys.reverse_merge(self.class.default_calendar_options)
|
21
|
-
|
22
|
-
# next_month and previous_month take precedence over next_and_previous_month
|
23
|
-
@options[:next_month] ||= @options[:next_and_previous_month]
|
24
|
-
@options[:previous_month] ||= @options[:next_and_previous_month]
|
25
|
-
|
26
|
-
@days = Date.civil(@year, @month, 1)..Date.civil(@year, @month, -1)
|
27
|
-
@block = block
|
28
|
-
end
|
29
|
-
|
30
|
-
def to_html
|
31
|
-
content_tag(:table, :class => "#{@options[:calendar_class]}") do
|
32
|
-
content_tag(:tbody, show_days)+ content_tag(:thead, "#{show_month_names}#{show_day_names}".html_safe)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
def show_days
|
38
|
-
content_tag(:tr, "#{show_previous_month}#{show_current_month}#{show_following_month}".html_safe)
|
39
|
-
end
|
40
|
-
|
41
|
-
def show_previous_month
|
42
|
-
return if @days.first.wday == first_day_of_week # don't display anything if the first day is the first day of a week
|
43
|
-
|
44
|
-
returning "" do |output|
|
45
|
-
beginning_of_week(@days.first).upto(@days.first - 1) { |d| output << show_day(d) }
|
46
|
-
end.html_safe
|
47
|
-
end
|
48
|
-
|
49
|
-
def show_current_month
|
50
|
-
returning "" do |output|
|
51
|
-
@days.first.upto(@days.last) { |d| output << show_day(d) }
|
52
|
-
end.html_safe
|
53
|
-
end
|
54
|
-
|
55
|
-
def show_following_month
|
56
|
-
return if @days.last.wday == last_day_of_week # don't display anything if the last day is the last day of a week
|
57
|
-
|
58
|
-
returning "" do |output|
|
59
|
-
(@days.last + 1).upto(beginning_of_week(@days.last + 1.week) - 1) { |d| output << show_day(d) }
|
60
|
-
end.html_safe
|
61
|
-
end
|
62
|
-
|
63
|
-
def show_day(day)
|
64
|
-
options = { :class => "day" }
|
65
|
-
options[:class] << " otherMonth" if day.month != @days.first.month
|
66
|
-
options[:class] << " weekend" if Calendar.weekend?(day)
|
67
|
-
options[:class] << " today" if day.today?
|
68
|
-
|
69
|
-
# block is only called for current month or if :yield_surrounding_days is set to true
|
70
|
-
if @block && (@options[:yield_surrounding_days] || day.month == @days.first.month)
|
71
|
-
content, options_from_block = Array(@block.call(day))
|
72
|
-
|
73
|
-
# passing options is optional
|
74
|
-
if options_from_block.is_a?(Hash)
|
75
|
-
options[:class] << " #{options_from_block.delete(:class)}" if options_from_block[:class]
|
76
|
-
options.merge!(options_from_block)
|
77
|
-
end
|
78
|
-
else
|
79
|
-
content = day.day
|
80
|
-
end
|
81
|
-
|
82
|
-
content = content_tag(:td, content.to_s.html_safe, options)
|
83
|
-
|
84
|
-
# close table row at the end of a week and start a new one
|
85
|
-
# opening and closing tag for the first and last week are included in #show_days
|
86
|
-
content << "</tr><tr>".html_safe if day < @days.last && day.wday == last_day_of_week
|
87
|
-
content
|
88
|
-
end
|
89
|
-
|
90
|
-
def beginning_of_week(day)
|
91
|
-
diff = day.wday - first_day_of_week
|
92
|
-
diff += 7 if first_day_of_week > day.wday # hackish ;-)
|
93
|
-
day - diff
|
94
|
-
end
|
95
|
-
|
96
|
-
def show_month_names
|
97
|
-
return if @options[:hide_month_name]
|
98
|
-
|
99
|
-
content_tag(:tr, "#{previous_month}#{current_month}#{next_month}".html_safe, :class => 'month_names')
|
100
|
-
end
|
101
|
-
|
102
|
-
# @options[:previous_month] can either be a single value or an array containing two values. For a single value, the
|
103
|
-
# value can either be a strftime compatible string or a proc.
|
104
|
-
# For an array, the first value is considered to be a strftime compatible string and the second is considered to be
|
105
|
-
# a proc. If the second value is not a proc then it will be ignored.
|
106
|
-
def previous_month
|
107
|
-
return unless @options[:previous_month]
|
108
|
-
|
109
|
-
show_month(@days.first - 1.month, @options[:previous_month], :class => "previous")
|
110
|
-
end
|
111
|
-
|
112
|
-
# see previous_month
|
113
|
-
def next_month
|
114
|
-
return unless @options[:next_month]
|
115
|
-
|
116
|
-
show_month(@days.first + 1.month, @options[:next_month], :class => "next")
|
117
|
-
end
|
118
|
-
|
119
|
-
# see previous_month and next_month
|
120
|
-
def current_month
|
121
|
-
colspan = @options[:previous_month] || @options[:next_month] ? 3 : 7 # span across all 7 days if previous and next month aren't shown
|
122
|
-
|
123
|
-
show_month(@days.first, @options[:current_month], :colspan => colspan, :class => "current")
|
124
|
-
end
|
125
|
-
|
126
|
-
def show_month(month, format, options={})
|
127
|
-
options[:colspan] ||= 2
|
128
|
-
|
129
|
-
content_tag(:th, :colspan => options[:colspan], :class => "#{options[:class]} #{Date::MONTHNAMES[month.month].downcase}") do
|
130
|
-
if format.kind_of?(Array) && format.size == 2
|
131
|
-
text = I18n.localize(month, :format => format.first.to_s).html_safe
|
132
|
-
format.last.respond_to?(:call) ? link_to(text, format.last.call(month)) : text
|
133
|
-
else
|
134
|
-
format.respond_to?(:call) ? format.call(month) : I18n.localize(month, :format => format.to_s).html_safe
|
135
|
-
end
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
def day_names
|
140
|
-
@day_names ||= @options[:use_full_day_names] ? full_day_names : abbreviated_day_names
|
141
|
-
end
|
142
|
-
|
143
|
-
def full_day_names
|
144
|
-
@full_day_names ||= I18n.translate(:'date.day_names')
|
145
|
-
end
|
146
|
-
|
147
|
-
def abbreviated_day_names
|
148
|
-
@abbreviated_day_names ||= I18n.translate(:'date.abbr_day_names')
|
149
|
-
end
|
150
|
-
|
151
|
-
def show_day_names
|
152
|
-
return if @options[:hide_day_names]
|
153
|
-
content_tag(:tr, :class => 'day_names') do
|
154
|
-
apply_first_day_of_week(day_names).inject('') do |output, day|
|
155
|
-
output << content_tag(:th, include_day_abbreviation(day), :scope => 'col', :class => Date::DAYNAMES[day_names.index(day)].downcase)
|
156
|
-
end.html_safe
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
# => <abbr title="Sunday">Sun</abbr>
|
161
|
-
def include_day_abbreviation(day)
|
162
|
-
return day if @options[:use_full_day_names]
|
163
|
-
|
164
|
-
content_tag(:abbr, day, :title => full_day_names[abbreviated_day_names.index(day)])
|
165
|
-
end
|
166
|
-
|
167
|
-
def apply_first_day_of_week(day_names)
|
168
|
-
names = day_names.dup
|
169
|
-
first_day_of_week.times { names.push(names.shift) }
|
170
|
-
names
|
171
|
-
end
|
172
|
-
|
173
|
-
def first_day_of_week
|
174
|
-
@options[:first_day_of_week]
|
175
|
-
end
|
176
|
-
|
177
|
-
def last_day_of_week
|
178
|
-
@options[:first_day_of_week] > 0 ? @options[:first_day_of_week] - 1 : 6
|
179
|
-
end
|
180
|
-
|
181
|
-
class << self
|
182
|
-
def weekend?(day)
|
183
|
-
[0,6].include?(day.wday) # 0 = Sunday, 6 = Saturday
|
184
|
-
end
|
185
|
-
|
186
|
-
def default_calendar_options
|
187
|
-
{
|
188
|
-
:calendar_class => "calendar",
|
189
|
-
:first_day_of_week => I18n.translate(:'date.first_day_of_week', :default => "0").to_i,
|
190
|
-
:hide_day_names => false,
|
191
|
-
:hide_month_name => false,
|
192
|
-
:use_full_day_names => false,
|
193
|
-
:current_month => I18n.translate(:'date.formats.calendar_header', :default => "%B"),
|
194
|
-
:next_month => false,
|
195
|
-
:previous_month => false,
|
196
|
-
:next_and_previous_month => false,
|
197
|
-
:yield_surrounding_days => false
|
198
|
-
}
|
199
|
-
end
|
200
|
-
end
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
ActionView::Base.send(:include, LaterDude::CalendarHelper)
|
1
|
+
require 'later_dude/calendar'
|
2
|
+
require 'later_dude/calendar_helper'
|
3
|
+
require 'later_dude/rails2_compat'
|
@@ -0,0 +1,194 @@
|
|
1
|
+
module LaterDude
|
2
|
+
# TODO: Maybe make output prettier?
|
3
|
+
class Calendar
|
4
|
+
include ActionView::Helpers::CaptureHelper
|
5
|
+
include ActionView::Helpers::TagHelper
|
6
|
+
include ActionView::Helpers::UrlHelper
|
7
|
+
|
8
|
+
attr_accessor :output_buffer
|
9
|
+
|
10
|
+
def initialize(year, month, options={}, &block)
|
11
|
+
@year, @month = year, month
|
12
|
+
@options = options.symbolize_keys.reverse_merge(self.class.default_calendar_options)
|
13
|
+
|
14
|
+
# next_month and previous_month take precedence over next_and_previous_month
|
15
|
+
@options[:next_month] ||= @options[:next_and_previous_month]
|
16
|
+
@options[:previous_month] ||= @options[:next_and_previous_month]
|
17
|
+
|
18
|
+
@days = Date.civil(@year, @month, 1)..Date.civil(@year, @month, -1)
|
19
|
+
@block = block
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_html
|
23
|
+
content_tag(:table, :class => "#{@options[:calendar_class]}") do
|
24
|
+
content_tag(:tbody, show_days)+ content_tag(:thead, "#{show_month_names}#{show_day_names}".html_safe)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
def show_days
|
30
|
+
content_tag(:tr, "#{show_previous_month}#{show_current_month}#{show_following_month}".html_safe)
|
31
|
+
end
|
32
|
+
|
33
|
+
def show_previous_month
|
34
|
+
return if @days.first.wday == first_day_of_week # don't display anything if the first day is the first day of a week
|
35
|
+
|
36
|
+
returning "" do |output|
|
37
|
+
beginning_of_week(@days.first).upto(@days.first - 1) { |d| output << show_day(d) }
|
38
|
+
end.html_safe
|
39
|
+
end
|
40
|
+
|
41
|
+
def show_current_month
|
42
|
+
returning "" do |output|
|
43
|
+
@days.first.upto(@days.last) { |d| output << show_day(d) }
|
44
|
+
end.html_safe
|
45
|
+
end
|
46
|
+
|
47
|
+
def show_following_month
|
48
|
+
return if @days.last.wday == last_day_of_week # don't display anything if the last day is the last day of a week
|
49
|
+
|
50
|
+
returning "" do |output|
|
51
|
+
(@days.last + 1).upto(beginning_of_week(@days.last + 1.week) - 1) { |d| output << show_day(d) }
|
52
|
+
end.html_safe
|
53
|
+
end
|
54
|
+
|
55
|
+
def show_day(day)
|
56
|
+
options = { :class => "day" }
|
57
|
+
options[:class] << " otherMonth" if day.month != @days.first.month
|
58
|
+
options[:class] << " weekend" if Calendar.weekend?(day)
|
59
|
+
options[:class] << " today" if day.today?
|
60
|
+
|
61
|
+
# block is only called for current month or if :yield_surrounding_days is set to true
|
62
|
+
if @block && (@options[:yield_surrounding_days] || day.month == @days.first.month)
|
63
|
+
content, options_from_block = Array(@block.call(day))
|
64
|
+
|
65
|
+
# passing options is optional
|
66
|
+
if options_from_block.is_a?(Hash)
|
67
|
+
options[:class] << " #{options_from_block.delete(:class)}" if options_from_block[:class]
|
68
|
+
options.merge!(options_from_block)
|
69
|
+
end
|
70
|
+
else
|
71
|
+
content = day.day
|
72
|
+
end
|
73
|
+
|
74
|
+
content = content_tag(:td, content.to_s.html_safe, options)
|
75
|
+
|
76
|
+
# close table row at the end of a week and start a new one
|
77
|
+
# opening and closing tag for the first and last week are included in #show_days
|
78
|
+
content << "</tr><tr>".html_safe if day < @days.last && day.wday == last_day_of_week
|
79
|
+
content
|
80
|
+
end
|
81
|
+
|
82
|
+
def beginning_of_week(day)
|
83
|
+
diff = day.wday - first_day_of_week
|
84
|
+
diff += 7 if first_day_of_week > day.wday # hackish ;-)
|
85
|
+
day - diff
|
86
|
+
end
|
87
|
+
|
88
|
+
def show_month_names
|
89
|
+
return if @options[:hide_month_name]
|
90
|
+
|
91
|
+
content_tag(:tr, "#{previous_month}#{current_month}#{next_month}".html_safe, :class => 'month_names')
|
92
|
+
end
|
93
|
+
|
94
|
+
# @options[:previous_month] can either be a single value or an array containing two values. For a single value, the
|
95
|
+
# value can either be a strftime compatible string or a proc.
|
96
|
+
# For an array, the first value is considered to be a strftime compatible string and the second is considered to be
|
97
|
+
# a proc. If the second value is not a proc then it will be ignored.
|
98
|
+
def previous_month
|
99
|
+
return unless @options[:previous_month]
|
100
|
+
|
101
|
+
show_month(@days.first - 1.month, @options[:previous_month], :class => "previous")
|
102
|
+
end
|
103
|
+
|
104
|
+
# see previous_month
|
105
|
+
def next_month
|
106
|
+
return unless @options[:next_month]
|
107
|
+
|
108
|
+
show_month(@days.first + 1.month, @options[:next_month], :class => "next")
|
109
|
+
end
|
110
|
+
|
111
|
+
# see previous_month and next_month
|
112
|
+
def current_month
|
113
|
+
colspan = @options[:previous_month] || @options[:next_month] ? 3 : 7 # span across all 7 days if previous and next month aren't shown
|
114
|
+
|
115
|
+
show_month(@days.first, @options[:current_month], :colspan => colspan, :class => "current")
|
116
|
+
end
|
117
|
+
|
118
|
+
def show_month(month, format, options={})
|
119
|
+
options[:colspan] ||= 2
|
120
|
+
|
121
|
+
content_tag(:th, :colspan => options[:colspan], :class => "#{options[:class]} #{Date::MONTHNAMES[month.month].downcase}") do
|
122
|
+
if format.kind_of?(Array) && format.size == 2
|
123
|
+
text = I18n.localize(month, :format => format.first.to_s).html_safe
|
124
|
+
format.last.respond_to?(:call) ? link_to(text, format.last.call(month)) : text
|
125
|
+
else
|
126
|
+
format.respond_to?(:call) ? format.call(month) : I18n.localize(month, :format => format.to_s).html_safe
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def day_names
|
132
|
+
@day_names ||= @options[:use_full_day_names] ? full_day_names : abbreviated_day_names
|
133
|
+
end
|
134
|
+
|
135
|
+
def full_day_names
|
136
|
+
@full_day_names ||= I18n.translate(:'date.day_names')
|
137
|
+
end
|
138
|
+
|
139
|
+
def abbreviated_day_names
|
140
|
+
@abbreviated_day_names ||= I18n.translate(:'date.abbr_day_names')
|
141
|
+
end
|
142
|
+
|
143
|
+
def show_day_names
|
144
|
+
return if @options[:hide_day_names]
|
145
|
+
content_tag(:tr, :class => 'day_names') do
|
146
|
+
apply_first_day_of_week(day_names).inject('') do |output, day|
|
147
|
+
output << content_tag(:th, include_day_abbreviation(day), :scope => 'col', :class => Date::DAYNAMES[day_names.index(day)].downcase)
|
148
|
+
end.html_safe
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
# => <abbr title="Sunday">Sun</abbr>
|
153
|
+
def include_day_abbreviation(day)
|
154
|
+
return day if @options[:use_full_day_names]
|
155
|
+
|
156
|
+
content_tag(:abbr, day, :title => full_day_names[abbreviated_day_names.index(day)])
|
157
|
+
end
|
158
|
+
|
159
|
+
def apply_first_day_of_week(day_names)
|
160
|
+
names = day_names.dup
|
161
|
+
first_day_of_week.times { names.push(names.shift) }
|
162
|
+
names
|
163
|
+
end
|
164
|
+
|
165
|
+
def first_day_of_week
|
166
|
+
@options[:first_day_of_week]
|
167
|
+
end
|
168
|
+
|
169
|
+
def last_day_of_week
|
170
|
+
@options[:first_day_of_week] > 0 ? @options[:first_day_of_week] - 1 : 6
|
171
|
+
end
|
172
|
+
|
173
|
+
class << self
|
174
|
+
def weekend?(day)
|
175
|
+
[0,6].include?(day.wday) # 0 = Sunday, 6 = Saturday
|
176
|
+
end
|
177
|
+
|
178
|
+
def default_calendar_options
|
179
|
+
{
|
180
|
+
:calendar_class => "calendar",
|
181
|
+
:first_day_of_week => I18n.translate(:'date.first_day_of_week', :default => "0").to_i,
|
182
|
+
:hide_day_names => false,
|
183
|
+
:hide_month_name => false,
|
184
|
+
:use_full_day_names => false,
|
185
|
+
:current_month => I18n.translate(:'date.formats.calendar_header', :default => "%B"),
|
186
|
+
:next_month => false,
|
187
|
+
:previous_month => false,
|
188
|
+
:next_and_previous_month => false,
|
189
|
+
:yield_surrounding_days => false
|
190
|
+
}
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
data/tasks/distribution.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: later_dude
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Clemens Kofler
|
@@ -29,6 +29,9 @@ files:
|
|
29
29
|
- VERSION
|
30
30
|
- init.rb
|
31
31
|
- lib/later_dude.rb
|
32
|
+
- lib/later_dude/calendar.rb
|
33
|
+
- lib/later_dude/calendar_helper.rb
|
34
|
+
- lib/later_dude/rails2_compat.rb
|
32
35
|
- tasks/distribution.rb
|
33
36
|
- tasks/documentation.rb
|
34
37
|
- tasks/testing.rb
|