storefront 0.2.1 → 0.2.7

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.
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