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