event_calendar 0.0.0 → 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +39 -5
- data/Rakefile +1 -29
- data/assets/javascripts/{calendar.js → event_calendar.prototype.js} +3 -3
- data/assets/stylesheets/{calendar.css → event_calendar.css} +20 -20
- data/lib/event_calendar.rb +112 -21
- data/lib/event_calendar/event.rb +74 -0
- data/lib/{calendar → event_calendar}/stylesheet.sass +2 -2
- data/lib/{calendar → event_calendar}/template.mab +23 -23
- data/lib/event_calendar/week.rb +67 -0
- data/lib/tasks/generate.rake +22 -24
- data/test/date_test.rb +14 -0
- data/test/event_calendar_test.rb +82 -0
- data/test/event_test.rb +59 -0
- data/test/fixtures/template.mab +2 -0
- data/test/test_helper.rb +25 -0
- data/test/week_test.rb +33 -0
- metadata +18 -13
- data/VERSION +0 -1
- data/assets/javascripts/prototype-1.6.1.js +0 -4874
- data/assets/stylesheets/yui-2.7.0.css +0 -13
- data/lib/calendar/event.rb +0 -46
- data/lib/calendar/week.rb +0 -34
- data/test/calendar_test.rb +0 -13
data/README.rdoc
CHANGED
@@ -1,17 +1,43 @@
|
|
1
1
|
= event_calendar
|
2
2
|
|
3
|
-
Generates HTML event calendars
|
3
|
+
Generates HTML event calendars
|
4
4
|
|
5
|
-
INCOMPLETE
|
6
5
|
|
7
6
|
== Installation
|
8
7
|
|
9
|
-
gem install event_calendar
|
8
|
+
gem install event_calendar
|
9
|
+
|
10
10
|
|
11
11
|
== Usage
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
=== Basic
|
14
|
+
|
15
|
+
@event_calendar = EventCalendar.new(2009, 10, :events => Event.all)
|
16
|
+
puts @event_calendar.to_html
|
17
|
+
|
18
|
+
=== Options
|
19
|
+
|
20
|
+
The <tt>EventCalendar.new</tt> method accepts a hash or block of options, for example:
|
21
|
+
|
22
|
+
@event_calendar = EventCalendar.new(2009, 10, :id => 'calendar', :events => Event.all)
|
23
|
+
|
24
|
+
@event_calendar = EventCalendar.new(2009, 10) do |c|
|
25
|
+
c.id = 'calendar'
|
26
|
+
c.events = Event.all
|
27
|
+
end
|
28
|
+
|
29
|
+
See the documentation for the <tt>EventCalendar</tt> class at http://rdoc.info/projects/shuber/event_calendar for a list of available options.
|
30
|
+
|
31
|
+
=== Assets
|
32
|
+
|
33
|
+
rake event_calendar:generate:css # Generates css for the event calendar
|
34
|
+
rake event_calendar:generate:js # Generates js for the event calendar
|
35
|
+
rake event_calendar:generate:sandbox # Creates a sandbox in the current working directory for testing
|
36
|
+
|
37
|
+
==== Note
|
38
|
+
|
39
|
+
The default css was built on YUI (See http://developer.yahoo.com/yui) and javascript on Prototype (See http://www.prototypejs.org).
|
40
|
+
|
15
41
|
|
16
42
|
== Note on Patches/Pull Requests
|
17
43
|
|
@@ -24,6 +50,14 @@ INCOMPLETE
|
|
24
50
|
bump version in a commit by itself I can ignore when I pull)
|
25
51
|
* Send me a pull request. Bonus points for topic branches.
|
26
52
|
|
53
|
+
|
54
|
+
== TODO
|
55
|
+
|
56
|
+
* Break Markaby template down into sections so that it's easier to overwrite certain parts
|
57
|
+
* Dynamic height calculations for calendar days in JavaScript
|
58
|
+
* jQuery support
|
59
|
+
|
60
|
+
|
27
61
|
== Copyright
|
28
62
|
|
29
63
|
Copyright (c) 2009 Sean Huber. See MIT-LICENSE for details.
|
data/Rakefile
CHANGED
@@ -1,26 +1,6 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'rake'
|
3
3
|
|
4
|
-
begin
|
5
|
-
require 'jeweler'
|
6
|
-
Jeweler::Tasks.new do |gem|
|
7
|
-
gem.name = 'event_calendar'
|
8
|
-
gem.summary = 'Generates HTML event calendars'
|
9
|
-
gem.description = 'Generates HTML event calendars'
|
10
|
-
gem.email = 'shuber@huberry.com'
|
11
|
-
gem.homepage = 'http://github.com/shuber/event_calendar'
|
12
|
-
gem.authors = ['Sean Huber']
|
13
|
-
gem.add_dependency 'activesupport'
|
14
|
-
gem.add_dependency 'markaby'
|
15
|
-
gem.add_dependency 'haml'
|
16
|
-
gem.add_development_dependency 'shoulda'
|
17
|
-
gem.add_development_dependency 'timecop'
|
18
|
-
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
19
|
-
end
|
20
|
-
rescue LoadError
|
21
|
-
puts 'Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler'
|
22
|
-
end
|
23
|
-
|
24
4
|
require 'rake/testtask'
|
25
5
|
Rake::TestTask.new(:test) do |test|
|
26
6
|
test.libs << 'lib' << 'test'
|
@@ -41,20 +21,12 @@ rescue LoadError
|
|
41
21
|
end
|
42
22
|
end
|
43
23
|
|
44
|
-
task :test => :check_dependencies
|
45
|
-
|
46
24
|
task :default => :test
|
47
25
|
|
48
26
|
require 'rake/rdoctask'
|
49
27
|
Rake::RDocTask.new do |rdoc|
|
50
|
-
if File.exist?('VERSION')
|
51
|
-
version = File.read('VERSION')
|
52
|
-
else
|
53
|
-
version = ""
|
54
|
-
end
|
55
|
-
|
56
28
|
rdoc.rdoc_dir = 'rdoc'
|
57
|
-
rdoc.title = "event_calendar
|
29
|
+
rdoc.title = "event_calendar"
|
58
30
|
rdoc.rdoc_files.include('README*')
|
59
31
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
60
32
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
var
|
1
|
+
var EventCalendar = Class.create({
|
2
2
|
|
3
3
|
options: $H({
|
4
4
|
events_css_path: '.event',
|
@@ -16,7 +16,7 @@ var Calendar = Class.create({
|
|
16
16
|
this.add_hover_behavior_to_event(event);
|
17
17
|
}.bind(this));
|
18
18
|
|
19
|
-
|
19
|
+
EventCalendar.instances.push(this);
|
20
20
|
},
|
21
21
|
|
22
22
|
add_fields_to_event: function(event) {
|
@@ -52,4 +52,4 @@ var Calendar = Class.create({
|
|
52
52
|
|
53
53
|
});
|
54
54
|
|
55
|
-
|
55
|
+
EventCalendar.instances = [];
|
@@ -1,22 +1,22 @@
|
|
1
|
-
.
|
1
|
+
.event_calendar table {
|
2
2
|
border-collapse: collapse;
|
3
3
|
margin: 0;
|
4
4
|
width: 100%; }
|
5
|
-
.
|
5
|
+
.event_calendar table td {
|
6
6
|
border-bottom: 0px solid transparent !important;
|
7
7
|
width: 14.285%; }
|
8
|
-
.
|
8
|
+
.event_calendar .days {
|
9
9
|
position: relative; }
|
10
|
-
.
|
10
|
+
.event_calendar .days table.grid {
|
11
11
|
z-index: 1; }
|
12
|
-
.
|
12
|
+
.event_calendar .days .events {
|
13
13
|
left: 0px;
|
14
14
|
position: absolute;
|
15
15
|
table-layout: fixed;
|
16
16
|
text-align: left;
|
17
17
|
top: 0px;
|
18
18
|
z-index: 2; }
|
19
|
-
.
|
19
|
+
.event_calendar .days .events td {
|
20
20
|
border-bottom-width: 0px;
|
21
21
|
border-left-width: 0px;
|
22
22
|
border-color: transparent;
|
@@ -24,47 +24,47 @@
|
|
24
24
|
padding: 0;
|
25
25
|
text-overflow: ellipsis;
|
26
26
|
white-space: nowrap; }
|
27
|
-
.
|
27
|
+
.event_calendar .days .events td a {
|
28
28
|
background-color: transparent;
|
29
29
|
cursor: pointer;
|
30
30
|
display: block;
|
31
31
|
padding: 1px 3px;
|
32
32
|
text-decoration: none; }
|
33
|
-
.
|
33
|
+
.event_calendar .days .events td .fields {
|
34
34
|
display: none; }
|
35
|
-
.
|
35
|
+
.event_calendar .days .events tr.grid td {
|
36
36
|
border-top-width: 0px;
|
37
37
|
height: 0px; }
|
38
38
|
|
39
|
-
.
|
39
|
+
.event_calendar {
|
40
40
|
border-bottom: 1px solid #d4d5d4; }
|
41
|
-
.
|
41
|
+
.event_calendar table td {
|
42
42
|
border-color: #d4d5d4;
|
43
43
|
border-width: 1px; }
|
44
|
-
.
|
44
|
+
.event_calendar .navigation td {
|
45
45
|
border-color: transparent; }
|
46
|
-
.
|
46
|
+
.event_calendar table.grid {
|
47
47
|
background-color: #fefffe;
|
48
48
|
height: 125px; }
|
49
|
-
.
|
49
|
+
.event_calendar .label {
|
50
50
|
background-color: #ebede2;
|
51
51
|
border-top-width: 1px;
|
52
52
|
color: black; }
|
53
|
-
.
|
53
|
+
.event_calendar .header .label {
|
54
54
|
background-color: #2f302f;
|
55
55
|
color: white; }
|
56
|
-
.
|
56
|
+
.event_calendar .days .events td {
|
57
57
|
border-top-width: 3px; }
|
58
|
-
.
|
58
|
+
.event_calendar .days .events td a {
|
59
59
|
background-color: #9aac9a;
|
60
60
|
color: white;
|
61
61
|
-khtml-border-radius: 5px;
|
62
62
|
-moz-border-radius: 5px;
|
63
63
|
-webkit-border-radius: 5px;
|
64
64
|
border-radius: 5px; }
|
65
|
-
.
|
65
|
+
.event_calendar .days .events td:hover a, .event_calendar .days .events td.hover a {
|
66
66
|
background-color: #6f7f6f; }
|
67
|
-
.
|
67
|
+
.event_calendar .days .events td.continuation a {
|
68
68
|
-khtml-border-radius-bottomleft: 0px;
|
69
69
|
-moz-border-radius-bottomleft: 0px;
|
70
70
|
-webkit-border-bottom-left-radius: 0px;
|
@@ -73,7 +73,7 @@
|
|
73
73
|
-moz-border-radius-topleft: 0px;
|
74
74
|
-webkit-border-top-left-radius: 0px;
|
75
75
|
border-top-left-radius: 0px; }
|
76
|
-
.
|
76
|
+
.event_calendar .days .events td.continued a {
|
77
77
|
-khtml-border-radius-bottomright: 0px;
|
78
78
|
-moz-border-radius-bottomright: 0px;
|
79
79
|
-webkit-border-bottom-right-radius: 0px;
|
data/lib/event_calendar.rb
CHANGED
@@ -1,22 +1,52 @@
|
|
1
|
-
require '
|
1
|
+
require 'active_support'
|
2
2
|
require 'markaby'
|
3
3
|
require 'haml'
|
4
|
-
require '
|
5
|
-
require '
|
4
|
+
require 'event_calendar/event'
|
5
|
+
require 'event_calendar/week'
|
6
6
|
|
7
|
+
# Adds an <tt>:events</tt> <tt>attr_accessor</tt> to the <tt>Date</tt> object.
|
7
8
|
Date.class_eval { attr_accessor :events }
|
8
9
|
|
9
|
-
|
10
|
+
# Generates HTML calendars
|
11
|
+
class EventCalendar
|
10
12
|
|
11
13
|
extend ActiveSupport::Memoizable
|
12
14
|
|
13
15
|
undef_method :id
|
14
16
|
|
15
|
-
attr_accessor :events, :
|
17
|
+
attr_accessor :events, :options
|
18
|
+
attr_reader :month, :year
|
16
19
|
|
20
|
+
# The default options used when generating event calendars
|
21
|
+
#
|
22
|
+
# :id => The HTML id of the generated container div for this event calendar. Defaults to 'event_calendar'.
|
23
|
+
# :beginning_of_week => The day number to use as the beginning of the week. For example, 0 is for Sunday, 1 is for Monday, etc.
|
24
|
+
# Defaults to 0.
|
25
|
+
# :day_label * => The label to use for each day. Defaults to the day number.
|
26
|
+
# :event_class ** => The HTML class to add to each event. Defaults to nil.
|
27
|
+
# :event_id ** => The id (object_id or database id) of an event. Defaults to :id.
|
28
|
+
# :event_title ** => The title of an event. Defaults to :title.
|
29
|
+
# :event_start ** => The start date or datetime of an event. Defaults to :starts_at.
|
30
|
+
# :event_end ** => The end date or datetime of an event. Defaults to :ends_at.
|
31
|
+
# :event_url ** => The url of an event to use as the HTML href attribute. Defaults to '#'.
|
32
|
+
# :event_output ** => The HTML to output for an event. Defaults to a link to the :event_url using the :event_title
|
33
|
+
# as its label and title attributes.
|
34
|
+
# :event_fields ** => The event fields to output as hidden attributes into the calendar so that they can be accessed with
|
35
|
+
# javascript. Defaults to [:id, :title, :start, :end].
|
36
|
+
# :events => An array of events to display in the calendar. Defaults to [].
|
37
|
+
# :header_label * => The label to use as the header of the calendar. Defaults to the month name and year like 'October 2009'.
|
38
|
+
# :header_day_label * => The label to use as the header of each day. Defaults to the abbreviated day name like 'Thu'.
|
39
|
+
# :navigation_label * => The label to use as the inner HTML for the navigation links. Defaults to the full month name like 'November'.
|
40
|
+
# :navigation_url => A proc which returns the url to use as the HTML href attribute for the previous and next month links.
|
41
|
+
# This proc is passed a date object representing the first day of the previous or next months. Defaults to '#'.
|
42
|
+
# :template => A path to the Markaby template file to use when rendering the calendar. Defaults to the 'event_calendar/template.mab'
|
43
|
+
# file found in this directory.
|
44
|
+
#
|
45
|
+
# * See the EventCalendar.evaluate_date_format_option method for possible values.
|
46
|
+
# ** See the Event#evaluate_option method for possible values.
|
17
47
|
def self.default_options
|
18
48
|
@default_options ||= {
|
19
|
-
:id => '
|
49
|
+
:id => 'event_calendar',
|
20
50
|
:beginning_of_week => 0,
|
21
51
|
:day_label => proc { |date| date.strftime('%d').gsub(/^0/, '') },
|
22
52
|
:event_class => nil,
|
@@ -24,42 +54,81 @@ class Calendar
|
|
24
54
|
:event_title => :title,
|
25
55
|
:event_start => :starts_at,
|
26
56
|
:event_end => :ends_at,
|
27
|
-
:
|
57
|
+
:event_url => '#',
|
58
|
+
:event_output => proc { |event| "<a href=\"#{event.url}\" title=\"#{event.title}\">#{event.title}</a>" },
|
28
59
|
:event_fields => [:id, :title, :start, :end],
|
29
60
|
:events => [],
|
30
61
|
:header_label => '%B %Y',
|
31
62
|
:header_day_label => '%a',
|
32
63
|
:navigation_label => '%B',
|
33
64
|
:navigation_url => proc { |date| '#' },
|
34
|
-
:template => File.join(File.dirname(__FILE__), '
|
65
|
+
:template => File.join(File.dirname(__FILE__), 'event_calendar', 'template.mab')
|
35
66
|
}
|
36
67
|
end
|
37
68
|
|
69
|
+
# Optionally accepts a <tt>year</tt> as the first argument, a <tt>month</tt> (integer) as the second argument, and a
|
70
|
+
# hash of options as the third argument. It also accepts a block which it passes itself to.
|
71
|
+
#
|
72
|
+
# For example:
|
73
|
+
#
|
74
|
+
# @event_calendar = EventCalendar.new
|
75
|
+
#
|
76
|
+
# @event_calendar = EventCalendar.new(2009, 10, :id => 'calendar', :events => Event.all)
|
77
|
+
#
|
78
|
+
# @event_calendar = EventCalendar.new(2009, 10) do |c|
|
79
|
+
# c.id = 'calendar'
|
80
|
+
# c.events = Event.all
|
81
|
+
# end
|
38
82
|
def initialize(year = Time.now.year, month = Time.now.month, options = {})
|
39
|
-
|
40
|
-
|
83
|
+
@year, @month, self.options = year, month, self.class.default_options.merge(options)
|
84
|
+
@events = self.options.delete(:events).collect { |event| Event.new(event, self.options) }.sort_by(&:start)
|
41
85
|
yield self if block_given?
|
42
86
|
end
|
43
87
|
|
88
|
+
# Returns a date object representing the first day of this <tt>EventCalendar</tt> instance's specified <tt>year</tt> and <tt>month</tt>.
|
44
89
|
def date
|
45
90
|
Date.civil(year, month, 1)
|
46
91
|
end
|
47
92
|
memoize :date
|
48
93
|
|
94
|
+
# Looks up the specified option representing a date format and returns the evaluated the result.
|
95
|
+
#
|
96
|
+
# This is used inside the <tt>Markaby</tt> template. For example, we have an option <tt>:header_label</tt> which
|
97
|
+
# represents the content at the top of the calendar that outputs the month name and year by default, like
|
98
|
+
# "October 2009".
|
99
|
+
#
|
100
|
+
# Inside the template, we call <tt>event_calendar.evaluate_date_format_option(:header_label, event_calendar.date)</tt>.
|
101
|
+
#
|
102
|
+
# If <tt>options[:header_label]</tt> is a string, it takes <tt>event_calendar.date</tt> and calls <tt>strftime(options[:header_label])</tt>
|
103
|
+
# on it.
|
104
|
+
#
|
105
|
+
# If it's a symbol, it takes <tt>event_calendar.date</tt> and calls <tt>send(options[:header_label])</tt> on it.
|
106
|
+
#
|
107
|
+
# If it's a proc, it calls the proc and passes <tt>event_calendar.date</tt> to it. You can pass any number of args to this method
|
108
|
+
# and they'll passed to the proc.
|
109
|
+
#
|
110
|
+
# Any other value for <tt>options[:header_label]</tt> is simply returned.
|
49
111
|
def evaluate_date_format_option(option, *args)
|
50
112
|
value = self.send(option)
|
51
113
|
case value
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
114
|
+
when String
|
115
|
+
args.first.strftime(value)
|
116
|
+
when Symbol
|
117
|
+
args.first.send(value)
|
118
|
+
when Proc
|
119
|
+
value.call(*args)
|
120
|
+
else
|
121
|
+
value
|
60
122
|
end
|
61
123
|
end
|
62
124
|
|
125
|
+
# Allows you to read and write options using method notation.
|
126
|
+
#
|
127
|
+
# For example:
|
128
|
+
#
|
129
|
+
# @event_calendar = EventCalendar.new(2009, 10)
|
130
|
+
# @event_calendar.template = '/path/to/some/other/template.mab'
|
131
|
+
# puts @event_calendar.beginning_of_week
|
63
132
|
def method_missing(method, *args)
|
64
133
|
if method.to_s =~ /^([^=]+)(=?)$/ && options.has_key?($1.to_sym)
|
65
134
|
options[$1.to_sym] = args.first unless $2.empty?
|
@@ -69,13 +138,30 @@ class Calendar
|
|
69
138
|
end
|
70
139
|
end
|
71
140
|
|
141
|
+
# Returns the HTML representation of this <tt>EventCalendar</tt>.
|
142
|
+
#
|
143
|
+
# aliased as <tt>to_html</tt>
|
72
144
|
def to_s
|
73
|
-
date(:reload)
|
74
|
-
weeks(:reload)
|
75
145
|
render
|
76
146
|
end
|
77
147
|
alias_method :to_html, :to_s
|
78
148
|
|
149
|
+
# Returns an array of week objects which contain date objects for every day that this calendar displays.
|
150
|
+
# It may contain a few days from the previous and next months.
|
151
|
+
#
|
152
|
+
# The <tt>EventCalendar::Week</tt> class inherits from <tt>Array</tt>.
|
153
|
+
#
|
154
|
+
# For example:
|
155
|
+
#
|
156
|
+
# puts EventCalendar.new(2009, 10).weeks.inspect
|
157
|
+
#
|
158
|
+
# # [
|
159
|
+
# # [Sun, 27 Sep 2009, Mon, 28 Sep 2009, Tue, 29 Sep 2009, Wed, 30 Sep 2009, Thu, 01 Oct 2009, Fri, 02 Oct 2009, Sat, 03 Oct 2009],
|
160
|
+
# # [Sun, 04 Oct 2009, Mon, 05 Oct 2009, Tue, 06 Oct 2009, Wed, 07 Oct 2009, Thu, 08 Oct 2009, Fri, 09 Oct 2009, Sat, 10 Oct 2009],
|
161
|
+
# # [Sun, 11 Oct 2009, Mon, 12 Oct 2009, Tue, 13 Oct 2009, Wed, 14 Oct 2009, Thu, 15 Oct 2009, Fri, 16 Oct 2009, Sat, 17 Oct 2009],
|
162
|
+
# # [Sun, 18 Oct 2009, Mon, 19 Oct 2009, Tue, 20 Oct 2009, Wed, 21 Oct 2009, Thu, 22 Oct 2009, Fri, 23 Oct 2009, Sat, 24 Oct 2009],
|
163
|
+
# # [Sun, 25 Oct 2009, Mon, 26 Oct 2009, Tue, 27 Oct 2009, Wed, 28 Oct 2009, Thu, 29 Oct 2009, Fri, 30 Oct 2009, Sat, 31 Oct 2009]
|
164
|
+
# # ]
|
79
165
|
def weeks
|
80
166
|
days_in_month = Time.days_in_month(month, year)
|
81
167
|
starting_day = date.beginning_of_week() -1.day + beginning_of_week.days
|
@@ -86,12 +172,17 @@ class Calendar
|
|
86
172
|
|
87
173
|
protected
|
88
174
|
|
175
|
+
# Generates the HTML representation of this <tt>EventCalendar</tt>. The default implementation calls
|
176
|
+
# <tt>render_with_markaby</tt>.
|
89
177
|
def render
|
90
178
|
render_with_markaby
|
91
179
|
end
|
180
|
+
memoize :render
|
92
181
|
|
182
|
+
# Reads the template file specified in <tt>options[:template]</tt> and evaluates it with <tt>Markaby</tt>,
|
183
|
+
# passing this <tt>EventCalendar</tt> instance as the <tt>event_calendar</tt> local variable.
|
93
184
|
def render_with_markaby
|
94
|
-
Markaby::Builder.new(:
|
185
|
+
Markaby::Builder.new(:event_calendar => self, :template => File.exists?(template) ? File.read(template) : template) { eval(template) }.to_s
|
95
186
|
end
|
96
187
|
|
97
188
|
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
class EventCalendar
|
2
|
+
|
3
|
+
# Provides conveniece methods for calculating dates and spans for an event. Stores the real event object for
|
4
|
+
# proxying all other method calls to it.
|
5
|
+
class Event
|
6
|
+
|
7
|
+
undef_method :id
|
8
|
+
|
9
|
+
attr_accessor :options
|
10
|
+
attr_reader :event
|
11
|
+
|
12
|
+
# Accepts a real event object which it stores to proxy method calls to, and a hash of options obtained from the
|
13
|
+
# <tt>EventCalendar</tt> instance.
|
14
|
+
def initialize(event, options)
|
15
|
+
@event, @options = event, options
|
16
|
+
end
|
17
|
+
|
18
|
+
# Calculates the number of days this day takes up on a calendar (rounding up).
|
19
|
+
# Optionally accepts <tt>week_start</tt> and <tt>week_end</tt> dates to calculate how many days an event takes
|
20
|
+
# up in a single week. For example, if an event started on a Friday and ended the following Wednesday, calling
|
21
|
+
# <tt>@event.days(the_sunday_after_the_event_starts)</tt> would return 4.
|
22
|
+
def days(week_start = start_date, week_end = end_date)
|
23
|
+
(end_date > week_end ? week_end : end_date) - (start_date < week_start ? week_start : start_date) + 1
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns the end date of the event. If the event stores its end as a datetime then it is converted to a date.
|
27
|
+
def end_date
|
28
|
+
self.end.to_date
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns the start date of the event. If the event stores its start as a datetime then it is converted to a date.
|
32
|
+
def start_date
|
33
|
+
start.to_date
|
34
|
+
end
|
35
|
+
|
36
|
+
# Allows you to read options starting with <tt>:event_</tt> using method notation.
|
37
|
+
#
|
38
|
+
# For example: calling <tt>@event.title</tt> will return the value of <tt>@event.options[:event_title]</tt> if
|
39
|
+
# that option exists.
|
40
|
+
#
|
41
|
+
# All other calls are delegated to the real <tt>:event</tt> object.
|
42
|
+
def method_missing(method, *args)
|
43
|
+
option = "event_#{method}".to_sym
|
44
|
+
if @options.has_key?(option)
|
45
|
+
evaluate_option(option)
|
46
|
+
else
|
47
|
+
@event.send(method, *args)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
protected
|
52
|
+
|
53
|
+
# Looks up the specified option returns the evaluated the result.
|
54
|
+
#
|
55
|
+
# If the value of the option is a symbol, then it calls <tt>@event.send(value)</tt>
|
56
|
+
#
|
57
|
+
# If the value of the option is a proc, then it calls the proc and passes the current <tt>Event</tt>
|
58
|
+
# instance as an argument.
|
59
|
+
#
|
60
|
+
# Any other value is simply returned.
|
61
|
+
def evaluate_option(option)
|
62
|
+
value = @options[option]
|
63
|
+
case value
|
64
|
+
when Symbol
|
65
|
+
@event.send(value)
|
66
|
+
when Proc
|
67
|
+
value.call(self)
|
68
|
+
else
|
69
|
+
value
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|