storefront 0.2.1 → 0.2.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/Rakefile +2 -2
  2. data/lib/storefront.rb +21 -3
  3. data/lib/storefront/configuration.rb +154 -0
  4. data/lib/storefront/dashboard.rb +8 -7
  5. data/lib/storefront/form.rb +70 -53
  6. data/lib/storefront/form/base.rb +50 -0
  7. data/lib/storefront/form/builder.rb +124 -0
  8. data/lib/storefront/form/errors.rb +20 -46
  9. data/lib/storefront/form/field.rb +102 -0
  10. data/lib/storefront/form/fieldset.rb +44 -0
  11. data/lib/storefront/form/hint.rb +34 -0
  12. data/lib/storefront/form/input.rb +191 -0
  13. data/lib/storefront/form/inputs/checkbox.rb +12 -0
  14. data/lib/storefront/form/inputs/date.rb +16 -0
  15. data/lib/storefront/form/inputs/file.rb +12 -0
  16. data/lib/storefront/form/inputs/hidden.rb +11 -0
  17. data/lib/storefront/form/inputs/radio.rb +11 -0
  18. data/lib/storefront/form/inputs/range.rb +15 -0
  19. data/lib/storefront/form/inputs/select.rb +68 -0
  20. data/lib/storefront/form/inputs/string.rb +89 -0
  21. data/lib/storefront/form/inputs/submit.rb +24 -0
  22. data/lib/storefront/form/inputs/textarea.rb +19 -0
  23. data/lib/storefront/form/inputs/value.rb +16 -0
  24. data/lib/storefront/form/label.rb +35 -0
  25. data/lib/storefront/helpers/attribute_helper.rb +29 -8
  26. data/lib/storefront/helpers/body_helper.rb +1 -1
  27. data/lib/storefront/helpers/cache_helper.rb +2 -2
  28. data/lib/storefront/helpers/component_helper.rb +34 -19
  29. data/lib/storefront/helpers/dashboard_helper.rb +9 -17
  30. data/lib/storefront/helpers/definition_list_helper.rb +82 -14
  31. data/lib/storefront/helpers/form_helper.rb +7 -2
  32. data/lib/storefront/helpers/head_helper.rb +2 -2
  33. data/lib/storefront/helpers/image_helper.rb +1 -25
  34. data/lib/storefront/helpers/list_helper.rb +120 -32
  35. data/lib/storefront/helpers/locale_helper.rb +98 -28
  36. data/lib/storefront/helpers/page_helper.rb +78 -60
  37. data/lib/storefront/helpers/request_helper.rb +3 -0
  38. data/lib/storefront/helpers/table_helper.rb +1 -1
  39. data/lib/storefront/helpers/template_helper.rb +11 -0
  40. data/lib/storefront/helpers/time_helper.rb +2 -2
  41. data/lib/storefront/helpers/widget_helper.rb +153 -2
  42. data/lib/storefront/model_helper.rb +17 -0
  43. data/lib/storefront/proxies/attribute_proxy.rb +150 -0
  44. data/lib/storefront/proxies/model_proxy.rb +249 -0
  45. data/lib/storefront/railtie.rb +4 -2
  46. data/lib/storefront/table.rb +7 -0
  47. data/test/form_helper_test.rb +1 -1
  48. metadata +25 -27
  49. data/init.rb +0 -1
  50. data/lib/storefront/form/elements.rb +0 -101
  51. data/lib/storefront/form/fields.rb +0 -420
  52. data/lib/storefront/form/hints.rb +0 -18
  53. data/lib/storefront/form/inputs.rb +0 -258
  54. data/lib/storefront/form/labels.rb +0 -81
  55. data/lib/storefront/form/model.rb +0 -84
  56. data/lib/storefront/microdata/address.rb +0 -7
  57. data/lib/storefront/microdata/event.rb +0 -13
  58. data/lib/storefront/microdata/geo.rb +0 -7
  59. data/lib/storefront/microdata/organization.rb +0 -7
  60. data/lib/storefront/microdata/person.rb +0 -7
  61. data/lib/storefront/microformat/event.rb +0 -7
  62. data/lib/storefront/microformat/person.rb +0 -7
  63. data/lib/storefront/models/container.rb +0 -0
  64. data/lib/storefront/models/element.rb +0 -15
  65. data/lib/storefront/models/form.rb +0 -0
  66. data/lib/storefront/models/form_element.rb +0 -0
  67. data/lib/storefront/models/link.rb +0 -0
  68. data/lib/storefront/models/list.rb +0 -0
  69. data/lib/storefront/models/list_element.rb +0 -0
  70. data/lib/storefront/models/table.rb +0 -0
  71. data/lib/storefront/models/term.rb +0 -0
  72. data/lib/storefront/models/term_list.rb +0 -0
  73. data/lib/storefront/models/validation.rb +0 -0
@@ -0,0 +1,249 @@
1
+ require 'ostruct'
2
+
3
+ module Storefront
4
+ class ModelProxy
5
+ class << self
6
+ def model_names(array)
7
+ Array(array).flatten.map do |object|
8
+ case object
9
+ when ::Class
10
+ object.ancestor_classes.map { |i| i.name.underscore }
11
+ when ::String, ::Symbol
12
+ object
13
+ else
14
+ object.class.ancestor_classes.map { |i| i.name.underscore }
15
+ end
16
+ end.flatten.compact.uniq
17
+ end
18
+ end
19
+
20
+ attr_reader :object, :parent, :errors, :keys
21
+
22
+ def initialize(options = {}, &block)
23
+ @object = options[:object]
24
+ @parent = options[:parent]
25
+ if options[:keys].present?
26
+ @keys = options[:keys]
27
+ elsif @object.is_a?(::OpenStruct) && @object.klass.present?
28
+ @keys = [@object.klass.to_s.underscore]
29
+ else
30
+ @keys = [@object.class.name.underscore]
31
+ end
32
+ end
33
+
34
+ def new_record?
35
+ @object.respond_to?(:new_record?) && !@object.new_record?
36
+ end
37
+
38
+ def config
39
+ Storefront.configuration
40
+ end
41
+
42
+ def self_and_ancestor_names
43
+ @self_and_ancestor_names ||= self.class.model_names(@object)
44
+ end
45
+
46
+ def get(attribute)
47
+ @object.send(attribute)
48
+ end
49
+
50
+ def validators?
51
+ @object.class.respond_to?(:validators_on)
52
+ end
53
+
54
+ def validators_on(attribute)
55
+ @object.class.validators_on(attribute)
56
+ end
57
+
58
+ def validation_message(attribute, key, options = {})
59
+ @object.errors.generate_message(attribute, key, options)
60
+ end
61
+
62
+ def errors_on?(attribute, options = {})
63
+ @object.respond_to?(:errors) ? @object.errors[attribute].present? : false
64
+ end
65
+
66
+ def default_input_type(method, options = {}) #:nodoc:
67
+ if column = column_for(method)
68
+ # Special cases where the column type doesn't map to an input method.
69
+ case column.type
70
+ when :string
71
+ return :password if method.to_s =~ /password/
72
+ return :country if method.to_s =~ /country$/
73
+ return :time_zone if method.to_s =~ /time_zone/
74
+ return :email if method.to_s =~ /email/
75
+ return :url if method.to_s =~ /^url$|^website$|_url$/
76
+ return :phone if method.to_s =~ /(phone|fax)/
77
+ return :search if method.to_s =~ /^search$/
78
+ when :integer
79
+ return :select if reflection_for(method)
80
+ return :numeric
81
+ when :float, :decimal
82
+ return :numeric
83
+ when :timestamp
84
+ return :datetime
85
+ end
86
+
87
+ # Try look for hints in options hash. Quite common senario: Enum keys stored as string in the database.
88
+ return :select if column.type == :string && options.key?(:collection)
89
+ # Try 3: Assume the input name will be the same as the column type (e.g. string_input).
90
+ return column.type
91
+ else
92
+ if @object
93
+ return :select if reflection_for(method)
94
+
95
+ return :file if is_file?(method, options)
96
+ end
97
+
98
+ return :select if options.key?(:collection)
99
+ return :password if method.to_s =~ /password/
100
+ return :string
101
+ end
102
+ end
103
+
104
+ def is_file?(method, options = {})
105
+ @files ||= {}
106
+ @files[method] ||= (options[:as].present? && options[:as] == :file) || begin
107
+ file = @object.send(method) if @object && @object.respond_to?(method)
108
+ file && file_methods.any?{|m| file.respond_to?(m)}
109
+ end
110
+ end
111
+
112
+ def file_methods
113
+ [:file?, :public_filename, :filename]
114
+ end
115
+
116
+ def errors_for(name)
117
+ return @object.errors[name] if errors_on?(name)
118
+ end
119
+
120
+ def humanized_attribute_name(method) #:nodoc:
121
+ if @object && @object.class.respond_to?(:human_attribute_name)
122
+ @object.class.human_attribute_name(method.to_s)
123
+ else
124
+ method.to_s.send(config.label_method)
125
+ end
126
+ end
127
+
128
+ def default(attribute)
129
+ if @object.respond_to?(attribute)
130
+ result = case macro_for(attribute)
131
+ when :belongs_to, :has_one
132
+ @object.send(attribute) || @object.send("build_#{attribute}")
133
+ when :has_many
134
+ @object.send(attribute.to_s.pluralize).build
135
+ else
136
+ @object.send(attribute)
137
+ end
138
+ result
139
+ elsif @object.is_a?(::OpenStruct)
140
+ result = ::OpenStruct.new
141
+ result.klass = attribute.to_s.camelize
142
+ @object.send("#{attribute}=", result)
143
+ result
144
+ else
145
+ nil
146
+ end
147
+ end
148
+
149
+ # If an association method is passed in (f.input :author) try to find the
150
+ # reflection object.
151
+ #
152
+ def reflection_for(method) #:nodoc:
153
+ @object.class.reflect_on_association(method) if @object.class.respond_to?(:reflect_on_association)
154
+ end
155
+
156
+ def macro_for(method)
157
+ reflection = reflection_for(method)
158
+ reflection ? reflection.macro : nil
159
+ end
160
+
161
+ # Get a column object for a specified attribute method - if possible.
162
+ #
163
+ def column_for(method) #:nodoc:
164
+ @object.column_for_attribute(method) if @object.respond_to?(:column_for_attribute)
165
+ end
166
+
167
+ def validations_for(method, mode = :active)
168
+ # ActiveModel?
169
+ validations = if @object && @object.class.respond_to?(:validators_on)
170
+ @object.class.validators_on(method)
171
+ else
172
+ # ValidationReflection plugin?
173
+ if @object && @object.class.respond_to?(:reflect_on_validations_for)
174
+ @object.class.reflect_on_validations_for(method)
175
+ else
176
+ []
177
+ end
178
+ end
179
+
180
+ validations = validations.select do |validation|
181
+ (validation.options.present? ? options_require_validation?(validation.options) : true)
182
+ end unless mode == :all
183
+
184
+ return validations
185
+ end
186
+
187
+ def get_maxlength_for(method)
188
+ validation = validations_for(method).find do |validation|
189
+ (validation.respond_to?(:macro) && validation.macro == :validates_length_of) || # Rails 2 validation
190
+ (validation.respond_to?(:kind) && validation.kind == :length) # Rails 3 validator
191
+ end
192
+
193
+ if validation
194
+ validation.options[:maximum] || (validation.options[:within].present? ? validation.options[:within].max : nil)
195
+ else
196
+ nil
197
+ end
198
+ end
199
+
200
+ # remove this, it's for old rails
201
+ def required?(attribute)
202
+ attribute_sym = attribute.to_s.sub(/_id$/, '').to_sym
203
+
204
+ if @object && @object.class.respond_to?(:reflect_on_validations_for)
205
+ @object.class.reflect_on_validations_for(attribute_sym).any? do |validation|
206
+ (validation.macro == :validates_presence_of || validation.macro == :validates_inclusion_of) &&
207
+ validation.name == attribute_sym &&
208
+ (validation.options.present? ? options_require_validation?(validation.options) : true)
209
+ end
210
+ else
211
+ if @object && @object.class.respond_to?(:validators_on)
212
+ !@object.class.validators_on(attribute_sym).find{|validator| (validator.kind == :presence || validator.kind == :inclusion) && (validator.options.present? ? options_require_validation?(validator.options) : true)}.nil?
213
+ else
214
+ true
215
+ end
216
+ end
217
+ end
218
+
219
+ def options_require_validation?(options)
220
+ allow_blank = options[:allow_blank]
221
+ return !allow_blank unless allow_blank.nil?
222
+ if_condition = !options[:if].nil?
223
+ condition = if_condition ? options[:if] : options[:unless]
224
+
225
+ condition = if condition.respond_to?(:call)
226
+ condition.call(@object)
227
+ elsif condition.is_a?(::Symbol) && @object.respond_to?(condition)
228
+ @object.send(condition)
229
+ else
230
+ condition
231
+ end
232
+
233
+ if_condition ? !!condition : !condition
234
+ end
235
+
236
+ def default_string_options(method, type)
237
+ validation_max_limit = get_maxlength_for(method)
238
+ column = column_for(method)
239
+
240
+ if type == :text
241
+ {:rows => default_text_area_height, :cols => config.default_text_area_width}
242
+ elsif type == :numeric || column.nil? || !column.respond_to?(:limit) || column.limit.nil?
243
+ {:maxlength => validation_max_limit, :size => config.default_text_field_size}
244
+ else
245
+ {:maxlength => validation_max_limit || column.limit, :size => config.default_text_field_size}
246
+ end
247
+ end
248
+ end
249
+ end
@@ -1,4 +1,3 @@
1
- # https://gist.github.com/af7e572c2dc973add221
2
1
  module Storefront
3
2
  class Railtie < Rails::Railtie
4
3
  initializer "storefront.insert_into_action_view" do
@@ -12,16 +11,19 @@ module Storefront
12
11
  end
13
12
 
14
13
  ActiveSupport.on_load :active_record do
15
- #
14
+ Object.send :include, Storefront::ModelHelper
16
15
  end
17
16
 
18
17
  ActiveSupport.on_load :action_controller do
19
18
  base = "#{File.expand_path(File.dirname(__FILE__))}/helpers"
20
19
  Dir["#{base}/*"].each do |path|
21
20
  next if File.directory?(path) || File.basename(path) =~ /(form|table|dashboard)/
21
+ # need to do these as traditional helper declarations somehow
22
22
  constant_name = File.basename(path, File.extname(path)).gsub("/", "::").camelize
23
23
  ActionController::Base.send :include, "Storefront::#{constant_name}".constantize
24
24
  end
25
+
26
+ ActionController::Base.send :before_filter, :configure_storefront
25
27
  end
26
28
  end
27
29
  end
@@ -1,5 +1,9 @@
1
1
  module Storefront
2
2
  class Table
3
+ include Storefront::AttributeHelper
4
+ include Storefront::LocaleHelper
5
+ include Storefront::TimeHelper
6
+
3
7
  attr_reader :content, :template, :key
4
8
 
5
9
  def initialize(template, *args, &block)
@@ -159,6 +163,9 @@ module Storefront
159
163
  attributes[:id] ||= id_for(:cell, key, value, @row_index, @cell_index)
160
164
  #attributes[:"aria-describedby"] = @headers[@cell_index]
161
165
  attributes[:headers] = @headers[@cell_index]
166
+ [:width, :height].each do |size|
167
+ attributes[size] = pixelate(attributes[size]) unless attributes[size].nil?
168
+ end
162
169
  template.capture_haml do
163
170
  if block_given?
164
171
  template.haml_tag :td, attributes, &block
@@ -2,4 +2,4 @@ require 'test_helper'
2
2
 
3
3
  class FormHelperTest < ActionView::TestCase
4
4
 
5
- end
5
+ end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: storefront
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.2.1
5
+ version: 0.2.7
6
6
  platform: ruby
7
7
  authors:
8
8
  - Lance Pollard
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-05-29 00:00:00 Z
13
+ date: 2011-07-05 00:00:00 Z
14
14
  dependencies: []
15
15
 
16
16
  description: Semantic HTML5 for Rails
@@ -23,15 +23,27 @@ extra_rdoc_files: []
23
23
 
24
24
  files:
25
25
  - Rakefile
26
- - init.rb
26
+ - lib/storefront/configuration.rb
27
27
  - lib/storefront/dashboard.rb
28
- - lib/storefront/form/elements.rb
28
+ - lib/storefront/form/base.rb
29
+ - lib/storefront/form/builder.rb
29
30
  - lib/storefront/form/errors.rb
30
- - lib/storefront/form/fields.rb
31
- - lib/storefront/form/hints.rb
32
- - lib/storefront/form/inputs.rb
33
- - lib/storefront/form/labels.rb
34
- - lib/storefront/form/model.rb
31
+ - lib/storefront/form/field.rb
32
+ - lib/storefront/form/fieldset.rb
33
+ - lib/storefront/form/hint.rb
34
+ - lib/storefront/form/input.rb
35
+ - lib/storefront/form/inputs/checkbox.rb
36
+ - lib/storefront/form/inputs/date.rb
37
+ - lib/storefront/form/inputs/file.rb
38
+ - lib/storefront/form/inputs/hidden.rb
39
+ - lib/storefront/form/inputs/radio.rb
40
+ - lib/storefront/form/inputs/range.rb
41
+ - lib/storefront/form/inputs/select.rb
42
+ - lib/storefront/form/inputs/string.rb
43
+ - lib/storefront/form/inputs/submit.rb
44
+ - lib/storefront/form/inputs/textarea.rb
45
+ - lib/storefront/form/inputs/value.rb
46
+ - lib/storefront/form/label.rb
35
47
  - lib/storefront/form.rb
36
48
  - lib/storefront/helpers/attribute_helper.rb
37
49
  - lib/storefront/helpers/body_helper.rb
@@ -59,29 +71,15 @@ files:
59
71
  - lib/storefront/helpers/sidebar_helper.rb
60
72
  - lib/storefront/helpers/system_helper.rb
61
73
  - lib/storefront/helpers/table_helper.rb
74
+ - lib/storefront/helpers/template_helper.rb
62
75
  - lib/storefront/helpers/time_helper.rb
63
76
  - lib/storefront/helpers/url_helper.rb
64
77
  - lib/storefront/helpers/user_helper.rb
65
78
  - lib/storefront/helpers/widget_helper.rb
66
79
  - lib/storefront/helpers/workflow_helper.rb
67
- - lib/storefront/microdata/address.rb
68
- - lib/storefront/microdata/event.rb
69
- - lib/storefront/microdata/geo.rb
70
- - lib/storefront/microdata/organization.rb
71
- - lib/storefront/microdata/person.rb
72
- - lib/storefront/microformat/event.rb
73
- - lib/storefront/microformat/person.rb
74
- - lib/storefront/models/container.rb
75
- - lib/storefront/models/element.rb
76
- - lib/storefront/models/form.rb
77
- - lib/storefront/models/form_element.rb
78
- - lib/storefront/models/link.rb
79
- - lib/storefront/models/list.rb
80
- - lib/storefront/models/list_element.rb
81
- - lib/storefront/models/table.rb
82
- - lib/storefront/models/term.rb
83
- - lib/storefront/models/term_list.rb
84
- - lib/storefront/models/validation.rb
80
+ - lib/storefront/model_helper.rb
81
+ - lib/storefront/proxies/attribute_proxy.rb
82
+ - lib/storefront/proxies/model_proxy.rb
85
83
  - lib/storefront/railtie.rb
86
84
  - lib/storefront/table.rb
87
85
  - lib/storefront.rb
data/init.rb DELETED
@@ -1 +0,0 @@
1
- File.dirname(__FILE__) + "/rails/init.rb"
@@ -1,101 +0,0 @@
1
- module Storefront
2
- class Form
3
- module Elements
4
- def wrapper_id(attribute, options = {})
5
-
6
- end
7
-
8
- # input :name, :as => :string, :class => "string something", :label_method => x, :value_method => y
9
- # disabled, readonly, accesskey, tabindex
10
- # button, checkbox, color, date, datetime, datetime-local, email, file, hidden, image, month, number, password, radio, range , reset, search, submit, tel, text, time, url, week
11
- def input(attribute, options = {}, &block)
12
- # aria-required=true
13
-
14
- options[:required] = required?(attribute) unless options.has_key?(:required)
15
- options[:as] ||= default_input_type(attribute, options)
16
-
17
- html_class = [
18
- options[:required] ? "required" : "optional",
19
- errors_on?(attribute, options) ? "error" : nil
20
- ].compact.uniq
21
-
22
- # input
23
- input_attributes = {}
24
- if options[:input_html].present?
25
- options[:input_html].each do |key, value|
26
- input_attributes[key] = value
27
- end
28
- end
29
- input_attributes[:class] = (html_class << (options.delete(:class) || options[:as]).to_s).compact.join(" ")
30
- input_attributes[:id] ||= input_id(attribute)
31
-
32
- input_attributes[:name] ||= input_name(attribute, options)
33
- input_attributes[:value] ||= input_value(attribute, options.delete(:value))
34
- input_attributes[:tabindex] = @tabindex
35
-
36
- @tabindex = @tabindex + 1
37
- access_key = input_attributes.delete(:accesskey) || access_key_for(attribute)
38
- input_attributes[:accesskey] = access_key
39
- #input_attributes = {
40
- # :input_attributes => input_attributes,
41
- # :include_blank => options.delete(:include_blank)
42
- #}
43
-
44
- # label
45
- unless options[:label] == false
46
- label_attributes = options.delete(:label_html) || {}
47
- label_attributes[:for] ||= input_attributes[:id]
48
- label_attributes[:id] ||= input_id(attribute, "label")
49
- label_attributes[:class] = "label"
50
- label_attributes[:value] = localized_string(attribute, options[:label], :label)
51
- label_attributes[:value] = humanized_attribute_name(attribute) if label_attributes[:value].blank?
52
- else
53
- label_attributes = false
54
- end
55
-
56
- # wrapper
57
- wrapper_attributes = options.delete(:wrapper_attributes) || {}
58
- wrapper_attributes[:class] = (html_class << wrapper_attributes[:class]).compact.join(" ")
59
- wrapper_attributes[:id] ||= input_id(attribute, "field")
60
-
61
- # hint
62
- #return if options[:hint].blank? or options[:hint].kind_of? Hash
63
- hint_class = options[:hint_class]# || default_hint_class
64
- hint_attributes = options.delete(:hint_html) || {}
65
- hint_attributes[:class] = "hint inline-hints"
66
- hint_attributes[:value] = localized_string(attribute, options[:hint], :hint)
67
-
68
- # error
69
- error_attributes = options.delete(:error_html) || {}
70
- error_attributes[:class] = "error"
71
-
72
- elements = []
73
- if options[:as] == :hidden
74
- elements << :input
75
- else
76
- if label_attributes
77
- elements << :label
78
- end
79
- elements = elements.concat [:input, :hints, :errors]
80
- end
81
-
82
- options[:input_attributes] = input_attributes
83
- options[:label_attributes] = label_attributes
84
- options[:hint_attributes] = hint_attributes
85
- options[:error_attributes] = error_attributes
86
-
87
- template.capture_haml do
88
- template.haml_tag :li, wrapper_attributes do
89
- result = elements.map do |element|
90
- send("#{element}_for", attribute, options)
91
- #if element == :input && block_given?
92
- # yield
93
- #end
94
- end.join
95
- template.haml_concat result.gsub(/\n$/, "")
96
- end
97
- end
98
- end
99
- end
100
- end
101
- end