BrianTheCoder-ratpack 0.2.4 → 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.
@@ -1,4 +1,4 @@
1
1
  ---
2
- :minor: 2
3
- :patch: 4
4
2
  :major: 0
3
+ :minor: 3
4
+ :patch: 2
@@ -22,7 +22,7 @@ module RatPack
22
22
  dir ||= ::File.basename(fname, '.*')
23
23
  search_me = ::File.expand_path(
24
24
  ::File.join(::File.dirname(fname), dir, '**', '*.rb'))
25
- Dir.glob(search_me).sort.each {|rb| require rb}
25
+ Dir.glob(search_me).sort.each {|rb| require rb }
26
26
  end
27
27
  end # module RatPack
28
28
 
@@ -0,0 +1,155 @@
1
+ module DateAndTimeFormatting
2
+ def self.included(base)
3
+ base.class_eval do
4
+ include DateAndTimeFormatting::InstanceMethods
5
+ include OrdinalizedFormatting
6
+ extend DateAndTimeFormatting::ClassMethods
7
+ end
8
+ end
9
+
10
+ module InstanceMethods
11
+
12
+
13
+ # Formats a date/time instance using a defined format
14
+ #
15
+ # ==== Parameters
16
+ # format<Symbol>:: of the format key from Date.date_formats
17
+ #
18
+ # ==== Returns
19
+ # String:: formatted string
20
+ #
21
+ # ==== Example
22
+ # Time.now.formatted(:rfc822) # => "Sun, 16 Nov 2007 00:21:16 -0800"
23
+ # Time.now.formatted(:db) # => "2008-11-16 00:22:09"
24
+ #
25
+ # You can also add your own formats using +Date.add_format+ when your app loads.
26
+ #
27
+ # # Add the following to your init.rb
28
+ # Merb::BootLoader.before_app_loads do
29
+ # Date.add_format(:matt, "%H:%M:%S %Y-%m-%d")
30
+ # end
31
+ #
32
+ # # Format a Time instance with the format you just specified
33
+ # Time.now.formatted(:matt) # => "00:00:00 2007-11-02"
34
+ #
35
+ #--
36
+ # @public
37
+ def formatted(format = :default)
38
+ self.strftime(Date.formats[format])
39
+ end
40
+
41
+ end
42
+
43
+ module ClassMethods
44
+
45
+ @@formats = {
46
+ :db => "%Y-%m-%d %H:%M:%S",
47
+ :time => "%H:%M", # 21:12
48
+ :date => "%Y-%m-%d", # 2008-12-04
49
+ :short => "%d %b %H:%M", # 01 Sep 21:12
50
+ :long => "%B %d, %Y %H:%M",
51
+ :rfc822 => "%a, %d %b %Y %H:%M:%S %z"
52
+ }
53
+
54
+ # Lists the date and time formats
55
+ #
56
+ # ==== Returns
57
+ # Hash:: a hash with all formats available
58
+ # --
59
+ # @public
60
+ def formats
61
+ @@formats
62
+ end
63
+
64
+ # Adds a date and time format
65
+ #
66
+ # Because this operation is not thread safe, you should define
67
+ # custom formats when you load you application. The recommended way
68
+ # to do that, is to use the before_app_loads bootloader.
69
+ #
70
+ # If you want to add a format at runtime, you will need to use a mutex
71
+ # and synchronize it yourself.
72
+ #
73
+ # ==== Parameters
74
+ # key<Symbol>:: name of the format
75
+ # format<Hash>:: time format to use
76
+ #
77
+ # ==== Returns
78
+ # Hash:: a hash with all formats available
79
+ #
80
+ # ==== Example
81
+ #
82
+ # Merb::BootLoader.before_app_loads do
83
+ # Date.add_format(:matt, "%H:%M:%S %Y-%m-%d")
84
+ # end
85
+ #
86
+ #
87
+ # --
88
+ # @public
89
+ def add_format(key, format)
90
+ formats.merge!({key => format})
91
+ end
92
+
93
+
94
+ # Resets the date and time formats
95
+ # --
96
+ # @private
97
+ def reset_formats
98
+ original_formats = [:db, :time, :short, :date, :long, :long_ordinal, :rfc822]
99
+ formats = @@formats.delete_if{|format, v| !original_formats.include?(format)}
100
+ end
101
+
102
+ end
103
+
104
+ end
105
+
106
+ module Ordinalize
107
+ # Ordinalize turns a number into an ordinal string used to denote the
108
+ # position in an ordered sequence such as 1st, 2nd, 3rd, 4th.
109
+ #
110
+ # ==== Examples
111
+ # 1.ordinalize # => "1st"
112
+ # 2.ordinalize # => "2nd"
113
+ # 1002.ordinalize # => "1002nd"
114
+ # 1003.ordinalize # => "1003rd"
115
+ def ordinalize
116
+ if (11..13).include?(self % 100)
117
+ "#{self}th"
118
+ else
119
+ case self % 10
120
+ when 1; "#{self}st"
121
+ when 2; "#{self}nd"
122
+ when 3; "#{self}rd"
123
+ else "#{self}th"
124
+ end
125
+ end
126
+ end
127
+ end
128
+
129
+ Integer.send :include, Ordinalize
130
+
131
+ # Time.now.to_ordinalized_s :long
132
+ # => "February 28th, 2006 21:10"
133
+ module OrdinalizedFormatting
134
+
135
+ def to_ordinalized_s(format = :default)
136
+ format = Date.formats[format]
137
+ return self.to_s if format.nil?
138
+ strftime_ordinalized(format)
139
+ end
140
+
141
+ # Gives you a relative date in an attractive format
142
+ #
143
+ # ==== Parameters
144
+ # format<String>:: strftime string used to format a time/date object
145
+ # locale<String, Symbol>:: An optional value which can be used by localization plugins
146
+ #
147
+ # ==== Returns
148
+ # String:: Ordinalized time/date object
149
+ #
150
+ # ==== Examples
151
+ # 5.days.ago.strftime_ordinalized('%b %d, %Y') # =>
152
+ def strftime_ordinalized(fmt, format=nil)
153
+ strftime(fmt.gsub(/(^|[^-])%d/, '\1_%d_')).gsub(/_(\d+)_/) { |s| s.to_i.ordinalize }
154
+ end
155
+ end
@@ -0,0 +1,183 @@
1
+ # Provides a number of methods for displaying and dealing with dates and times
2
+ #
3
+ # Parts were strongly based on http://ar-code.svn.engineyard.com/plugins/relative_time_helpers/, and
4
+ # active_support
5
+ #
6
+ # The key methods are `relative_date`, `relative_date_span`, and `relative_time_span`. This also gives
7
+ # you the Rails style Time DSL for working with numbers eg. 3.months.ago or 5.days.until(1.year.from_now)
8
+ module RatPack
9
+ module DateAndTime
10
+ @@time_class = Time
11
+ @@time_output = {
12
+ :today => 'today',
13
+ :yesterday => 'yesterday',
14
+ :tomorrow => 'tomorrow',
15
+ :initial_format => '%b %d',
16
+ :year_format => ', %Y'
17
+ }
18
+
19
+ def self.time_class
20
+ @@time_class
21
+ end
22
+
23
+ # ==== Parameters
24
+ # format<Symbol>:: time format to use
25
+ # locale<String, Symbol>:: An optional value which can be used by localization plugins
26
+ #
27
+ # ==== Returns
28
+ # String:: a string used to format time using #strftime
29
+ def self.time_output(format, locale=nil)
30
+ @@time_output[format]
31
+ end
32
+
33
+ # Gives you a relative date in an attractive format
34
+ #
35
+ # ==== Parameters
36
+ # time<~to_date>:: The Date or Time to test
37
+ # locale<String, Symbol>:: An optional value which can be used by localization plugins
38
+ #
39
+ # ==== Returns
40
+ # String:: Relative date
41
+ #
42
+ # ==== Examples
43
+ # relative_date(Time.now.utc) => "today"
44
+ # relative_date(5.days.ago) => "March 5th"
45
+ # relative_date(1.year.ago) => "March 10th, 2007"
46
+ def relative_date(time, locale=nil)
47
+ date = time.to_date
48
+ today = DateAndTime.time_class.now.to_date
49
+ if date == today
50
+ DateAndTime.time_output(:today, locale)
51
+ elsif date == (today - 1)
52
+ DateAndTime.time_output(:yesterday, locale)
53
+ elsif date == (today + 1)
54
+ DateAndTime.time_output(:tomorrow, locale)
55
+ else
56
+ fmt = DateAndTime.time_output(:initial_format, locale).dup
57
+ fmt << DateAndTime.time_output(:year_format, locale) unless date.year == today.year
58
+ time.strftime_ordinalized(fmt, locale)
59
+ end
60
+ end
61
+
62
+ # Gives you a relative date span in an attractive format
63
+ #
64
+ # ==== Parameters
65
+ # times<~first,~last>:: The Dates or Times to test
66
+ #
67
+ # ==== Returns
68
+ # String:: The sexy relative date span
69
+ #
70
+ # ==== Examples
71
+ # relative_date([1.second.ago, 10.seconds.ago]) => "March 10th"
72
+ # relative_date([1.year.ago, 1.year.ago) => "March 10th, 2007"
73
+ # relative_date([Time.now, 1.day.from_now]) => "March 10th - 11th"
74
+ # relative_date([Time.now, 1.year.ago]) => "March 10th, 2007 - March 10th, 2008"
75
+ def relative_date_span(times)
76
+ times = [times.first, times.last].collect! { |t| t.to_date }
77
+ times.sort!
78
+ if times.first == times.last
79
+ relative_date(times.first)
80
+ else
81
+ first = times.first; last = times.last; now = DateAndTime.time_class.now
82
+ arr = [first.strftime_ordinalized('%b %d')]
83
+ arr << ", #{first.year}" unless first.year == last.year
84
+ arr << ' - '
85
+ arr << last.strftime('%b') << ' ' unless first.year == last.year && first.month == last.month
86
+ arr << last.day.ordinalize
87
+ arr << ", #{last.year}" unless first.year == last.year && last.year == now.year
88
+ arr.to_s
89
+ end
90
+ end
91
+
92
+ # Gives you a relative date span in an attractive format
93
+ #
94
+ # ==== Parameters
95
+ # times<~first,~last>:: The Dates or Times to test
96
+ #
97
+ # ==== Returns
98
+ # String:: The sexy relative time span
99
+ #
100
+ # ==== Examples
101
+ # relative_time_span([1.second.ago, 10.seconds.ago]) => "12:00 - 12:09 AM March 10th"
102
+ # relative_time_span([1.year.ago, 1.year.ago) => "12:09 AM March 10th, 2007"
103
+ # relative_time_span([Time.now, 13.hours.from_now]) => "12:09 AM - 1:09 PM March 10th"
104
+ # relative_time_span([Time.now, 1.year.ago]) => "12:09 AM March 10th, 2007 - 12:09 AM March 10th, 2008"
105
+ def relative_time_span(times)
106
+ times = [times.first, times.last].collect! { |t| t.to_time }
107
+ times.sort!
108
+ if times.first == times.last
109
+ "#{prettier_time(times.first)} #{relative_date(times.first)}"
110
+ elsif times.first.to_date == times.last.to_date
111
+ same_half = (times.first.hour/12 == times.last.hour/12)
112
+ "#{prettier_time(times.first, !same_half)} - #{prettier_time(times.last)} #{relative_date(times.first)}"
113
+
114
+ else
115
+ first = times.first; last = times.last; now = DateAndTime.time_class.now
116
+ arr = [prettier_time(first)]
117
+ arr << ' '
118
+ arr << first.strftime_ordinalized('%b %d')
119
+ arr << ", #{first.year}" unless first.year == last.year
120
+ arr << ' - '
121
+ arr << prettier_time(last)
122
+ arr << ' '
123
+ arr << last.strftime('%b') << ' ' unless first.year == last.year && first.month == last.month
124
+ arr << last.day.ordinalize
125
+ arr << ", #{last.year}" unless first.year == last.year && last.year == now.year
126
+ arr.to_s
127
+ end
128
+ end
129
+
130
+ # Condenses time... very similar to time_ago_in_words in ActionPack
131
+ #
132
+ # ==== Parameters
133
+ # from_time<~to_time>:: The Date or Time to start from
134
+ # to_time<~to_time>:: The Date or Time to go to, Defaults to Time.now.utc
135
+ # include_seconds<Boolean>:: Count the seconds initially, Defaults to false
136
+ # locale<String, Symbol>:: An optional value which can be used by localization plugins
137
+ #
138
+ # ==== Returns
139
+ # String:: The time distance
140
+ #
141
+ # ==== Examples
142
+ # time_lost_in_words(3.minutes.from_now) # => 3 minutes
143
+ # time_lost_in_words(Time.now - 15.hours) # => 15 hours
144
+ # time_lost_in_words(Time.now, 3.minutes.from_now) # => 3 minutes
145
+ # time_lost_in_words(Time.now) # => less than a minute
146
+ # time_lost_in_words(Time.now, Time.now, true) # => less than 5 seconds
147
+ #
148
+ def time_lost_in_words(from_time, to_time = Time.now.utc, include_seconds = false, locale=nil)
149
+ from_time = from_time.to_time if from_time.respond_to?(:to_time)
150
+ to_time = to_time.to_time if to_time.respond_to?(:to_time)
151
+ distance_in_minutes = (((to_time - from_time).abs)/60).round
152
+ distance_in_seconds = ((to_time - from_time).abs).round
153
+
154
+ case distance_in_minutes
155
+ when 0..1
156
+ return (distance_in_minutes == 0) ? 'less than a minute' : '1 minute' unless include_seconds
157
+ case distance_in_seconds
158
+ when 0..4 then 'less than 5 seconds'
159
+ when 5..9 then 'less than 10 seconds'
160
+ when 10..19 then 'less than 20 seconds'
161
+ when 20..39 then 'half a minute'
162
+ when 40..59 then 'less than a minute'
163
+ else '1 minute'
164
+ end
165
+
166
+ when 2..44 then "#{distance_in_minutes} minutes"
167
+ when 45..89 then 'about 1 hour'
168
+ when 90..1439 then "about #{(distance_in_minutes.to_f / 60.0).round} hours"
169
+ when 1440..2879 then '1 day'
170
+ when 2880..43199 then "#{(distance_in_minutes / 1440).round} days"
171
+ when 43200..86399 then 'about 1 month'
172
+ when 86400..525599 then "#{(distance_in_minutes / 43200).round} months"
173
+ when 525600..1051199 then 'about 1 year'
174
+ else "over #{(distance_in_minutes / 525600).round} years"
175
+ end
176
+ end
177
+ alias :time_ago_in_words :time_lost_in_words
178
+
179
+ def prettier_time(time, ampm=true, locale=nil)
180
+ time.strftime("%I:%M#{" %p" if ampm}").sub(/^0/, '')
181
+ end
182
+ end
183
+ end
@@ -3,7 +3,7 @@ module RatPack
3
3
  def error_messages_for(obj = nil, opts = {})
4
4
  return unless obj.respond_to?(:errors)
5
5
  return if obj.errors.blank?
6
- html = tag(:h2, "Form submission failed be cause of #{obj.errors.size} #{pluralize("error",obj.errors.size)}")
6
+ html = tag(:h2, "Form submission failed because of #{obj.errors.size} #{pluralize("error",obj.errors.size)}")
7
7
  msgs = obj.errors.map{|error| error.map{|msg| tag(:li,msg)}}.flatten
8
8
  tag(:div, html + tag(:ul,msgs), :class => "error")
9
9
  end
@@ -40,6 +40,7 @@ module RatPack
40
40
  def check_box(attrs)
41
41
  html = ""
42
42
  label = build_field(attrs)
43
+ attrs[:checked] = "checked" if attrs[:checked]
43
44
  if attrs.delete(:boolean)
44
45
  on, off = attrs.delete(:on), attrs.delete(:off)
45
46
  html << hidden_field(:name => attrs[:name], :value => off)
@@ -73,15 +74,19 @@ module RatPack
73
74
  private
74
75
 
75
76
  def form_field(type, content, attrs)
76
- attrs[:id] = attrs[:name].gsub(/(\[)(.+?)\]$/,'_\2') unless attrs.has_key?(:id)
77
+ attrs[:id] = sanitize_name(attrs[:name]) unless attrs.has_key?(:id)
77
78
  build_field(attrs) + tag(type, content, attrs)
78
79
  end
79
80
 
80
81
  def closed_form_field(type, attrs)
81
- attrs[:id] = attrs[:name].gsub(/(\[)(.+?)\]$/,'_\2') unless attrs.has_key?(:id)
82
+ attrs[:id] = sanitize_name(attrs[:name]) unless attrs.has_key?(:id)
82
83
  build_field(attrs) + self_closing_tag(type, attrs)
83
84
  end
84
85
 
86
+ def sanitize_name(name)
87
+ name.gsub(/\[\]$/,'').gsub(/(\[)(.+?)\]$/,'_\2')
88
+ end
89
+
85
90
  def build_field(attrs)
86
91
  label = attrs.has_key?(:label) ? build_label(attrs) : ""
87
92
  hint = attrs.has_key?(:hint) ? tag(:div,attrs.delete(:hint), :class => "hint") : ""
@@ -10,7 +10,8 @@ module RatPack
10
10
  end
11
11
 
12
12
  def image_tag(file,attrs = {})
13
- defaults = {:src => "/images/#{file}"}
13
+ file = "/images/#{file}" unless remote_asset?(file)
14
+ defaults = {:src => file }
14
15
  self_closing_tag(:img,defaults.merge(options))
15
16
  end
16
17
 
@@ -28,19 +29,15 @@ module RatPack
28
29
  end
29
30
 
30
31
  def partial(template, opts = {})
31
- template_engine = opts.delete(:template) || :erb
32
+ engine = opts.delete(:template) || :erb
32
33
  opts.merge!(:layout => false)
33
- template = :"partials/#{template}"
34
+ path = :"partials/#{template}"
34
35
  if collection = opts.delete(:collection) then
35
- collection.inject([]) do |buffer, member|
36
- buffer << send(template_engine,template, opts.merge(
37
- :layout => false,
38
- :locals => {template.to_sym => member}
39
- )
40
- )
36
+ collection.map do |member|
37
+ send(engine,path, opts.merge(:locals => {template.to_sym => member}))
41
38
  end.join("\n")
42
39
  else
43
- send(template_engine,template, opts)
40
+ send(engine,path, opts)
44
41
  end
45
42
  end
46
43
 
@@ -0,0 +1,59 @@
1
+ # Provides a a simple way of calling time units and to see the elapsed time between 2 moments
2
+ # ==== Examples
3
+ # 142.minutes => returns a value in seconds
4
+ # 7.days => returns a value in seconds
5
+ # 1.week => returns a value in seconds
6
+ # 2.weeks.ago => returns a date
7
+ # 1.year.since(time) => returns a date
8
+ # 5.months.since(2.weeks.from_now) => returns a date
9
+ module TimeDSL
10
+
11
+ def second
12
+ self * 1
13
+ end
14
+ alias_method :seconds, :second
15
+
16
+ def minute
17
+ self * 60
18
+ end
19
+ alias_method :minutes, :minute
20
+
21
+ def hour
22
+ self * 3600
23
+ end
24
+ alias_method :hours, :hour
25
+
26
+ def day
27
+ self * 86400
28
+ end
29
+ alias_method :days, :day
30
+
31
+ def week
32
+ self * 604800
33
+ end
34
+ alias_method :weeks, :week
35
+
36
+ def month
37
+ self * 2592000
38
+ end
39
+ alias_method :months, :month
40
+
41
+ def year
42
+ self * 31471200
43
+ end
44
+ alias_method :years, :year
45
+
46
+ # Reads best without arguments: 10.minutes.ago
47
+ def ago(time = ::Time.now)
48
+ time - self
49
+ end
50
+ alias :until :ago
51
+
52
+ # Reads best with argument: 10.minutes.since(time)
53
+ def since(time = ::Time.now)
54
+ time + self
55
+ end
56
+ alias :from_now :since
57
+ end
58
+
59
+ Numeric.send :include, TimeDSL
@@ -5,6 +5,7 @@ module Sinatra
5
5
  app.helpers ::RatPack::HtmlHelpers
6
6
  app.helpers ::RatPack::Routes
7
7
  app.helpers ::RatPack::Forms
8
+ app.helpers ::RatPack::DateAndTime
8
9
  end
9
10
  end
10
11
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: BrianTheCoder-ratpack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - brianthecoder
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-04-14 00:00:00 -07:00
12
+ date: 2009-04-25 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -29,10 +29,13 @@ files:
29
29
  - VERSION.yml
30
30
  - lib/ratpack.rb
31
31
  - lib/ratpack/core_ext/hash.rb
32
+ - lib/ratpack/date_time_formatting.rb
33
+ - lib/ratpack/date_time_helpers.rb
32
34
  - lib/ratpack/forms.rb
33
35
  - lib/ratpack/html_helpers.rb
34
36
  - lib/ratpack/routes.rb
35
37
  - lib/ratpack/tag.rb
38
+ - lib/ratpack/time_dsl.rb
36
39
  - lib/sinatra/ratpack.rb
37
40
  - test/ratpack_test.rb
38
41
  - test/test_helper.rb
@@ -60,7 +63,7 @@ requirements: []
60
63
  rubyforge_project:
61
64
  rubygems_version: 1.2.0
62
65
  signing_key:
63
- specification_version: 2
66
+ specification_version: 3
64
67
  summary: A collection of helpers I wanted for sinatra, thought I'd share
65
68
  test_files:
66
69
  - test/ratpack_test.rb