storefront 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/Rakefile +76 -0
  2. data/init.rb +1 -0
  3. data/lib/storefront.rb +21 -0
  4. data/lib/storefront/dashboard.rb +184 -0
  5. data/lib/storefront/form.rb +65 -0
  6. data/lib/storefront/form/elements.rb +101 -0
  7. data/lib/storefront/form/errors.rb +57 -0
  8. data/lib/storefront/form/fields.rb +420 -0
  9. data/lib/storefront/form/hints.rb +18 -0
  10. data/lib/storefront/form/inputs.rb +254 -0
  11. data/lib/storefront/form/labels.rb +81 -0
  12. data/lib/storefront/form/model.rb +84 -0
  13. data/lib/storefront/helpers/attribute_helper.rb +60 -0
  14. data/lib/storefront/helpers/body_helper.rb +18 -0
  15. data/lib/storefront/helpers/browser_helper.rb +54 -0
  16. data/lib/storefront/helpers/cache_helper.rb +25 -0
  17. data/lib/storefront/helpers/collection_helper.rb +14 -0
  18. data/lib/storefront/helpers/component_helper.rb +35 -0
  19. data/lib/storefront/helpers/dashboard_helper.rb +37 -0
  20. data/lib/storefront/helpers/debug_helper.rb +11 -0
  21. data/lib/storefront/helpers/definition_list_helper.rb +29 -0
  22. data/lib/storefront/helpers/error_helper.rb +11 -0
  23. data/lib/storefront/helpers/flash_helper.rb +14 -0
  24. data/lib/storefront/helpers/form_helper.rb +8 -0
  25. data/lib/storefront/helpers/format_helper.rb +59 -0
  26. data/lib/storefront/helpers/head_helper.rb +229 -0
  27. data/lib/storefront/helpers/image_helper.rb +54 -0
  28. data/lib/storefront/helpers/list_helper.rb +47 -0
  29. data/lib/storefront/helpers/locale_helper.rb +175 -0
  30. data/lib/storefront/helpers/open_graph_helper.rb +5 -0
  31. data/lib/storefront/helpers/page_helper.rb +73 -0
  32. data/lib/storefront/helpers/presenter_helper.rb +5 -0
  33. data/lib/storefront/helpers/request_helper.rb +66 -0
  34. data/lib/storefront/helpers/semantic/location_helper.rb +18 -0
  35. data/lib/storefront/helpers/semantic/time_helper.rb +14 -0
  36. data/lib/storefront/helpers/sidebar_helper.rb +27 -0
  37. data/lib/storefront/helpers/system_helper.rb +18 -0
  38. data/lib/storefront/helpers/table_helper.rb +38 -0
  39. data/lib/storefront/helpers/time_helper.rb +20 -0
  40. data/lib/storefront/helpers/url_helper.rb +32 -0
  41. data/lib/storefront/helpers/user_helper.rb +15 -0
  42. data/lib/storefront/helpers/widget_helper.rb +10 -0
  43. data/lib/storefront/helpers/workflow_helper.rb +50 -0
  44. data/lib/storefront/microdata/address.rb +7 -0
  45. data/lib/storefront/microdata/event.rb +13 -0
  46. data/lib/storefront/microdata/geo.rb +7 -0
  47. data/lib/storefront/microdata/organization.rb +7 -0
  48. data/lib/storefront/microdata/person.rb +7 -0
  49. data/lib/storefront/microformat/event.rb +7 -0
  50. data/lib/storefront/microformat/person.rb +7 -0
  51. data/lib/storefront/railtie.rb +28 -0
  52. data/lib/storefront/table.rb +191 -0
  53. data/rails/init.rb +1 -0
  54. data/test/form_helper_test.rb +5 -0
  55. data/test/support/mock_controller.rb +15 -0
  56. data/test/support/mock_response.rb +14 -0
  57. data/test/support/models.rb +0 -0
  58. data/test/test_helper.rb +34 -0
  59. metadata +111 -0
@@ -0,0 +1,54 @@
1
+ module Storefront
2
+ module ImageHelper
3
+ def image_tag(source, options = {})
4
+ options.symbolize_keys!
5
+
6
+ src = options[:src] = path_to_image(source)
7
+
8
+ unless src =~ /^cid:/
9
+ options[:alt] = options.fetch(:alt) { File.basename(src, '.*').gsub(/-\d+$/, "").gsub("-", " ").humanize }
10
+ end
11
+
12
+ if size = options.delete(:size)
13
+ options[:width], options[:height] = size.split("x") if size =~ %{^\d+x\d+$}
14
+ end
15
+
16
+ if mouseover = options.delete(:mouseover)
17
+ options[:onmouseover] = "this.src='#{path_to_image(mouseover)}'"
18
+ options[:onmouseout] = "this.src='#{src}'"
19
+ end
20
+
21
+ tag("img", options)
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
+
48
+ # http://snippets.dzone.com/posts/show/805
49
+ def read_image_size(path)
50
+ width, height = IO.read("#{Rails.root}/public/images/#{path}")[0x10..0x18].unpack('NN')
51
+ {:width => width, :height => height}
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,47 @@
1
+ module Storefront
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)
7
+ if attributes.has_key?(:current)
8
+ current = attributes.delete(:current) == true
9
+ else
10
+ current = on_current_page?(path)
11
+ end
12
+ li_class = "primary-navigation-item"
13
+ if current
14
+ li_class << " active"
15
+ attributes[:class] = [attributes[:class], "active"].compact.uniq.join(" ")
16
+ 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
37
+ else
38
+ haml_concat link_to(text.strip, path, attributes)
39
+ end
40
+ end
41
+ haml_tag :span, separator if separator
42
+ end
43
+ end
44
+ result
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,175 @@
1
+ module Storefront
2
+ module LocaleHelper
3
+ # t!(:"what.summary", :scope => :"reports.titles", :model => deal)
4
+ 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
16
+
17
+ count = options.delete(:count)
18
+ # none, one, many, other
19
+ count_key = count != 1 ? :other : :one
20
+
21
+ if options.has_key?(:present) || options.has_key?(:past) || options.has_key?(:future)
22
+ if options[:future] == true
23
+ tense_key = :future
24
+ else
25
+ tense_key = (options.delete(:present) == true || options.delete(:past) == false) ? :present : :past
26
+ end
27
+ else
28
+ tense_key = nil
29
+ end
30
+
31
+ defaults = []
32
+
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
41
+
42
+ path = '{{key}}'
43
+ path.gsub!('{{key}}', key)
44
+ path.gsub!('..', '.')
45
+ defaults << path
46
+ end
47
+
48
+ defaults.map!(&:to_sym)
49
+ defaults << ''
50
+
51
+ value = I18n.t(defaults.shift, options.merge(:default => defaults))
52
+
53
+ if value.is_a?(::Hash)
54
+ if value.has_key?(count_key)
55
+ value = value[count_key]
56
+ elsif value.has_key?(tense_key)
57
+ value = value[tense_key]
58
+ if value.is_a?(::Hash) && value.has_key?(count_key)
59
+ value = value[count_key]
60
+ end
61
+ elsif value.has_key?(count_key)
62
+ value = value[count_key]
63
+ end
64
+ end
65
+
66
+ if value.is_a?(::Hash)
67
+ if value.has_key?(:one)
68
+ value = value[:one]
69
+ end
70
+ end
71
+
72
+ if value.is_a?(::Hash)
73
+ if value.has_key?(:present)
74
+ value = value[:present]
75
+ elsif value.has_key?(:past)
76
+ value = value[:past]
77
+ elsif value.has_key?(:future)
78
+ value = value[:future]
79
+ end
80
+ end
81
+
82
+ value.blank? && !allow_blank ? key.to_s.split(".").last.titleize : value
83
+ end
84
+
85
+ # interpolate_hash(report, :scope => "reports", :begins_at_level => 3, :keys => {:bookmark => :selected})
86
+ def interpolate_hash(hash, options = {})
87
+ result = {}
88
+ hash.each do |key, value|
89
+ result[key.to_sym] = _interpolate_hash(key, value, {}, options)
90
+ end
91
+ result
92
+ end
93
+
94
+ protected
95
+ # This:
96
+ # {
97
+ # :who => {
98
+ # :title => "Who",
99
+ # :subtitle => "again?",
100
+ # :averages => {
101
+ # :title => "Averages",
102
+ # :first_time => {
103
+ # :title => "First Time",
104
+ # :value => 10
105
+ # }
106
+ # },
107
+ # :best => {
108
+ # :location => {
109
+ # :key => "work",
110
+ # :value => 80.0
111
+ # }
112
+ # }
113
+ # }
114
+ # }
115
+ #
116
+ # becomes...
117
+ #
118
+ # {
119
+ # :who => {
120
+ # :title => "Who",
121
+ # :subtitle => "again?",
122
+ # :averages => {
123
+ # :title => "Averages",
124
+ # :first_time => {
125
+ # :title => "First Time",
126
+ # :value => 10.0
127
+ # }
128
+ # },
129
+ # :best => {
130
+ # :title => "Most Popular"
131
+ # :location => {
132
+ # :title => "Location",
133
+ # :value => "Work (80%)"
134
+ # }
135
+ # }
136
+ # }
137
+ # }
138
+ #
139
+ # who.summary.title.past
140
+ # who.summary.title
141
+ # who.summary.past
142
+ # who.summary
143
+ def _interpolate_hash(key, object, result, options = {})
144
+ return object unless object.is_a?(::Hash)
145
+ key = key.to_s
146
+ title = object[:title] || object[:label]
147
+ subtitle = object[:subtitle]
148
+
149
+ title = t!(:"#{key}", options.merge(:try => :title))
150
+ title = key.to_s.split(".").last.titleize if title.blank? || title.is_a?(::Hash)
151
+ subtitle = t!(:"#{key}.subtitle", options.merge(:allow_blank => true))
152
+
153
+ # everything has to have a title
154
+ result[:title] = title
155
+
156
+ # not everything has to have a subtitle
157
+ result[:subtitle] = subtitle if subtitle.present?
158
+
159
+ # it's a leaf if we're at this point!
160
+ if object.has_key?(:value)
161
+ result[:value] = object[:value]
162
+ else
163
+ object.each do |child_key, child_value|
164
+ if child_value.is_a?(::Hash)
165
+ result[child_key.to_sym] = _interpolate_hash("#{key}.#{child_key}", child_value, {}, options)
166
+ else
167
+ result[child_key.to_sym] = child_value
168
+ end
169
+ end
170
+ end
171
+
172
+ result
173
+ end
174
+ end
175
+ end
@@ -0,0 +1,5 @@
1
+ module Storefront
2
+ module OpenGraphHelper
3
+
4
+ end
5
+ end
@@ -0,0 +1,73 @@
1
+ module Storefront
2
+ module PageHelper
3
+ def page(options = {})
4
+ page_title(options)
5
+ end
6
+
7
+ # = page #=> figures out name from resource (inherited_resources)
8
+ # = page :step => 1 #=> prepends "Step 1: " to the title
9
+ # options => [:browser_title, :title, :clazz]
10
+ def page_title(options = {})
11
+ if options.is_a?(String)
12
+ title = browser_title = options
13
+ title_class = ""
14
+ elsif options.is_a?(Symbol)
15
+ title = browser_title = t("page.titles.#{options}")
16
+ else
17
+ title_class = options.delete(:title_class)
18
+ title = options.delete(:title)
19
+ browser_title = options.delete(:browser_title)
20
+ end
21
+ if title
22
+ capture_page_title((browser_title || title), (title || browser_title), :class => title_class)
23
+ else
24
+ return "" unless (defined?(:resource) || defined?(:collection))
25
+ cont = params[:controller].split("/").last
26
+ key = "#{cont}.#{params[:action]}"
27
+ default_key = "resource.#{params[:action]}"
28
+ parent_exists = parent rescue nil
29
+ parent_exists = !parent_exists.nil?
30
+ options[:name] = resource.name if resource rescue nil
31
+ options[:name] ||= parent.name if parent_exists
32
+ if parent_exists
33
+ key << ".nested"
34
+ default_key << ".nested"
35
+ end
36
+ if options[:clazz].blank?
37
+ options[:clazz] = cont.singularize.titleize
38
+ options[:clazz] = options[:clazz].pluralize if params[:action] == "index"
39
+ end
40
+ browser_title_options = options.merge(:default => t("#{default_key}.browser_title"))
41
+ page_title_options = options.merge(:default => t("#{default_key}.page_title"))
42
+ capture_page_title(
43
+ t("#{key}.browser_title", browser_title_options).strip.squeeze(" "),
44
+ t(key, page_title_options).strip.squeeze(" "),
45
+ :class => title_class
46
+ )
47
+ end
48
+ end
49
+
50
+ def resource_title(options = {})
51
+ return options[:default] if options[:default]
52
+ return "" unless (defined?(:resource) || defined?(:collection))
53
+ options[:action] ||= params[:action]
54
+ cont = params[:controller].split("/").last
55
+ key = "#{cont}.#{options[:action]}"
56
+ options[:name] = resource.name if resource rescue nil
57
+ options[:clazz] = cont.singularize.camelize
58
+ options[:clazz] = options[:clazz].pluralize if options[:action] == "index"
59
+ page_title_options = options.merge(:default => t("resource.#{options[:action]}.page_title"))
60
+ t(key, page_title_options).strip.squeeze(" ")
61
+ end
62
+
63
+ def capture_page_title(browser_title, the_page_title, options = {})
64
+ result = capture_haml do
65
+ title browser_title
66
+ haml_tag :header, options.reject{|k,v| v.blank?}.merge(:id => "page-title") do
67
+ haml_tag :h1, the_page_title
68
+ end
69
+ end
70
+ result
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,5 @@
1
+ module Storefront
2
+ module PresenterHelper
3
+
4
+ end
5
+ end
@@ -0,0 +1,66 @@
1
+ module Storefront
2
+ module RequestHelper
3
+ def requesting?(expression)
4
+ case expression
5
+ when ::Symbol
6
+ (request.path =~ /#{expression}\/?$/).present?
7
+ else
8
+ (request.path =~ expression).present?
9
+ end
10
+ end
11
+
12
+ def self.clear_session
13
+ before_filter { |controller| controller.session.clear }
14
+ end
15
+
16
+ # ensure_domain :production => "site.com", :staging => "site-development.heroku.com"
17
+ def self.ensure_domain(options = {})
18
+ @ensure_domain_options = options.symbolize_keys
19
+ true
20
+ end
21
+
22
+ def ensure_domain
23
+ domain = self.class.ensure_domain_options[Rails.env.to_sym]
24
+ return true if domain.blank?
25
+ redirect_to(request.protocol + domain + request.request_uri) if request.env['HTTP_HOST'] != domain
26
+ true
27
+ end
28
+
29
+ def self.ensure_domain_options
30
+ @ensure_domain_options
31
+ end
32
+
33
+ def on_current_page?(options)
34
+ url_string = CGI.unescapeHTML(url_for(options))
35
+ request = controller.request
36
+ if url_string.index("?")
37
+ fullpath = request.fullpath
38
+ else
39
+ fullpath = request.fullpath.split('?').first
40
+ end
41
+ if url_string =~ /^\w+:\/\//
42
+ url_string == "#{request.protocol}#{request.host_with_port}#{fullpath}"
43
+ else
44
+ url_string == fullpath.gsub(/&sort_by=.*/, "").gsub(/&vendor_name=.*/, "")
45
+ end
46
+ end
47
+
48
+ def with_subdomain(subdomain)
49
+ subdomain = (subdomain || "")
50
+ subdomain += "." unless subdomain.empty?
51
+ [subdomain, request.domain(2), request.port_string].join
52
+ end
53
+
54
+ def url_for(options = {})
55
+ if options.kind_of?(Hash) && options.has_key?(:subdomain)
56
+ options[:host] = with_subdomain(options.delete(:subdomain))
57
+ end
58
+
59
+ if options.is_a?(Symbol) && options == :up
60
+ request.path.split("/")[0..-2].join("/")
61
+ else
62
+ super(options)
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,18 @@
1
+ module Storefront
2
+ module Semantic
3
+ module LocationHelper
4
+ def semantic_geo_tag(lat, lng, options = {})
5
+ capture_haml do
6
+ haml_tag :span, :itemprop => "geo", :itemtype => "http://data-vocabulary.org/Geo" do
7
+ haml_tag :span, :itemprop => "latitude" do
8
+ haml_tag :span, lat, :class => "value-title"
9
+ end
10
+ haml_tag :span, :itemprop => "longitude" do
11
+ haml_tag :span, lng, :class => "value-title"
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end