simple_calendar 1.0.1 → 1.1.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ae8f18ccce8e55fd2c7caefb28f9260befdb50c8
4
- data.tar.gz: ed5657eb62db1fee6021f516f935eed13c55335c
3
+ metadata.gz: 4ac05b82caf3c5475d9890349e7fe90fb9c536d1
4
+ data.tar.gz: df0ee7c7ba1fc634b41aa703dde69b89ec1040a5
5
5
  SHA512:
6
- metadata.gz: 687581a924042ef175fede1beb7fbf550dbbf5e8a936b7365d6b9c362d9484216c092bcc80abfcf3a116dff5184758393db77514c2023285662b86417e73170c
7
- data.tar.gz: 2d70ac7b3b28297e0e6cdbf457078240dbadcff2ed0635d1f4fccae5e45acc722ebc5814367137ca9001908bbc51872987fb03c0540ffe2b00ad3ba6da5c25a8
6
+ metadata.gz: af7ea6649813615d366c6915e883ee128a125526308e8caeb960da9552046d70407fe5c6dc87cf9f29effec7710064d181a2fb25f8e3f65782392ef2a1e7388c
7
+ data.tar.gz: ae67ff184ff36292f9c6ab38a55159c0d390a439436d49b33f577aaa5e3ed4268e17e8075038c116dbd6e8ae206f8f13e9d1d8c2945d1c80dccc4784fa716063
data/README.md CHANGED
@@ -17,12 +17,12 @@ Installation
17
17
 
18
18
  Just add this into your Gemfile followed by a bundle install:
19
19
 
20
- gem "simple_calendar", "~> 1.0.0"
20
+ gem "simple_calendar", "~> 1.1.0"
21
21
 
22
22
  Usage
23
23
  -----
24
24
 
25
- Generating calendars is extremely simple with simple_calendar in version 1.0.
25
+ Generating calendars is extremely simple with simple_calendar in version 1.1.
26
26
 
27
27
  The first parameter is a symbol that looks up the current date in
28
28
  `params`. If no date is found, it will use the current date.
@@ -33,22 +33,20 @@ In these examples, we're using `:start_date` which is the default.
33
33
 
34
34
  You can generate a calendar for the month with the `month_calendar`
35
35
  method.
36
- This will use `params[:start_date]` to render the calendar.
37
36
 
38
37
  ```erb
39
- <%= month_calendar :start_date do |day| %>
40
- <%= day %>
38
+ <%= month_calendar do |date| %>
39
+ <%= date %>
41
40
  <% end %>
42
41
  ```
43
42
 
44
43
  ### Week Calendar
45
44
 
46
45
  You can generate a week calendar with the `week_calendar` method.
47
- This will use `params[:start_date]` to render the calendar.
48
46
 
49
47
  ```erb
50
- <%= week_calendar :start_date, number_of_weeks: 2 do |day| %>
51
- <%= day %>
48
+ <%= week_calendar number_of_weeks: 2 do |date| %>
49
+ <%= date %>
52
50
  <% end %>
53
51
  ```
54
52
 
@@ -57,16 +55,66 @@ Setting `number_of_weeks` is optional and defaults to 1.
57
55
  ### Custom Length Calendar
58
56
 
59
57
  You can generate calendars of any length by passing in the number of days you want to render.
60
- This will use `params[:start_date]` to render the calendar.
61
58
 
62
59
  ```erb
63
- <%= calendar :start_date, number_of_days: 4 do |day| %>
64
- <%= day %>
60
+ <%= calendar number_of_days: 4 do |date| %>
61
+ <%= date %>
65
62
  <% end %>
66
63
  ```
67
64
 
68
65
  Setting `number_of_days` is optional and defaults to 4.
69
66
 
67
+ ## Rendering Events
68
+
69
+ What's a calendar without events in it? There are two simple steps for
70
+ creating calendars with events.
71
+
72
+ The first step is to add the following to your model. We'll be using a
73
+ model called Event, but you can add this to any model or Ruby object.
74
+
75
+ We use the `has_calendar` method to tell simple_calendar how to filter
76
+ and sort the events on the different calendar days. This should be the
77
+ start date/time of your event. By default it uses `starts_at` as the
78
+ attribute name.
79
+
80
+ ```ruby
81
+ class Event < ActiveRecord::Base
82
+ extend SimpleCalendar
83
+ has_calendar
84
+
85
+ # Or set a custom attribute for simple_calendar to sort by
86
+ # has_calendar :attribute => :your_starting_time_column_name
87
+ end
88
+ ```
89
+
90
+ In your controller, query for these events and store them in an instance
91
+ variable. We'll just load up all the events for this example.
92
+
93
+ ```ruby
94
+ def index
95
+ @events = Event.all
96
+ end
97
+ ```
98
+
99
+ Then in your view, you can pass in the `events` option to render. The
100
+ events will automatically be filter out by day for you.
101
+
102
+ ```erb
103
+ <%= month_calendar events: @events do |date, events| %>
104
+ <%= date %>
105
+
106
+ <% events.each do |event| %>
107
+ <div>
108
+ <%= event.name %>
109
+ </div>
110
+ <% end %>
111
+ <% end %>
112
+ ```
113
+
114
+ If you pass in objects that don't respond to the attribute method (like
115
+ starts_at), then all the events will be yielded each day. This lets you
116
+ do custom filtering however you want.
117
+
70
118
  ## Customizing The Calendar
71
119
 
72
120
  You can change a couple of global options that will affect how the
@@ -113,10 +161,7 @@ the `content_tag` method so each of them **must** be a hash.
113
161
 
114
162
  ```ruby
115
163
 
116
- <%= calendar :start_date,
117
- table: {class: "table table-bordered"},
118
- tr: {class: "row"},
119
- td: {class: "day"}, do |day| %>
164
+ <%= calendar table: {class: "table table-bordered"}, tr: {class: "row"}, td: {class: "day"}, do |day| %>
120
165
  <% end %>
121
166
  ```
122
167
 
@@ -149,9 +194,7 @@ content_tag options. If you wish to set a class or data attributes, just
149
194
  set them as you normally would in a content_tag call.
150
195
 
151
196
  ```erb
152
- <%= month_calendar :start_date, tr: ->(start_date,
153
- current_calendar_date) { {class: "calendar-date", data: {day:
154
- current_calendar_date}} } do |day| %>
197
+ <%= month_calendar td: ->(start_date, current_calendar_date) { {class: "calendar-date", data: {day: current_calendar_date}} } do |day| %>
155
198
  <% end %>
156
199
  ```
157
200
 
@@ -162,6 +205,25 @@ This generate each day in the calendar like this:
162
205
  </td>
163
206
  ```
164
207
 
208
+ Instead of writing the lambdas inline, a cleaner approach is to write a
209
+ helper that returns a lambda. You can duplicate the following example by
210
+ adding this to your helpers
211
+
212
+ ```ruby
213
+ def month_calendar_td_options
214
+ ->(start_date, current_calendar_date) {
215
+ {class: "calendar-date", data: {day: current_calendar_date}}
216
+ }
217
+ end
218
+ ```
219
+
220
+ And then your view would use `month_calendar_td_options` as the value.
221
+
222
+ ```erb
223
+ <%= month_calendar td: month_calendar_td_options do |day| %>
224
+ <% end %>
225
+ ```
226
+
165
227
  ### Custom Header Links
166
228
 
167
229
  Each of the calendar methods will generate a header with links to the
@@ -174,8 +236,7 @@ To change these, you can pass in the `prev_link`, `header`, and
174
236
  The default `month_calendar` look like this:
175
237
 
176
238
  ```erb
177
- <%= month_calendar :start_date,
178
- prev_link: ->(range) { link_to raw("&laquo;"), param_name => range.first - 1.day },
239
+ <%= month_calendar prev_link: ->(range) { link_to raw("&laquo;"), param_name => range.first - 1.day },
179
240
  header: ->{ content_tag :span, "#{I18n.t("date.month_names")[start_date.month]} #{start_date.year}", class: "calendar-header" },
180
241
  next_link: ->(range) { link_to raw("&raquo;"), param_name => range.last + 1.day } do |day| %>
181
242
 
@@ -197,16 +258,12 @@ If you wish to disable any of these partsof the header, just pass in
197
258
  `false` and that will hide it:
198
259
 
199
260
  ```erb
200
- <%= month_calendar :start_date, header: false do |day| %>
261
+ <%= month_calendar header: false do |day| %>
201
262
  <% end %>
202
263
  ```
203
264
 
204
265
  ## TODO
205
266
 
206
- - Having an "events" option would be nice. Users can pass in all the
207
- objects and we can use it to auto-filter them so the user doesn't
208
- have to. This is what the previous version did and yielded the
209
- day's events to the block.
210
267
  - Multi-day events?
211
268
 
212
269
  ## Author
@@ -0,0 +1,126 @@
1
+ module SimpleCalendar
2
+ class Calendar
3
+ delegate :capture, :concat, :content_tag, :link_to, :params, :raw, :safe_join, to: :view_context
4
+
5
+ attr_reader :block, :events, :options, :view_context
6
+
7
+ def initialize(view_context, options={})
8
+ @view_context = view_context
9
+ @events = options.delete(:events) { [] }
10
+ @options = options
11
+ @options[:previous_link] ||= default_previous_link
12
+ @options[:header] ||= default_header
13
+ @options[:next_link] ||= default_next_link
14
+ @options[:td] ||= default_td_classes
15
+ end
16
+
17
+ def render(block)
18
+ @block = block
19
+
20
+ capture do
21
+ concat render_header
22
+ concat render_table
23
+ end
24
+ end
25
+
26
+ def render_header
27
+ capture do
28
+ content_tag :div do
29
+ concat get_option(:previous_link, param_name, date_range)
30
+ concat get_option(:header, start_date)
31
+ concat get_option(:next_link, param_name, date_range)
32
+ end
33
+ end
34
+ end
35
+
36
+ def render_table
37
+ content_tag :table, get_option(:table) do
38
+ content_tag :tbody, get_option(:tbody) do
39
+ render_weeks
40
+ end
41
+ end
42
+ end
43
+
44
+ def render_weeks
45
+ capture do
46
+ date_range.each_slice(7) do |week|
47
+ concat content_tag(:tr, render_week(week), get_option(:tr, week))
48
+ end
49
+ end
50
+ end
51
+
52
+ def render_week(week)
53
+ results = week.map do |day|
54
+ content_tag :td, get_option(:td, start_date, day) do
55
+ block.call day, events_for_date(day)
56
+ end
57
+ end
58
+ safe_join results
59
+ end
60
+
61
+ def param_name
62
+ @param_name ||= options.fetch(:param_name, :start_date)
63
+ end
64
+
65
+ def events_for_date(current_date)
66
+ if events.any? && events.first.respond_to?(:simple_calendar_start_time)
67
+ events.select do |e|
68
+ current_date == e.send(:simple_calendar_start_time).to_date
69
+ end.sort_by(&:simple_calendar_start_time)
70
+ else
71
+ events
72
+ end
73
+ end
74
+
75
+ def default_previous_link
76
+ ->(param, date_range) { link_to raw("&laquo;"), param => date_range.first - 1.day }
77
+ end
78
+
79
+ def default_header
80
+ ->(start_date) { }
81
+ end
82
+
83
+ def default_next_link
84
+ ->(param, date_range) { link_to raw("&raquo;"), param => date_range.last + 1.day }
85
+ end
86
+
87
+ def start_date
88
+ @start_date ||= (params[param_name] ||Time.zone.now).to_date
89
+ end
90
+
91
+ def date_range
92
+ @date_range ||= begin
93
+ number_of_days = options.fetch(:number_of_days, 4) - 1
94
+ start_date..(start_date + number_of_days.days)
95
+ end
96
+ end
97
+
98
+ def default_td_classes
99
+ ->(start_date, current_calendar_date) {
100
+ today = Time.zone.now.to_date
101
+ td_class = ["day"]
102
+
103
+ td_class << "today" if today == current_calendar_date
104
+ td_class << "past" if today > current_calendar_date
105
+ td_class << "future" if today < current_calendar_date
106
+ td_class << "prev-month" if start_date.month != current_calendar_date.month && current_calendar_date < start_date
107
+ td_class << "next-month" if start_date.month != current_calendar_date.month && current_calendar_date > start_date
108
+ td_class << "current-month" if start_date.month == current_calendar_date.month
109
+ td_class << "wday-#{current_calendar_date.wday.to_s}"
110
+
111
+ { class: td_class.join(" ") }
112
+ }
113
+ end
114
+
115
+ def get_option(name, *params)
116
+ option = options[name]
117
+ case option
118
+ when Hash
119
+ option
120
+ else
121
+ option.call(*params) if option.respond_to? :call
122
+ end
123
+ end
124
+ end
125
+ end
126
+
@@ -0,0 +1,16 @@
1
+ module SimpleCalendar
2
+ module ModelAdditions
3
+ def has_calendar(options={})
4
+ config = { :attribute => :starts_at }
5
+
6
+ # Override default config
7
+ config.update(options) if options.is_a?(Hash)
8
+
9
+ class_eval <<-EOV
10
+ def simple_calendar_start_time
11
+ #{config[:attribute]}
12
+ end
13
+ EOV
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module SimpleCalendar
2
+ class MonthCalendar < Calendar
3
+ def date_range
4
+ @date_range ||= start_date.beginning_of_month.beginning_of_week..start_date.end_of_month.end_of_week
5
+ end
6
+
7
+ def default_header
8
+ ->(start_date) { content_tag :span, month_name(start_date), class: "calendar-header" }
9
+ end
10
+
11
+ def month_name(start_date)
12
+ "#{I18n.t("date.month_names")[start_date.month]} #{start_date.year}"
13
+ end
14
+ end
15
+ end
16
+
@@ -1,3 +1,3 @@
1
1
  module SimpleCalendar
2
- VERSION = "1.0.1"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -1,150 +1,18 @@
1
1
  module SimpleCalendar
2
2
  module ViewHelpers
3
- def month_calendar(param_name=:start_date, options={}, &block)
4
- start_date = (params[param_name] || Time.zone.now).to_date
5
-
6
- options.reverse_merge!(
7
- td: day_classes,
8
- prev_link: ->(range) { link_to raw("&laquo;"), param_name => range.first - 1.day },
9
- header: month_header,
10
- next_link: ->(range) { link_to raw("&raquo;"), param_name => range.last + 1.day },
11
- start_date: start_date,
12
- )
13
- render_calendar month_range(start_date), options, &block
14
- end
15
-
16
- def week_calendar(param_name=:start_date, options={}, &block)
17
- start_date = (params[param_name] || Time.zone.now).to_date
18
- number_of_weeks = options.fetch(:number_of_weeks, 1)
19
-
20
- options.reverse_merge!(
21
- td: day_classes,
22
- prev_link: ->(range) { link_to raw("&laquo;"), param_name => range.first - 1.day },
23
- header: false,
24
- next_link: ->(range) { link_to raw("&raquo;"), param_name => range.last + 1.day },
25
- start_date: start_date,
26
- )
27
- render_calendar week_range(start_date, number_of_weeks), options, &block
28
- end
29
-
30
- def calendar(param_name=:start_date, options={}, &block)
31
- start_date = (params[param_name] || Time.zone.now).to_date
32
- number_of_days_to_advance = options.fetch(:number_of_days, 4) - 1
33
-
34
- options.reverse_merge!(
35
- td: day_classes,
36
- prev_link: ->(range) { link_to raw("&laquo;"), param_name => range.first - 1.day },
37
- header: false,
38
- next_link: ->(range) { link_to raw("&raquo;"), param_name => range.last + 1.day },
39
- start_date: start_date,
40
- )
41
- render_calendar calendar_range(start_date, number_of_days_to_advance), options, &block
42
- end
43
-
44
- def month_range(start_date)
45
- start_date.beginning_of_month.beginning_of_week.to_date..start_date.end_of_month.end_of_week.to_date
46
- end
47
-
48
- def week_range(start_date, number_of_weeks)
49
- number_of_days_to_advance = (number_of_weeks * 7) - 1
50
- starting_day = start_date.beginning_of_week.to_date
51
- ending_day = starting_day + number_of_days_to_advance.days
52
- starting_day..ending_day
53
- end
54
-
55
- def calendar_range(start_date, number_of_days_to_advance)
56
- start_date..(start_date + number_of_days_to_advance.days)
57
- end
58
-
59
- def render_calendar(range, options, &block)
60
- raise 'SimpleCalendar requires a block' unless block_given?
61
-
62
- @block = block
63
- @options = options.reverse_merge default_options
64
- @start_date = options.fetch(:start_date)
65
-
66
- capture do
67
- concat render_header(@start_date, range)
68
- concat render_table(range)
69
- end
70
- end
71
-
72
- def render_header(start_date, range)
73
- capture do
74
- content_tag :div do
75
- concat get_options(@options[:prev_link], range)
76
- concat get_options(@options[:header], start_date)
77
- concat get_options(@options[:next_link], range)
78
- end
79
- end
80
- end
81
-
82
- def render_table(range)
83
- content_tag(:table, get_options(@options[:table])) do
84
- content_tag(:tbody) do
85
- render_weeks(range)
86
- end
87
- end
88
- end
89
-
90
-
91
- def render_weeks(range)
92
- weeks = []
93
- range.each_slice(7) do |week|
94
- weeks << content_tag(:tr, get_options(@options[:tr], week)) do
95
- render_week(week)
96
- end
97
- end
98
- safe_join weeks
3
+ def calendar(options={}, &block)
4
+ raise 'calendar requires a block' unless block_given?
5
+ SimpleCalendar::Calendar.new(self, options).render(block)
99
6
  end
100
7
 
101
- def render_week(week)
102
- results = week.map do |day|
103
- content_tag :td, get_options(@options[:td], @start_date, day) do
104
- @block.call(day)
105
- end
106
- end
107
- safe_join results
108
- end
109
-
110
- def get_options(options, *params)
111
- case options
112
- when Hash
113
- options
114
- when String
115
- send(options, *params)
116
- when Symbol
117
- send(options, *params)
118
- else
119
- options.call(*params) if options.respond_to? :call
120
- end
121
- end
122
-
123
- def default_options
124
- { table: {}, tr: {}, td: {}, }
125
- end
126
-
127
- def day_classes
128
- ->(start_date, current_calendar_date) {
129
- today = Time.zone.now.to_date
130
- td_class = ["day"]
131
-
132
- td_class << "today" if today == current_calendar_date
133
- td_class << "past" if today > current_calendar_date
134
- td_class << "future" if today < current_calendar_date
135
- td_class << "prev-month" if start_date.month != current_calendar_date.month && current_calendar_date < start_date
136
- td_class << "next-month" if start_date.month != current_calendar_date.month && current_calendar_date > start_date
137
- td_class << "current-month" if start_date.month == current_calendar_date.month
138
- td_class << "wday-#{current_calendar_date.wday.to_s}"
139
-
140
- { class: td_class.join(" ") }
141
- }
8
+ def month_calendar(options={}, &block)
9
+ raise 'month_calendar requires a block' unless block_given?
10
+ SimpleCalendar::MonthCalendar.new(self, options).render(block)
142
11
  end
143
12
 
144
- def month_header
145
- ->(start_date) {
146
- content_tag :span, "#{I18n.t("date.month_names")[start_date.month]} #{start_date.year}", class: "calendar-header"
147
- }
13
+ def week_calendar(options={}, &block)
14
+ raise 'week_calendar requires a block' unless block_given?
15
+ SimpleCalendar::WeekCalendar.new(self, options).render(block)
148
16
  end
149
17
  end
150
18
  end
@@ -0,0 +1,22 @@
1
+ module SimpleCalendar
2
+ class WeekCalendar < Calendar
3
+ def date_range
4
+ @date_range ||= begin
5
+ number_of_weeks = options.fetch(:number_of_weeks, 1)
6
+ number_of_days = (number_of_weeks * 7) - 1
7
+ starting_day = start_date.beginning_of_week.to_date
8
+ ending_day = starting_day + number_of_days.days
9
+ starting_day..ending_day
10
+ end
11
+ end
12
+
13
+ def default_previous_link
14
+ ->(param, date_range) { link_to raw("&laquo;"), param => date_range.first - 8.days }
15
+ end
16
+
17
+ def default_next_link
18
+ ->(param, date_range) { link_to raw("&raquo;"), param => date_range.last + 1.day }
19
+ end
20
+ end
21
+ end
22
+
@@ -1,3 +1,17 @@
1
+ require "simple_calendar/calendar"
2
+ require "simple_calendar/month_calendar"
3
+ require "simple_calendar/week_calendar"
4
+ require "simple_calendar/model_additions"
5
+ require "simple_calendar/railtie"
1
6
  require "simple_calendar/version"
2
7
  require "simple_calendar/view_helpers"
3
- require "simple_calendar/railtie"
8
+
9
+ module SimpleCalendar
10
+ def self.extended(model_class)
11
+ return if model_class.respond_to? :has_calendar
12
+
13
+ model_class.class_eval do
14
+ extend ModelAdditions
15
+ end
16
+ end
17
+ end
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_calendar
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Oliver
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-12 00:00:00.000000000 Z
11
+ date: 2014-05-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - '>='
18
18
  - !ruby/object:Gem::Version
19
19
  version: '3.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '3.0'
27
27
  description: A simple Rails 3 and Rails 4 calendar
@@ -31,15 +31,19 @@ executables: []
31
31
  extensions: []
32
32
  extra_rdoc_files: []
33
33
  files:
34
- - ".gitignore"
35
- - ".rspec"
34
+ - .gitignore
35
+ - .rspec
36
36
  - Gemfile
37
37
  - README.md
38
38
  - Rakefile
39
39
  - lib/simple_calendar.rb
40
+ - lib/simple_calendar/calendar.rb
41
+ - lib/simple_calendar/model_additions.rb
42
+ - lib/simple_calendar/month_calendar.rb
40
43
  - lib/simple_calendar/railtie.rb
41
44
  - lib/simple_calendar/version.rb
42
45
  - lib/simple_calendar/view_helpers.rb
46
+ - lib/simple_calendar/week_calendar.rb
43
47
  - simple_calendar.gemspec
44
48
  homepage: https://github.com/excid3/simple_calendar
45
49
  licenses: []
@@ -50,12 +54,12 @@ require_paths:
50
54
  - lib
51
55
  required_ruby_version: !ruby/object:Gem::Requirement
52
56
  requirements:
53
- - - ">="
57
+ - - '>='
54
58
  - !ruby/object:Gem::Version
55
59
  version: '0'
56
60
  required_rubygems_version: !ruby/object:Gem::Requirement
57
61
  requirements:
58
- - - ">="
62
+ - - '>='
59
63
  - !ruby/object:Gem::Version
60
64
  version: '0'
61
65
  requirements: []