storefront 0.2.0

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 (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,76 @@
1
+ require 'rake'
2
+ require "rake/rdoctask"
3
+ require 'rake/gempackagetask'
4
+
5
+ spec = Gem::Specification.new do |s|
6
+ s.name = "storefront"
7
+ s.authors = ["Lance Pollard"]
8
+ s.version = "0.2.0"
9
+ s.summary = "Semantic HTML5 for Rails"
10
+ s.homepage = "http://github.com/viatropos/storefront"
11
+ s.email = "lancejpollard@gmail.com"
12
+ s.description = "DRY, SEO-friendly Rails Views"
13
+ s.rubyforge_project = "storefront"
14
+ s.platform = Gem::Platform::RUBY
15
+ s.files = %w(Rakefile init.rb) + Dir["{lib,rails,test}/**/*"] - Dir["test/tmp"]
16
+ s.require_path = "lib"
17
+ end
18
+
19
+ Rake::GemPackageTask.new(spec) do |pkg|
20
+ pkg.gem_spec = spec
21
+ end
22
+
23
+ desc 'run unit tests'
24
+ task :test do
25
+ Dir["test/**/*"].each do |file|
26
+ next unless File.basename(file) =~ /test_/
27
+ next unless File.extname(file) == ".rb"
28
+ system "ruby #{file}"
29
+ end
30
+ end
31
+
32
+ desc "Create .gemspec file (useful for github)"
33
+ task :gemspec do
34
+ File.open("#{spec.name}.gemspec", "w") do |f|
35
+ f.puts spec.to_ruby
36
+ end
37
+ end
38
+
39
+ desc "Build the gem into the current directory"
40
+ task :gem => :gemspec do
41
+ `gem build #{spec.name}.gemspec`
42
+ end
43
+
44
+ desc "Publish gem to rubygems"
45
+ task :publish => [:package] do
46
+ %x[gem push #{spec.name}-#{spec.version}.gem]
47
+ end
48
+
49
+ desc "Print a list of the files to be put into the gem"
50
+ task :manifest do
51
+ File.open("Manifest", "w") do |f|
52
+ spec.files.each do |file|
53
+ f.puts file
54
+ end
55
+ end
56
+ end
57
+
58
+ desc "Install the gem locally"
59
+ task :install => [:package] do
60
+ File.mkdir("pkg") unless File.exists?("pkg")
61
+ command = "gem install pkg/#{spec.name}-#{spec.version} --no-ri --no-rdoc"
62
+ command = "sudo #{command}" if ENV["SUDO"] == true
63
+ sh %{#{command}}
64
+ end
65
+
66
+ desc "Generate the rdoc"
67
+ Rake::RDocTask.new do |rdoc|
68
+ files = ["README.md", "lib/**/*.rb"]
69
+ rdoc.rdoc_files.add(files)
70
+ rdoc.main = "README.md"
71
+ rdoc.title = spec.summary
72
+ end
73
+
74
+ task :yank do
75
+ `gem yank #{spec.name} -v #{spec.version}`
76
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ File.dirname(__FILE__) + "/rails/init.rb"
@@ -0,0 +1,21 @@
1
+
2
+ # This takes care of the rest of functionality you need
3
+ # for an SEO and easy to build page.
4
+ # It includes: metadata helpers, grid helpers (e.g. for photo gallerys),
5
+ # navigation helpers (menus and breadcrumbs),
6
+ # better render method so you can pass a block to partials
7
+ # http://github.com/rpheath/navigation_helper.git
8
+ # http://github.com/justinfrench/lovely-layouts.git
9
+ # http://github.com/ianwhite/truncate_html
10
+ # http://github.com/dekart/breadcrumbs.git
11
+ # http://github.com/html/once/blob/master/lib/once.rb
12
+ # http://github.com/fnando/breadcrumbs.git
13
+ # http://github.com/semanticart/smart-meta
14
+ Dir["#{File.expand_path(File.dirname(__FILE__))}/storefront/railtie"]
15
+ Dir["#{File.expand_path(File.dirname(__FILE__))}/storefront/helpers/*"].each do |path|
16
+ require path unless ::File.directory?(path)
17
+ end
18
+ # make this more explicit
19
+ Dir["#{File.expand_path(File.dirname(__FILE__))}/storefront/**/*"].each do |path|
20
+ require path unless ::File.directory?(path) || path =~ /helpers/
21
+ end
@@ -0,0 +1,184 @@
1
+ module Storefront
2
+ class Dashboard
3
+ include Storefront::AttributeHelper
4
+ attr_reader :content, :template, :key, :report, :keys
5
+
6
+ def initialize(template, record_or_key, hash, options = {}, &block)
7
+ @template = template
8
+ @key = record_key(record_or_key)
9
+ @section_index = -1
10
+ @column_index = -1
11
+ @row_index = -1
12
+ @cols = 0
13
+ @section_scope = nil
14
+ @column_scope = nil
15
+ @filter_scope = nil
16
+ @model_names = @key.to_s.camelize.constantize.ancestor_classes.map {|i| i.name.underscore}
17
+ @filter = Array(options.delete(:filter)).compact
18
+ @report = hash
19
+ options[:id] ||= "#{record_or_key.to_s}-section"
20
+ @keys = options.delete(:keys) || {}
21
+
22
+ @content = template.capture_haml do
23
+ template.haml_tag :article, options do
24
+ yield(self)
25
+ end
26
+ end
27
+ end
28
+
29
+ # section :when, :cols => 3
30
+ def section(*args, &block)
31
+ attributes = args.extract_options!
32
+ @section_scope = args.shift
33
+ @section_index += 1
34
+ @row_index = -1
35
+ @column_index = -1
36
+ @cols = attributes.delete(:cols)
37
+ @header = attributes.delete(:title) != false
38
+ attributes[:"data-filters"] = @filter.join(",")
39
+ attributes[:"data-section"] = @section_scope.to_s
40
+ @subtitle = attributes.delete(:subtitle) || report_subtitle
41
+
42
+ merge_class! attributes, index_class(@section_index, @cols), "dashboard-widget", "#{@section_scope}-dashboard-widget"
43
+
44
+ template.capture_haml do
45
+ template.haml_tag :section, attributes do
46
+ if @header
47
+ template.haml_tag :header, :class => "header" do
48
+ template.haml_tag :h3, t!(:"#{@section_scope}.title", locale_keys.merge(:scope => :"reports.titles")), :class => "title"
49
+ if @subtitle.present?
50
+ template.haml_tag :h4, @subtitle, :class => "subtitle"
51
+ end
52
+ end
53
+ end
54
+ yield
55
+ end
56
+ @row_index = 0
57
+ @cols = 0
58
+ end
59
+ end
60
+
61
+ def figure(*args, &block)
62
+ attributes = args.extract_options!
63
+ @figure_scope = args.shift
64
+
65
+ merge_class! attributes, "figure"
66
+ attributes[:id] ||= "#{@figure_scope.to_s}-figure"
67
+
68
+ template.capture_haml do
69
+ template.haml_tag :figure, "", attributes
70
+ end
71
+ end
72
+
73
+ def locale_keys
74
+ hash = {}
75
+ keys.each do |key, value|
76
+ hash[key] = value.is_a?(::Symbol) ? t!(:"#{value}", :scope => :"reports.keys", :model_names => @model_names) : value
77
+ end
78
+ hash.merge(:model_names => @model_names)
79
+ end
80
+
81
+ def column(*args, &block)
82
+ attributes = args.extract_options!
83
+ @column_scope = args.shift
84
+ @column_index += 1
85
+ @row_data = []
86
+ @row_index = -1
87
+ @rows = attributes.delete(:rows)
88
+
89
+ keys = attributes.delete(:keys) || @locale_keys
90
+
91
+ merge_class! attributes, index_class(@column_index, @cols), "#{@column_scope}-column", "col#{@cols}", "column"
92
+ attributes[:"data-column"] = @column_scope.to_s
93
+
94
+ title = attributes.delete(:title) || t!(:"#{@section_scope}.#{@column_scope}.title", locale_keys.merge(:scope => :"reports.titles"))
95
+
96
+ template.capture_haml do
97
+ template.capture_haml(&block)
98
+ @rows = @row_data.length
99
+ template.haml_tag :section, attributes.merge("data-rows" => @rows) do
100
+ template.haml_tag :header, :class => "header" do
101
+ template.haml_tag @header ? :h4 : :h3, title, :class => "title"
102
+ end
103
+
104
+ template.haml_tag :dl, :class => "statistics" do
105
+ @row_data.map { |row_data| _row(*row_data) }
106
+ end
107
+ end
108
+ @row_index = -1
109
+ @rows = 0
110
+ end
111
+ end
112
+
113
+ def row(*args)
114
+ @row_data << args
115
+ end
116
+
117
+ # data-type='distance' (microdata for each statistic)
118
+ def _row(*args, &block)
119
+ attributes = args.extract_options!
120
+ @row_scope = args.shift
121
+ @row_index += 1
122
+ @row_tags = []
123
+
124
+ merge_class! attributes, index_class(@row_index, @rows)
125
+
126
+ template.haml_tag :dt, t!(:"#{@section_scope}.#{@column_scope}.#{@row_scope}", locale_keys.merge(attributes.slice(:past, :present, :future).merge(:scope => :"reports.titles"))), merge_class(attributes, "key")
127
+ template.haml_tag :dd, report_value, merge_class(attributes.merge(:"data-stat" => @row_scope.to_s), "value")
128
+ end
129
+
130
+ private
131
+ def report_value
132
+ keys = @filter + [@section_scope, @column_scope, @row_scope]
133
+ result = report
134
+ begin
135
+
136
+ keys.each { |key| result = result[key] }
137
+ rescue Exception => e
138
+ raise keys.inspect
139
+ end
140
+
141
+ if result.is_a?(::Array)
142
+ result.compact.blank? ? I18n.t("reports.values.missing") : result
143
+ else
144
+ result.blank? ? I18n.t("reports.values.missing") : result
145
+ end
146
+ end
147
+
148
+ def report_subtitle
149
+ keys = @filter + [@section_scope, :subtitle]
150
+ result = report
151
+ keys.each { |key| result = result[key] }
152
+ result
153
+ end
154
+
155
+ def record_key(record_or_key)
156
+ if record_or_key.is_a?(String) || record_or_key.is_a?(Symbol)
157
+ record_or_key.to_s
158
+ else
159
+ record_or_key.class.name
160
+ end
161
+ end
162
+
163
+ def id_for(type, key, value, row_index = @row_index, column_index = @column_index)
164
+ [key, type, row_index, column_index].compact.map do |node|
165
+ node.to_s.gsub(/[\s_]/, "-")
166
+ end.join("-")
167
+ end
168
+
169
+ # reports:
170
+ # titles:
171
+ # what:
172
+ # summary: Quick Summary
173
+ # total: Total Activity
174
+ # deal:
175
+ # what:
176
+ # summary: Quick Summary
177
+ # total: Total Activity
178
+ # rewards_deal:
179
+ # what:
180
+ # summary: Quick Summary
181
+ # total: Total Activity
182
+
183
+ end
184
+ end
@@ -0,0 +1,65 @@
1
+ module Storefront
2
+ class Form
3
+ attr_reader :content, :template, :object, :parent, :tabindex, :access_keys
4
+ include Haml::Helpers
5
+
6
+ # - form_for @user do |form|
7
+ # = form.inputs do
8
+ # = form.input :name, :as => :string
9
+ # = form.input :email, :as => :email
10
+ # = form.partial :name, :values
11
+ # novalidate
12
+ def initialize(template, *args, &block)
13
+ init_haml_helpers
14
+ @template = template
15
+ options = args.extract_options!
16
+ record_or_key = args.shift
17
+ if record_or_key.is_a?(::Symbol) || record_or_key.is_a?(::String)
18
+ record_or_key = record_or_key.to_s.camelize.constantize.new
19
+ end
20
+ @object = record_or_key
21
+ attributes = options.delete(:html) || {}
22
+ attributes[:action] = options.delete(:url)
23
+ attributes[:class] = options.delete(:class) if options.has_key?(:class)
24
+ attributes[:id] = options.delete(:id) if options.has_key?(:id)
25
+ attributes[:multipart] = options.delete(:multipart).to_s if options.has_key?(:multipart)
26
+ method = attributes.delete(:method)
27
+ if method.blank?
28
+ if record_or_key.respond_to?(:new_record?) && !record_or_key.new_record?
29
+ method = :put
30
+ else
31
+ method = :post
32
+ end
33
+ end
34
+
35
+ if method == :get
36
+ attributes[:method] = :get
37
+ else
38
+ attributes[:method] = :post
39
+ end
40
+ #role="form"
41
+ #role="search"
42
+ # other roles = button, checkbox, link, menuitem, menuitemcheckbox, menuitemradio, presentation, progressbar, radio, slider, scrollbar, tab, or treeitem
43
+ # article, document, application, presentation or main
44
+ # http://www.w3.org/TR/wai-aria/roles#widget_roles
45
+
46
+ @content = template.capture_haml do
47
+ template.haml_tag :form, attributes do
48
+ if block_given?
49
+ fields = Storefront::Form::Fields.new(@template,
50
+ :tabindex => 1,
51
+ :access_keys => {},
52
+ :object => @object,
53
+ :keys => [@object.class.name.underscore],
54
+ &block
55
+ )
56
+ end
57
+
58
+ unless method == attributes[:method]
59
+ template.haml_tag :input, :type => :hidden, :name => :_method, :value => method
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,101 @@
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