storefront 0.3.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. data/Rakefile +4 -4
  2. data/lib/storefront.rb +22 -35
  3. data/lib/storefront/components/base.rb +99 -0
  4. data/lib/storefront/components/breadcrumb.rb +7 -0
  5. data/lib/storefront/components/button.rb +37 -0
  6. data/lib/storefront/components/definition_list.rb +34 -0
  7. data/lib/storefront/components/definition_list_item.rb +63 -0
  8. data/lib/storefront/components/flash.rb +12 -0
  9. data/lib/storefront/components/footer.rb +19 -0
  10. data/lib/storefront/components/form.rb +82 -0
  11. data/lib/storefront/{form → components/form}/base.rb +3 -3
  12. data/lib/storefront/{form → components/form}/builder.rb +3 -3
  13. data/lib/storefront/{form → components/form}/errors.rb +1 -3
  14. data/lib/storefront/{form → components/form}/field.rb +1 -1
  15. data/lib/storefront/{form → components/form}/fieldset.rb +0 -0
  16. data/lib/storefront/{form → components/form}/hint.rb +0 -0
  17. data/lib/storefront/{form → components/form}/input.rb +7 -5
  18. data/lib/storefront/components/form/inputs.rb +7 -0
  19. data/lib/storefront/{form → components/form}/inputs/checkbox.rb +0 -0
  20. data/lib/storefront/{form → components/form}/inputs/date.rb +0 -0
  21. data/lib/storefront/{form → components/form}/inputs/file.rb +0 -0
  22. data/lib/storefront/{form → components/form}/inputs/hidden.rb +0 -0
  23. data/lib/storefront/{form → components/form}/inputs/radio.rb +0 -0
  24. data/lib/storefront/{form → components/form}/inputs/range.rb +0 -0
  25. data/lib/storefront/{form → components/form}/inputs/select.rb +6 -6
  26. data/lib/storefront/{form → components/form}/inputs/string.rb +0 -0
  27. data/lib/storefront/{form → components/form}/inputs/submit.rb +0 -0
  28. data/lib/storefront/{form → components/form}/inputs/textarea.rb +0 -0
  29. data/lib/storefront/{form → components/form}/inputs/value.rb +0 -0
  30. data/lib/storefront/{form → components/form}/label.rb +1 -1
  31. data/lib/storefront/components/header.rb +73 -0
  32. data/lib/storefront/components/image.rb +12 -0
  33. data/lib/storefront/components/javascript_template.rb +21 -0
  34. data/lib/storefront/components/list.rb +27 -0
  35. data/lib/storefront/components/menu.rb +41 -0
  36. data/lib/storefront/components/nav.rb +78 -0
  37. data/lib/storefront/components/sidebar.rb +23 -0
  38. data/lib/storefront/components/table.rb +232 -0
  39. data/lib/storefront/components/text.rb +29 -0
  40. data/lib/storefront/configuration.rb +53 -5
  41. data/lib/storefront/helpers/cache_helper.rb +37 -19
  42. data/lib/storefront/helpers/component_helper.rb +80 -41
  43. data/lib/storefront/helpers/content_helper.rb +211 -0
  44. data/lib/storefront/helpers/dom_helper.rb +136 -0
  45. data/lib/storefront/helpers/head_helper.rb +277 -205
  46. data/lib/storefront/helpers/model_helper.rb +21 -0
  47. data/lib/storefront/helpers/request_helper.rb +301 -53
  48. data/lib/storefront/helpers/tag_helper.rb +29 -0
  49. data/lib/storefront/{proxies/attribute_proxy.rb → models/attribute.rb} +1 -1
  50. data/lib/storefront/{proxies/model_proxy.rb → models/model.rb} +4 -6
  51. data/lib/storefront/railtie.rb +3 -16
  52. metadata +48 -64
  53. data/lib/storefront/dashboard.rb +0 -185
  54. data/lib/storefront/form.rb +0 -82
  55. data/lib/storefront/helpers/attribute_helper.rb +0 -81
  56. data/lib/storefront/helpers/body_helper.rb +0 -18
  57. data/lib/storefront/helpers/browser_helper.rb +0 -54
  58. data/lib/storefront/helpers/collection_helper.rb +0 -14
  59. data/lib/storefront/helpers/dashboard_helper.rb +0 -29
  60. data/lib/storefront/helpers/debug_helper.rb +0 -11
  61. data/lib/storefront/helpers/definition_list_helper.rb +0 -110
  62. data/lib/storefront/helpers/error_helper.rb +0 -11
  63. data/lib/storefront/helpers/flash_helper.rb +0 -14
  64. data/lib/storefront/helpers/form_helper.rb +0 -13
  65. data/lib/storefront/helpers/format_helper.rb +0 -59
  66. data/lib/storefront/helpers/image_helper.rb +0 -30
  67. data/lib/storefront/helpers/list_helper.rb +0 -135
  68. data/lib/storefront/helpers/locale_helper.rb +0 -245
  69. data/lib/storefront/helpers/open_graph_helper.rb +0 -5
  70. data/lib/storefront/helpers/page_helper.rb +0 -91
  71. data/lib/storefront/helpers/presenter_helper.rb +0 -5
  72. data/lib/storefront/helpers/semantic/location_helper.rb +0 -18
  73. data/lib/storefront/helpers/semantic/time_helper.rb +0 -14
  74. data/lib/storefront/helpers/sidebar_helper.rb +0 -27
  75. data/lib/storefront/helpers/system_helper.rb +0 -18
  76. data/lib/storefront/helpers/table_helper.rb +0 -38
  77. data/lib/storefront/helpers/template_helper.rb +0 -11
  78. data/lib/storefront/helpers/time_helper.rb +0 -21
  79. data/lib/storefront/helpers/url_helper.rb +0 -32
  80. data/lib/storefront/helpers/user_helper.rb +0 -15
  81. data/lib/storefront/helpers/widget_helper.rb +0 -142
  82. data/lib/storefront/helpers/workflow_helper.rb +0 -50
  83. data/lib/storefront/model_helper.rb +0 -17
  84. data/lib/storefront/table.rb +0 -198
  85. data/rails/init.rb +0 -1
  86. data/test/form_helper_test.rb +0 -5
  87. data/test/support/mock_controller.rb +0 -15
  88. data/test/support/mock_response.rb +0 -14
  89. data/test/support/models.rb +0 -0
  90. data/test/test_helper.rb +0 -34
@@ -0,0 +1,232 @@
1
+ module Storefront
2
+ module Components
3
+ class Table < Base
4
+
5
+ attr_reader :content, :template, :key
6
+
7
+ def initialize(template, *args)
8
+ @template = template
9
+ options = args.extract_options!
10
+ record_or_key = args.shift
11
+ @key = record_key(record_or_key)
12
+ @row_index = 0
13
+ @cell_index = 0
14
+ @scope = :table
15
+ @headers = []
16
+ options[:summary] ||= "Table for #{key.titleize}"
17
+ options[:class] = ["data-table", options[:class]].compact.uniq.join(" ")
18
+ options[:role] = :grid
19
+ data = options.delete(:data) || {}
20
+ data[:url] = options[:url] || @template.controller.request.path
21
+ data[:for] = options[:for] || options[:model] || @key
22
+ data[:total] = options[:total] if options[:total]
23
+ data[:page] = options[:page] if options[:page]
24
+ data[:count] = options[:count] if options[:count]
25
+ aria = options.delete(:aria) || {}
26
+ aria[:"aria-multiselectable"] = false unless aria.has_key?(:"aria-multiselectable") || options[:multiselect] == true
27
+ options[:data] = data
28
+ options[:id] ||= "#{record_or_key.to_s}-table"
29
+ end
30
+
31
+ def render(&block)
32
+ template.capture_haml do
33
+ template.haml_tag :table, options do
34
+ yield(self)
35
+ end
36
+ end
37
+ end
38
+
39
+ def table_query_row_class
40
+ ["search-row", query_params.except("page", "sort").blank? ? nil : "search-results"].compact.join(" ")
41
+ end
42
+
43
+ def link_to_sort(title, attribute, options = {})
44
+ sort_param = sort_value(attribute, opposite_sort_direction(attribute))
45
+ link_to title, with_params(request.path, :sort => sort_param), options
46
+ end
47
+
48
+ def next_page_path(collection)
49
+ with_params(request.path, :page => collection.next_page)
50
+ end
51
+
52
+ def prev_page_path(collection)
53
+ with_params(request.path, :page => collection.prev_page)
54
+ end
55
+
56
+ def first_page_path(collection)
57
+ with_params(request.path, :page => 1)
58
+ end
59
+
60
+ def last_page_path(collection)
61
+ with_params(request.path, :page => collection.last_page)
62
+ end
63
+
64
+ def current_page_num
65
+ page = params[:page] ? params[:page].to_i : 1
66
+ page = 1 if page < 1
67
+ page
68
+ end
69
+
70
+ def caption
71
+
72
+ end
73
+
74
+ # scope='col'
75
+ def head(attributes = {}, &block)
76
+ @hide_header = attributes.delete(:visible) == false
77
+ template.capture_haml do
78
+ @row_index = 0
79
+ @scope = :head
80
+ template.haml_tag :thead, attributes, &block
81
+ @row_index = 0
82
+ @scope = :table
83
+ end
84
+ end
85
+
86
+ # scope='row'
87
+ # <td headers='x'/>
88
+ def body(attributes = {}, &block)
89
+ template.capture_haml do
90
+ @row_index = 0
91
+ @scope = :body
92
+ template.haml_tag :tbody, attributes, &block
93
+ @row_index = 0
94
+ @scope = :table
95
+ end
96
+ end
97
+
98
+ def foot(attributes = {}, &block)
99
+ template.capture_haml do
100
+ @row_index = 0
101
+ @scope = :foot
102
+ template.haml_tag :tfoot, attributes, &block
103
+ @row_index = 0
104
+ @scope = :table
105
+ end
106
+ end
107
+
108
+ def row(*args, &block)
109
+ attributes = args.extract_options!
110
+ if @scope == :body
111
+ attributes[:class] = [template.cycle("odd", "even"), attributes[:class]].compact.uniq.join(" ")
112
+ end
113
+ attributes[:role] = :row
114
+ attributes[:scope] = :row
115
+ template.capture_haml do
116
+ @row_index += 1
117
+ @cell_index = 0
118
+ template.haml_tag :tr, attributes, &block
119
+ @cell_index = 0
120
+ end
121
+ end
122
+
123
+ def column(*args, &block)
124
+ attributes = args.extract_options!
125
+ value = args.shift
126
+ attributes[:id] ||= id_for(:header, key, value, @row_index, @cell_index) if config.id_enabled_on.include?("table")
127
+ [:width, :height].each do |size|
128
+ attributes[size] = pixelate(attributes[size]) unless attributes[size].nil?
129
+ end
130
+ @headers.push(attributes[:id])
131
+
132
+ template.capture_haml do
133
+ template.haml_tag :col, attributes
134
+ @cell_index += 1
135
+ end
136
+ end
137
+
138
+ # direction => "ascending"
139
+ # valid directions: ascending, descending, none, other
140
+ # abbr is what the header controls (for sorting)
141
+ def header(*args, &block)
142
+ attributes = args.extract_options!
143
+ value = args.shift
144
+ if value.is_a?(::Symbol)
145
+ attributes[:abbr] ||= value.to_s
146
+ end
147
+ # aria-selected if sorted
148
+ attributes[:role] = :columnheader
149
+ attributes[:id] ||= id_for(:header, key, value, @row_index, @cell_index) if config.id_enabled_on.include?("table")
150
+ attributes[:scope] = :col
151
+ attributes[:abbr] ||= attributes.delete(:for) if attributes.has_key?(:for)
152
+ [:width, :height].each do |size|
153
+ attributes[size] = pixelate(attributes[size]) unless attributes[size].nil?
154
+ end
155
+ sort = attributes.delete(:sort) == true
156
+ label = attributes.delete(:label) || (value.is_a?(::String) ? value.strip : value.to_s.titleize)
157
+
158
+ if sort
159
+ attributes[:class] = [attributes[:class], attributes.delete(:sort_class) || "sortable"].compact.uniq.join(" ")
160
+ attributes[:direction] ||= template.sort_class(value)
161
+ end
162
+
163
+ direction = attributes.delete(:direction)
164
+ if direction.present?
165
+ attributes[:"aria-sort"] = direction
166
+ attributes[:class] = [attributes[:class], direction].join(" ")
167
+ attributes[:"aria-selected"] = true
168
+ else
169
+ attributes[:"aria-sort"] = "none"
170
+ attributes[:"aria-selected"] = false
171
+ end
172
+
173
+ @headers.push(attributes[:id])
174
+ template.capture_haml do
175
+ if block_given?
176
+ template.haml_tag :th, attributes, &block
177
+ else
178
+ if sort
179
+ template.haml_tag :th, attributes do
180
+ template.haml_concat template.link_to_sort(label, value)
181
+ end
182
+ else
183
+ template.haml_tag :th, attributes do
184
+ template.haml_tag :span, label
185
+ end
186
+ end
187
+ end
188
+ @cell_index += 1
189
+ end
190
+ end
191
+
192
+ def cell(*args, &block)
193
+ attributes = args.extract_options!
194
+ value = args.shift
195
+ attributes[:role] = :gridcell
196
+ attributes[:id] ||= id_for(:cell, key, value, @row_index, @cell_index) if config.id_enabled_on.include?("table")
197
+ #attributes[:"aria-describedby"] = @headers[@cell_index]
198
+ attributes[:headers] = @headers[@cell_index]
199
+ [:width, :height].each do |size|
200
+ attributes[size] = pixelate(attributes[size]) unless attributes[size].nil?
201
+ end
202
+ template.capture_haml do
203
+ if block_given?
204
+ template.haml_tag :td, attributes, &block
205
+ else
206
+ template.haml_tag :td, value.to_s.strip, attributes
207
+ end
208
+ @cell_index += 1
209
+ end
210
+ end
211
+
212
+ def record_key(record_or_key)
213
+ if record_or_key.is_a?(String) || record_or_key.is_a?(Symbol)
214
+ record_or_key.to_s
215
+ else
216
+ record_or_key.class.name
217
+ end
218
+ end
219
+
220
+ def id_for(type, key, value, row_index = @row_index, column_index = @column_index)
221
+ [key, type, row_index, column_index].compact.map do |node|
222
+ node.to_s.gsub(/[\s_]/, "-")
223
+ end.join("-")
224
+ end
225
+
226
+ private
227
+ def pixelate(value)
228
+ value.is_a?(::String) ? value : "#{value}px"
229
+ end
230
+ end
231
+ end
232
+ end
@@ -0,0 +1,29 @@
1
+ module Storefront
2
+ module Components
3
+ class Text < Base
4
+ def render(&block)
5
+ template.capture_haml do
6
+ template.haml_tag :article, options[:outer_html] do
7
+ header = template.header_widget(options)
8
+ template.haml_concat header.gsub(/\n$/, "") if header.present?
9
+ content = options[:body] || options[:content]
10
+ content ||= template.capture(&block) if block_given?
11
+ template.haml_tag options[:tag], content, options[:content_html]
12
+ end
13
+ end
14
+ end
15
+
16
+ def extract_options!(*args)
17
+ options = super(*args)
18
+
19
+ options[:content_html] ||= {}
20
+
21
+ merge_class! options[:content_html], config.content_class
22
+
23
+ options[:tag] ||= :p
24
+
25
+ options
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,11 +1,24 @@
1
1
  module Storefront
2
+ class << self
3
+ def configure(&block)
4
+ yield configuration
5
+ end
6
+
7
+ def configuration
8
+ @configuration ||= Storefront::Configuration.new
9
+ end
10
+ end
11
+
2
12
  class Configuration
3
13
  attr_accessor :field,
14
+ :component_suffix,
4
15
  :hint_class,
5
16
  :hint_tag,
6
17
  :label_class,
7
18
  :error_class,
8
19
  :error_tag,
20
+ :auto_id_nav,
21
+ :auto_id_form,
9
22
  :valid_class,
10
23
  :required_class,
11
24
  :required_abbr,
@@ -65,12 +78,15 @@ module Storefront
65
78
  :always_include_error_tag,
66
79
  :cycle_fields,
67
80
  :require_if_validates_presence,
81
+ :default_component_header_level,
68
82
  # localization
69
83
  :localize_with_inheritance,
70
84
  :localize_with_namespace,
71
- :localize_with_nested_model
85
+ :localize_with_nested_model,
86
+ :meta_tags
72
87
 
73
88
  def initialize
89
+ @component_suffix = "widget"
74
90
  @hint_class = "hint"
75
91
  @hint_tag = :figure
76
92
  @label_class = "label"
@@ -99,12 +115,13 @@ module Storefront
99
115
  @escape_html_entities_in_hints_and_labels = false
100
116
  @rename_nested_attributes = true
101
117
  @inline_validations = true
118
+ @auto_id_form = true
102
119
  @fieldset_class = "fieldset"
103
120
  @field_class = "field"
104
121
  @validate_class = "validate"
105
122
  @legend_class = "legend"
106
123
  @form_class = "form"
107
- @id_enabled_on = [] # %w(field label error hint)
124
+ @id_enabled_on = ["input"] # %w(field label error hint)
108
125
  @widgets_path = "shared/widgets"
109
126
  @nav_class = "list-item"
110
127
  @include_aria = true
@@ -118,6 +135,7 @@ module Storefront
118
135
  @list_tag = :ul
119
136
  @page_header_id = "header"
120
137
  @page_title_id = "title"
138
+ @auto_id_nav = false
121
139
  @page_subtitle_id = "subtitle"
122
140
  @widget_class = "widget"
123
141
  @header_class = "header"
@@ -126,7 +144,7 @@ module Storefront
126
144
  @content_class = "content"
127
145
  @default_header_level = 3
128
146
  @term_separator = ":"
129
- @rich_input = true
147
+ @rich_input = false
130
148
  @submit_fieldset_class = "submit-fieldset"
131
149
  @add_label = "+"
132
150
  @remove_label = "-"
@@ -137,6 +155,15 @@ module Storefront
137
155
  @localize_with_namespace = false
138
156
  @localize_with_nested_model = false
139
157
  @localize_with_inheritance = true
158
+ @default_component_header_level = 3
159
+ @meta_tags = [
160
+ :description,
161
+ :keywords,
162
+ :author,
163
+ :copyright,
164
+ :category,
165
+ :robots
166
+ ]
140
167
  end
141
168
 
142
169
  def get(key)
@@ -144,11 +171,32 @@ module Storefront
144
171
  end
145
172
 
146
173
  def current_scope
147
- Thread.current[:storefront_config]
174
+ Thread.current[:storefront]
148
175
  end
149
176
 
150
177
  def current_scope=(value)
151
- Thread.current[:storefront_config] = value
178
+ Thread.current[:storefront] = value
179
+ end
180
+
181
+ def configure_action_view
182
+ base = "#{File.expand_path(File.dirname(__FILE__))}/helpers"
183
+ Dir["#{base}/*"].each do |path|
184
+ next if File.directory?(path)
185
+ constant_name = File.basename(path, File.extname(path)).gsub("/", "::").camelize
186
+ ActionView::Base.send :include, "Storefront::Helpers::#{constant_name}".constantize
187
+ end
188
+ end
189
+
190
+ def configure_action_controller
191
+ base = "#{File.expand_path(File.dirname(__FILE__))}/helpers"
192
+ Dir["#{base}/*"].each do |path|
193
+ next if File.directory?(path) || File.basename(path) =~ /(form|table|dashboard)/
194
+ # need to do these as traditional helper declarations somehow
195
+ constant_name = File.basename(path, File.extname(path)).gsub("/", "::").camelize
196
+ ActionController::Base.send :include, "Storefront::Helpers::#{constant_name}".constantize
197
+ end
198
+
199
+ ActionController::Base.send :before_filter, :configure_storefront
152
200
  end
153
201
  end
154
202
  end
@@ -1,24 +1,42 @@
1
1
  module Storefront
2
- module CacheHelper
3
- def optional_cache(key, &block)
4
- cache(key, &block) unless session[:disable_caching]
5
- end
6
-
7
- def conditional_cache(key, options = {}, &block)
8
- condition = true
9
- condition = false if options.has_key?(:if) && options[:if] != true
10
- if condition
11
- cache(key, &block)
12
- else
13
- haml_concat capture_haml(&block)
2
+ module Helpers
3
+ module CacheHelper
4
+ def cached_partial(path, locals = {})
5
+ if Rails.env.development?
6
+ render(:partial => path, :locals => locals)
7
+ else
8
+ fragment_for path do
9
+ concat render(:partial => path, :locals => locals)
10
+ end
11
+ end
14
12
  end
15
- end
16
-
17
- def set_cache_buster
18
- if request.xhr?
19
- response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate"
20
- response.headers["Pragma"] = "no-cache"
21
- response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT"
13
+
14
+ def cached_content(key, &block)
15
+ if Rails.env.development?
16
+ yield
17
+ else
18
+ fragment_for key do
19
+ concat yield
20
+ end
21
+ end
22
+ end
23
+
24
+ def conditional_cache(key, options = {}, &block)
25
+ condition = true
26
+ condition = false if options.has_key?(:if) && options[:if] != true
27
+ if condition
28
+ cache(key, &block)
29
+ else
30
+ haml_concat capture_haml(&block)
31
+ end
32
+ end
33
+
34
+ def set_cache_buster
35
+ if request.xhr?
36
+ response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate"
37
+ response.headers["Pragma"] = "no-cache"
38
+ response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT"
39
+ end
22
40
  end
23
41
  end
24
42
  end
@@ -1,50 +1,89 @@
1
1
  module Storefront
2
- # Encapsulates common browser hacks
3
- module ComponentHelper
4
- def rich_image_tag(label, path, options = {})
5
- capture_haml do
6
- haml_tag :span
7
- haml_concat image_tag(label, path, options)
2
+ module Helpers
3
+ module ComponentHelper
4
+ def render_flash
5
+ flash_to_render = [:success, :failure, :notice, :error]
6
+ flash.select { |type, _| flash_to_render.include?(type) }.map do |type, content|
7
+ content_tag(:output, content, :class => "flash-#{type}")
8
+ end.join
9
+ end
10
+
11
+ def flash?
12
+ flash.present?
8
13
  end
9
- end
10
-
11
- def rich_button(*args, &block)
12
- attributes = args.extract_options!
13
- label = args.shift
14
- path = args.shift
15
- tag = attributes.delete(:as)
16
-
17
- #locale_options = attributes.delete(:locale_options) || {}
18
- #label = t?(label, locale_options.reverse_merge(:scope => :"buttons"))
19
-
20
- inner_html = attributes.delete(:inner_html) || {}
21
- outer_html = attributes.delete(:outer_html) || {}
22
-
23
- inner_html.merge! clone_attributes(attributes)
24
- outer_html.merge! clone_attributes(attributes.except(:rel, :target))
25
14
 
26
- merge_class! outer_html, "button"
27
-
28
- capture_haml do
29
- haml_tag :div, :<, outer_html do
30
- result = succeed "<span></span>".html_safe do
31
- if block_given?
32
- haml_concat capture_haml(&block).gsub("\n", "").strip
33
- else
34
- if tag
35
- haml_tag tag, :>, :<, inner_html
36
- else
37
- haml_concat link_to(label, path, inner_html)
38
- end
39
- end
15
+ def form(*args, &block)
16
+ Storefront::Components::Form.new(self, *args).render_with_pointer(&block)
17
+ end
18
+ alias_method :form_for, :form
19
+
20
+ def table(*args, &block)
21
+ Storefront::Components::Table.new(self, *args).render_with_pointer(&block)
22
+ end
23
+ alias_method :table_for, :table
24
+
25
+ def sidebar(*args, &block)
26
+ Storefront::Components::Sidebar.new(self, *args).render_with_pointer(&block)
27
+ end
28
+ alias_method :sidebar_for, :sidebar
29
+
30
+ %w(address breadcrumb button definition_list definition_list_item footer header javascript_template list menu nav slider text video).each do |name|
31
+ class_eval %{
32
+ def #{name}_widget(*args, &block)
33
+ Storefront::Components::#{name.camelize}.new(self, *args).render_with_pointer(&block)
40
34
  end
41
- haml_concat result
35
+ alias_method :#{name}, :#{name}_widget
36
+ }
37
+ end
38
+
39
+ alias_method :terms, :definition_list
40
+ alias_method :term, :definition_list_item
41
+
42
+ def cached_widget(*args, &block)
43
+ options = args.extract_options!
44
+
45
+ unless options[:cache_key]
46
+ raise ArgumentError.new("Specify the :cache_key option with a unique id for fragment caching this widget.")
47
+ end
48
+
49
+ cached_content widget_cache_key(args[0], options[:cache_key]) do
50
+ widget(*(args << options), &block)
42
51
  end
43
52
  end
44
- end
45
-
46
- def rich_input(*args, &block)
47
-
53
+
54
+ # Core widget method
55
+ #
56
+ # You can automatically cache this based on some fragment cache key,
57
+ # and it will invalidate the cache automatically
58
+ # If the widget is given a record, it will use that.
59
+ def widget(*args, &block)
60
+ options = args.extract_options!
61
+ path = args.shift
62
+ name = path.to_s.gsub("/", "_")
63
+
64
+ if self.respond_to?("#{name}_widget")
65
+ send("#{name}_widget", name, options, &block)
66
+ else
67
+ raise "Please define a helper method 'def #{name}_widget(*args)'"
68
+ end
69
+ end
70
+ alias_method :component, :widget
71
+ alias_method :cell, :widget
72
+
73
+ def widget_cache_key(name, cache_key)
74
+ key = []
75
+ key << "storefront/widget"
76
+ key << "#{name}" # name of widget
77
+ key << cache_key.to_s
78
+ key.join("/")
79
+ end
80
+
81
+ protected
82
+ def render_widget_partial(name, *args)
83
+ path = name.is_a?(::Symbol) ? ::File.join(storefront_config.widgets_path, name.to_s) : name.to_s
84
+ locals = args.extract_options!.merge(:yielded_content => block_given? ? capture(&block) : nil)
85
+ render :partial => path, :locals => locals
86
+ end
48
87
  end
49
88
  end
50
89
  end