BrianTheCoder-ratpack 0.2.4 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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