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
@@ -3,35 +3,27 @@ module Storefront
3
3
  def dashboard_for(*args, &block)
4
4
  record = args.shift
5
5
  options = args.extract_options!
6
- condition = extract_condition!(options)
7
6
  @dashboard_record = record
8
- concat(capture(&block)) if record && condition != false
7
+ concat(capture(&block)) if record
9
8
  @dashboard_record = nil
10
9
  end
11
-
12
- def dashboard(key, locals = {})
13
- render :partial => key, :locals => locals.reverse_merge(:figures => [])
14
- end
15
-
10
+
16
11
  def figure(*names, &block)
17
12
  locals = names.extract_options!
18
- condition = extract_condition!(locals)
19
13
 
20
- if condition != false
21
- locals.reverse_merge(:locale => nil)
22
- locals.merge!(:yielded_content => capture(&block)) if block_given?
23
- result = capture_haml do
24
- names.each do |name|
25
- haml_concat render(:partial => "shared/dashboard/#{name}", :locals => locals)
26
- end
14
+ locals.reverse_merge(:locale => nil)
15
+ locals.merge!(:yielded_content => capture(&block)) if block_given?
16
+ result = capture_haml do
17
+ names.each do |name|
18
+ haml_concat render(:partial => "shared/dashboard/#{name}", :locals => locals)
27
19
  end
28
20
  end
29
21
 
30
22
  result
31
23
  end
32
-
24
+
33
25
  def report_for(record_or_key, hash, options = {}, &block)
34
- Semantic::Dashboard.new(self, record_or_key, hash, options, &block).content
26
+ Storefront::Dashboard.new(self, record_or_key, hash, options, &block).content
35
27
  end
36
28
  end
37
29
  end
@@ -1,29 +1,97 @@
1
1
  module Storefront
2
- module DefinitionListHelper
3
- def term(key, value, options = {})
4
- return if value.blank?
5
- condition = extract_condition!(options)
2
+ module DefinitionListHelper
3
+ def definition_list_widget(*args, &block)
4
+ options = definition_list_widget_options(*args)
5
+
6
+ capture_haml do
7
+ haml_tag options[:as], options[:outer_html] do
8
+ @separator = options.has_key?(:separator) ? options[:separator] : storefront_config.term_separator
9
+ header = header_widget(options)
10
+ haml_concat header.gsub(/\n$/, "") if header.present?
6
11
 
7
- if condition != false
8
- result = capture_haml do
9
- haml_tag :tr, :class => "term" do
10
- text = key.is_a?(String) ? key : t("widgets.details.#{key}")
11
- haml_tag :td, text.gsub(/:?$/, ":"), :class => "key first"
12
- haml_tag :td, value, :class => "value"
12
+ haml_tag options[:tag], options[:content_html], &block
13
+
14
+ if options[:footer_html].present?
15
+ haml_concat footer_widget(options[:footer_html])
13
16
  end
17
+ @separator = nil
14
18
  end
15
19
  end
20
+ end
21
+ alias terms_widget definition_list_widget
22
+
23
+ def definition_list_widget_options(*args)
24
+ options = widget_options("definition-list-widget", *args)
25
+
26
+ options[:as] ||= :section
27
+ options[:tag] ||= storefront_config.terms_tag
28
+
29
+ options[:content_html] ||= {}
30
+ merge_class! options[:content_html], storefront_config.content_class
31
+
32
+ options
33
+ end
34
+
35
+ def definition(key, value, options = {})
36
+ locale_options = options.delete(:locale_options) || {}
37
+ label = t?(key, locale_options.reverse_merge(:scope => :"terms.labels"))
38
+
39
+ key_html = options.delete(:key_html) || {}
40
+ value_html = options.delete(:value_html) || {}
41
+
42
+ key_html.reverse_merge! clone_attributes(options)
43
+ value_html.reverse_merge! clone_attributes(options)
44
+
45
+ merge_class! key_html, storefront_config.term_key_class
46
+ merge_class! value_html, storefront_config.term_value_class
47
+
48
+ id_base = label.underscore.strip.gsub(/[\s|_]+/, storefront_config.separator).squeeze(storefront_config.separator)
49
+
50
+ key_html[:id] ||= "#{id_base}-key"
51
+ value_html[:id] ||= "#{id_base}-value"
52
+
53
+ separator = options[:separator] || @separator
54
+
55
+ label.gsub!(/#{separator}?$/, separator) if separator.present?
56
+
57
+ if storefront_config.include_aria
58
+ value_html[:role] ||= :definition
59
+ value_html[:"aria-labelledby"] = key_html[:id]
60
+ #value_html[:"aria-describedby"] = hint_html[:id]
61
+ end
16
62
 
17
- result
63
+ if storefront_config.terms_tag == :table
64
+ _table_term(label, value, key_html, value_html)
65
+ else
66
+ _definiton_list_term(label, value, key_html, value_html)
67
+ end
18
68
  end
69
+ alias term definition
19
70
 
20
- def terms(&block)
71
+ def definition_list(&block)
21
72
  capture_haml do
22
- haml_tag :dl do
73
+ haml_tag storefront_config.terms_tag do
23
74
  yield
24
75
  end
25
76
  end
26
77
  end
27
- alias definition_list terms
78
+ alias terms definition_list
79
+
80
+ protected
81
+ def _definiton_list_term(label, value, key_html, value_html)
82
+ capture_haml do
83
+ haml_tag :dt, label, key_html
84
+ haml_tag :dd, value, value_html
85
+ end
86
+ end
87
+
88
+ def _table_term(label, value, key_html, value_html)
89
+ capture_haml do
90
+ haml_tag :tr, :class => storefront_config.term_class do
91
+ haml_tag :td, label, key_html
92
+ haml_tag :td, value, value_html
93
+ end
94
+ end
95
+ end
28
96
  end
29
97
  end
@@ -1,8 +1,13 @@
1
1
  module Storefront
2
2
  module FormHelper
3
3
  def form_for(*args, &block)
4
- Storefront::Form.new(self, *args, &block).content
4
+ Storefront::Form.new(self, *args).render(&block)
5
+ end
6
+
7
+ def submit_for(text, url, options = {})
8
+ form_for(object, options.merge(:url => url)) do |form|
9
+ haml_concat Storefront::Form::Input.find(:submit).new(:value => text).render
10
+ end
5
11
  end
6
12
  end
7
13
  end
8
-
@@ -193,7 +193,7 @@ module Storefront
193
193
  def content_type_tag(type = "text/html", charset = "UTF-8")
194
194
  meta_tag("Content-Type", "#{type}; charset=#{charset}")
195
195
  end
196
-
196
+
197
197
  def search_link_tag(href, title)
198
198
  link_tag({:rel => "search", :type => "application/opensearchdescription+xml", :href => href, :title => title})
199
199
  end
@@ -201,7 +201,7 @@ module Storefront
201
201
  def favicon_link_tag(favicon = "/favicon.ico")
202
202
  link_tag({:rel => "shortcut icon", :href => favicon, :type => "image/x-icon"})
203
203
  end
204
-
204
+
205
205
  def link_tag(options = {})
206
206
  tag(:link, options)
207
207
  end
@@ -20,31 +20,7 @@ module Storefront
20
20
 
21
21
  tag("img", options)
22
22
  end
23
-
24
- def load_logo(parent, size = "small", link = nil, lightbox = true)
25
- if parent && parent.logo_id.present?
26
- path = parent.logo.url(size.to_s) rescue nil
27
- end
28
-
29
- if path.blank?
30
- path = "/images/vendors/no-logo.png"
31
- alt = "No logo"
32
- else
33
- alt = "Logo for #{parent.is_a?(::Group) ? parent.name : parent.vendor_name}"
34
- end
35
-
36
- if parent && parent.logo
37
- path << "?#{parent.logo.updated_at.to_i}"
38
- end
39
- if link
40
- # , :width => 74, :height => 74
41
- clazz = lightbox == true ? 'fancy-ajax logo' : 'logo'
42
- link_to [content_tag(:span), image_tag(path, :class => "photo", :alt => alt, :title => alt)].join("").html_safe, link, :class => clazz, :"data-deal-id" => parent.id, :"data-ajax" => "false"
43
- else
44
- image_tag(path)
45
- end
46
- end
47
-
23
+
48
24
  # http://snippets.dzone.com/posts/show/805
49
25
  def read_image_size(path)
50
26
  width, height = IO.read("#{Rails.root}/public/images/#{path}")[0x10..0x18].unpack('NN')
@@ -1,47 +1,135 @@
1
1
  module Storefront
2
2
  module ListHelper
3
- def nav(key, path = nil, attributes = {}, &block)
4
- condition = extract_condition!(attributes)
5
- return if condition == false
6
- text = widget_text(key, :nav)
3
+ def list_widget(*args, &block)
4
+ options = list_widget_options("list-widget", *args)
5
+
6
+ capture_haml do
7
+ haml_tag :nav, options[:outer_html] do
8
+ @list_context = :list
9
+
10
+ header = header_widget(options)
11
+ haml_concat header if header.present?
12
+
13
+ haml_tag options[:tag], options[:inner_html], &block
14
+
15
+ footer_widget(options[:footer_html]) if options[:footer_html].present?
16
+
17
+ @list_context = nil
18
+ end
19
+ end
20
+ end
21
+
22
+ def list_widget_options(*args)
23
+ options = widget_options(*args)
24
+
25
+ options[:tag] ||= :ul
26
+
27
+ if storefront_config.include_aria
28
+ options[:outer_html][:role] ||= :list
29
+ end
30
+
31
+ options[:inner_html] ||= {}
32
+
33
+ merge_class! options[:inner_html], *[
34
+ "list-items"
35
+ ]
36
+
37
+ options
38
+ end
39
+
40
+ def menu_widget(*args, &block)
41
+ options = menu_widget_options("menu-widget", *args)
42
+
43
+ capture_haml do
44
+ haml_tag :nav, options[:outer_html] do
45
+ @list_context = :menu
46
+ header = header_widget(options)
47
+ haml_concat header if header.present?
48
+
49
+ haml_tag options[:tag], options[:inner_html], &block
50
+
51
+ footer_widget(options[:footer_html]) if options[:footer_html].present?
52
+ @list_context = nil
53
+ end
54
+ end
55
+ end
56
+ alias nav_widget menu_widget
57
+
58
+ def menu_widget_options(*args)
59
+ options = widget_options(*args)
60
+
61
+ if storefront_config.include_aria
62
+ options[:outer_html][:role] ||= :menu
63
+ end
64
+
65
+ options[:inner_html] ||= {}
66
+
67
+ options[:tag] ||= :ol
68
+
69
+ merge_class! options[:inner_html], *[
70
+ "list-items"
71
+ ]
72
+
73
+ options
74
+ end
75
+
76
+ def list_item(key, path = nil, attributes = {}, &block)
77
+ locale_options = attributes.delete(:locale_options) || {}
78
+ text = t?(key, locale_options.reverse_merge(:scope => :"widgets.nav"))
79
+
80
+ as = attributes.delete(:as) || :span
81
+ separator = attributes.delete(:separator)
82
+
7
83
  if attributes.has_key?(:current)
8
- current = attributes.delete(:current) == true
84
+ current = attributes.delete(:current) == true
9
85
  else
10
- current = on_current_page?(path)
86
+ current = on_current_page?(path)
11
87
  end
12
- li_class = "primary-navigation-item"
13
- if current
14
- li_class << " active"
15
- attributes[:class] = [attributes[:class], "active"].compact.uniq.join(" ")
88
+
89
+ inner_html = attributes.delete(:inner_html) || {}
90
+ outer_html = attributes.delete(:outer_html) || {}
91
+
92
+ inner_html.merge! clone_attributes(attributes)
93
+
94
+ merge_class! outer_html, *[
95
+ storefront_config.nav_class,
96
+ current ? storefront_config.active_class : nil
97
+ ].compact.uniq
98
+
99
+ if storefront_config.include_aria
100
+ outer_html[:role] ||= case @list_context
101
+ when :list
102
+ :listitem
103
+ when :menu
104
+ :menuitem
105
+ else
106
+ :listitem
107
+ end
16
108
  end
17
- as = attributes.delete(:as) || :span
18
- li_class << " #{attributes.delete(:li_class)}" if attributes[:li_class]
19
- li_class = li_class.present? ? {:class => li_class} : nil
20
- separator = attributes.delete(:separator)
21
- checkbox = attributes.delete(:checkbox) == true
22
- result = capture_haml do
23
- haml_tag :li, li_class do
24
- if checkbox
25
- haml_tag :label, text.strip
26
- haml_tag :input, :type => "checkbox"
27
- else
28
- if block_given?
29
- case block.arity
30
- when 1
31
- yield(text.strip)
32
- else
33
- yield
34
- end
35
- elsif current && as == :span
36
- haml_tag :span, text.strip, attributes
109
+
110
+ text.strip!
111
+
112
+ outer_html[:id] ||= [text.underscore.parameterize, storefront_config.nav_class].join(storefront_config.separator).gsub(/[\s|_]+/, storefront_config.separator).squeeze(storefront_config.separator)
113
+
114
+ capture_haml do
115
+ haml_tag storefront_config.nav_tag, outer_html do
116
+ if block_given?
117
+ case block.arity
118
+ when 1
119
+ yield(text.strip)
37
120
  else
38
- haml_concat link_to(text.strip, path, attributes)
121
+ yield
39
122
  end
123
+ elsif current && as == :span
124
+ haml_tag :span, text, inner_html
125
+ else
126
+ inner_html[:title] ||= "Link to the #{text.strip} page."
127
+ haml_concat link_to(text, path, inner_html)
40
128
  end
41
129
  haml_tag :span, separator if separator
42
130
  end
43
131
  end
44
- result
45
132
  end
133
+ alias nav list_item
46
134
  end
47
135
  end
@@ -1,23 +1,61 @@
1
1
  module Storefront
2
2
  module LocaleHelper
3
- # t!(:"what.summary", :scope => :"reports.titles", :model => deal)
3
+ SCOPES_WITH_NAMESPACE_AND_NESTED_MODEL = [
4
+ '%{namespace}.%{model}.%{nested_model}.%{action}.%{attribute}',
5
+ '%{model}.%{nested_model}.%{action}.%{attribute}',
6
+ '%{namespace}.%{model}.%{action}.%{attribute}',
7
+ '%{model}.%{action}.%{attribute}',
8
+ '%{namespace}.%{model}.%{nested_model}.%{attribute}',
9
+ '%{model}.%{nested_model}.%{attribute}',
10
+ '%{namespace}.%{model}.%{attribute}',
11
+ '%{model}.%{attribute}',
12
+ '%{namespace}.%{nested_model}.%{attribute}',
13
+ '%{nested_model}.%{attribute}',
14
+ '%{namespace}.%{attribute}',
15
+ '%{attribute}'
16
+ ]
17
+
18
+ SCOPES_WITH_NESTED_MODEL = [
19
+ '%{model}.%{nested_model}.%{action}.%{attribute}',
20
+ '%{model}.%{action}.%{attribute}',
21
+ '%{model}.%{nested_model}.%{attribute}',
22
+ '%{model}.%{attribute}',
23
+ '%{nested_model}.%{attribute}',
24
+ '%{attribute}'
25
+ ]
26
+
27
+ SCOPES_WITH_NAMESPACE = [
28
+ '%{namespace}.%{model}.%{action}.%{attribute}',
29
+ '%{namespace}.%{model}.%{attribute}',
30
+ '%{model}.%{action}.%{attribute}',
31
+ '%{model}.%{attribute}',
32
+ '%{namespace}.%{attribute}',
33
+ '%{attribute}'
34
+ ]
35
+
36
+ SCOPES = [
37
+ '%{model}.%{action}.%{attribute}',
38
+ '%{model}.%{attribute}',
39
+ '%{attribute}'
40
+ ]
41
+
42
+ # t?(:"what.summary", :scope => :"reports.titles", :model => deal)
4
43
  def t?(key, options = {})
5
- return key if key.is_a?(::String)
6
- model_names = options[:model_names]
7
- model_names ||= options[:model].present? ? options[:model].class.ancestor_classes.map { |i| i.name.underscore } : []
8
- allow_blank = options.delete(:allow_blank) == true
9
-
10
- keys = [key.to_s]
11
- if options[:try].present?
12
- keys += Array(options[:default]).map do |extra_key|
13
- "#{key}.#{extra_key}"
14
- end
15
- end
44
+ return key if key.is_a?(::String) || key.blank?
16
45
 
46
+ models = Storefront::ModelProxy.model_names(options[:model] || options[:models] || options[:model_names] || storefront_config.current_scope[:resource] || [])
47
+ models << "" if models.blank?
48
+ namespaces = Array(options[:namespaces] || options[:namespace] || storefront_config.current_scope[:namespace])
49
+ namespaces << "" if namespaces.blank? && !!storefront_config.localize_with_namespace
50
+ action_name = options[:action] || storefront_config.current_scope[:action]
51
+ defaults = []
52
+ allow_blank = options.delete(:allow_blank) == true
17
53
  count = options.delete(:count)
18
54
  # none, one, many, other
19
55
  count_key = count != 1 ? :other : :one
20
56
 
57
+ keys = [key.to_s]
58
+
21
59
  if options.has_key?(:present) || options.has_key?(:past) || options.has_key?(:future)
22
60
  if options[:future] == true
23
61
  tense_key = :future
@@ -28,21 +66,53 @@ module Storefront
28
66
  tense_key = nil
29
67
  end
30
68
 
31
- defaults = []
69
+ if options.has_key?(:nested_model)
70
+ with_nested_model = !!options[:nested_model]
71
+ else
72
+ with_nested_model = !!storefront_config.localize_with_nested_model
73
+ end
32
74
 
33
- keys.each do |key|
34
- model_names.each do |model_name|
35
- path = '{{model}}.{{key}}'
36
- path.gsub!('{{model}}', model_name)
37
- path.gsub!('{{key}}', key)
38
- path.gsub!('..', '.')
39
- defaults << path
40
- end
75
+ if options.has_key?(:namespace)
76
+ with_namespace = !!options[:namespace]
77
+ else
78
+ with_namespace = !!storefront_config.localize_with_namespace
79
+ end
41
80
 
42
- path = '{{key}}'
43
- path.gsub!('{{key}}', key)
44
- path.gsub!('..', '.')
45
- defaults << path
81
+ if with_nested_model && with_namespace
82
+ # TODO, need to performance test before we do this many operations
83
+ SCOPES_WITH_NAMESPACE_AND_NESTED_MODEL
84
+ elsif with_nested_model
85
+ # TODO
86
+ SCOPES_WITH_NESTED_MODEL
87
+ elsif with_namespace
88
+ namespaces.each do |namespace|
89
+ models.each do |model|
90
+ keys.each do |_key|
91
+ SCOPES_WITH_NAMESPACE.each do |path|
92
+ path = path.dup
93
+ path.gsub!('%{namespace}', namespace)
94
+ path.gsub!('%{model}', model)
95
+ path.gsub!('%{action}', action_name)
96
+ path.gsub!('%{attribute}', _key)
97
+ path.gsub!('..', '.')
98
+ defaults << path
99
+ end
100
+ end
101
+ end
102
+ end
103
+ else
104
+ models.each do |model|
105
+ keys.each do |_key|
106
+ SCOPES.each do |path|
107
+ path = path.dup
108
+ path.gsub!('%{model}', model)
109
+ path.gsub!('%{action}', action_name)
110
+ path.gsub!('%{attribute}', _key)
111
+ path.gsub!('..', '.')
112
+ defaults << path
113
+ end
114
+ end
115
+ end
46
116
  end
47
117
 
48
118
  defaults.map!(&:to_sym)
@@ -146,9 +216,9 @@ module Storefront
146
216
  title = object[:title] || object[:label]
147
217
  subtitle = object[:subtitle]
148
218
 
149
- title = t!(:"#{key}", options.merge(:try => :title))
219
+ title = t?(:"#{key}", options.merge(:try => :title))
150
220
  title = key.to_s.split(".").last.titleize if title.blank? || title.is_a?(::Hash)
151
- subtitle = t!(:"#{key}.subtitle", options.merge(:allow_blank => true))
221
+ subtitle = t?(:"#{key}.subtitle", options.merge(:allow_blank => true))
152
222
 
153
223
  # everything has to have a title
154
224
  result[:title] = title
@@ -156,7 +226,7 @@ module Storefront
156
226
  # not everything has to have a subtitle
157
227
  result[:subtitle] = subtitle if subtitle.present?
158
228
 
159
- # it's a leaf if we're at this point!
229
+ # it's a leaf if we're at this point?
160
230
  if object.has_key?(:value)
161
231
  result[:value] = object[:value]
162
232
  else