fluffery 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .DS_Store
6
+ .rvmrc
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in fluffery.gemspec
4
+ gemspec
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "fluffery/version"
4
+
5
+ Gem::Specification.new do |s|
6
+
7
+ s.name = "fluffery"
8
+ s.version = Fluffery::VERSION
9
+ s.platform = Gem::Platform::RUBY
10
+ s.authors = ["kurb media"]
11
+ s.date = %q{2011-03-10}
12
+ s.email = %q{info@kurbmedia.com}
13
+ s.homepage = %q{http://github.com/kurbmedia/fluffery}
14
+ s.licenses = ["MIT"]
15
+ s.summary = %q{ummm.. Adds misc fluffery to yer apps.}
16
+ s.description = %q{Random fluffage for Rails applications.}
17
+
18
+ s.rubyforge_project = "fluffery"
19
+
20
+ s.files = `git ls-files`.split("\n")
21
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
22
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
23
+ s.require_paths = ["lib"]
24
+
25
+ s.add_development_dependency(%q<rails>, ["~> 3.0.0"])
26
+ s.add_development_dependency(%q<actionpack>, ["~> 3.0.0"])
27
+ s.add_development_dependency(%q<rspec>, ["~> 2.3"])
28
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
29
+
30
+
31
+ end
@@ -0,0 +1,21 @@
1
+ module Fluffery
2
+
3
+ autoload :Config, 'fluffery/config'
4
+
5
+ module Forms
6
+ autoload :Builder, 'fluffery/forms/builder'
7
+ autoload :Utilities, 'fluffery/forms/utilities'
8
+ end
9
+
10
+ module Helpers
11
+ autoload :Navigation, 'fluffery/helpers/navigation'
12
+ autoload :PageVariables, 'fluffery/helpers/page_variables'
13
+ autoload :Elements, 'fluffery/helpers/elements'
14
+ autoload :Includes, 'fluffery/helpers/includes'
15
+ end
16
+
17
+ module Utils
18
+ autoload :Internal, 'fluffery/utils/internal'
19
+ end
20
+
21
+ end
@@ -0,0 +1,29 @@
1
+ module Fluffery
2
+
3
+ class Config
4
+
5
+ def self.forms
6
+ @forms ||= {
7
+ :error_class => 'field_with_errors',
8
+ :message_error_class => 'errors_for_field',
9
+ :error_template => %{
10
+ <span class="<%= error_class %>">
11
+ <%= html_tag %>
12
+ <span class="<%= message_error_class %>"><%= [messages].flatten.join(",") %></span>
13
+ </span>
14
+ }
15
+ }
16
+ end
17
+
18
+ def self.dom
19
+ @dom ||= {}
20
+ end
21
+
22
+ def initialize
23
+ yield Fluffery::Config if block_given?
24
+ end
25
+
26
+
27
+ end
28
+
29
+ end
@@ -0,0 +1,142 @@
1
+ module Fluffery
2
+ module Forms
3
+
4
+ class Builder < ActionView::Helpers::FormBuilder
5
+
6
+ include Fluffery::Forms::Utilities
7
+
8
+ # Access the template object
9
+ attr_accessor :template
10
+
11
+ # Sets up options custom to our form builder.
12
+ # It also overrides the default error proc so we can use something more custom.
13
+ #
14
+ def initialize(object_name, object, template, options, proc)
15
+ without_error_proc do
16
+ super(object_name, object, template, options, proc)
17
+ end
18
+ end
19
+
20
+ # Creates a html button tag for use in forms instead of the default input submit.
21
+ # Uses a span to wrap the content so it can be styled with css.
22
+ #
23
+ def button(value = nil, options = {})
24
+ value, options = nil, value if value.is_a?(Hash)
25
+ value ||= submit_default_value
26
+
27
+ options = confirm_or_disable(options)
28
+ options = Fluffery::Utils::Internal.merge_html_classes(options, 'button')
29
+
30
+ content_tag(:button, options.reverse_merge!({ "type" => "submit", "name" => "commit" })) do
31
+ content_tag(:span, value.to_s)
32
+ end
33
+
34
+ end
35
+
36
+ # Custom label tag including an asterisk if the field is required.
37
+ #
38
+ def label(method, text = nil, options = {}, &block)
39
+
40
+ options, text = text, nil if text.is_a?(Hash)
41
+ text ||= method.to_s.humanize
42
+ options.stringify_keys!
43
+
44
+ options.reverse_merge!('transform' => :titleize) unless option_exists?(options['transform'])
45
+ text.send(options['transform'].to_sym)
46
+ options.delete('transform')
47
+
48
+ # Check to see if :required is set on a label, or if the attribute/method has a validator that require it exists.
49
+ # If so, add a * to the label.
50
+ text = "#{text} <abbr title='Required'>*</abbr>".html_safe if validator.attribute_required?(method, options)
51
+ super(method, text, options, &block)
52
+
53
+ end
54
+
55
+ def email_field(method, options = {})
56
+ render_with_fluff(method, options) do
57
+ super(method, options.merge!('type' => 'email'))
58
+ end
59
+ end
60
+
61
+ # Renders the default date_select but with an error wrapping if
62
+ # the method in question has errors
63
+ #
64
+ def date_select(method, options = {}, html_options = {})
65
+ render_with_fluff(method, options, html_options) do
66
+ super(method, options, html_options)
67
+ end
68
+ end
69
+
70
+ # HTML5 Number field, again, falls back to text in unsupportive browsers.
71
+ #
72
+ def number_field(method, range, options = {})
73
+ options, range = range, nil if range.is_a?(Hash)
74
+ options.stringify_keys!
75
+ unless range.nil?
76
+ range = (range.is_a?(Range)) ? range.to_a : range
77
+ options.merge!('min' => range.first, 'max' => range.last)
78
+ end
79
+
80
+ render_with_fluff(method, options) do
81
+ super(method, options.merge!('type' => 'number'))
82
+ end
83
+
84
+ end
85
+
86
+ def password_field(method, options = {})
87
+ render_with_fluff(method, options) do
88
+ super(method, options)
89
+ end
90
+ end
91
+
92
+ def select(method, choices, options = {}, html_options = {})
93
+ render_with_fluff(method, options, html_options) do
94
+ @template.select(@object_name, method, choices, options, html_options)
95
+ end
96
+ end
97
+
98
+ def state_select(method, options = {}, html_options = {})
99
+
100
+ state_options = [['Please Select',nil]]
101
+ state_options << ['International', (int || 'International')] if int = options.delete(:international)
102
+ [
103
+ ['Alabama', "AL"],['Alaska', "AK"],['Arizona', "AZ"],['Arkansas', "AR"],['California', "CA"],['Colorado', "CO"],
104
+ ['Connecticut', "CT"],['District of Columbia', "DC"],['Delaware', "DE"],['Florida', "FL"],['Georgia', "GA"],
105
+ ['Hawaii', "HI"],['Idaho', "ID"],['Illinois', "IL"],['Indiana', "IN"],['Iowa', "IA"],['Kansas', "KS"],['Kentucky', "KY"],
106
+ ['Louisiana', "LA"],['Maine', "ME"],['Maryland', "MD"],['Massachusetts', "MA"],['Michigan', "MI"],['Minnesota', "MN"],
107
+ ['Mississippi', "MS"],['Missouri', "MO"],['Montana', "MT"],['Nebraska', "NE"],['Nevada', "NV"],['New Hampshire', "NH"],
108
+ ['New Jersey', "NJ"],['New Mexico', "NM"],['New York', "NY"],['North Carolina', "NC"],['North Dakota', "ND"],
109
+ ['Ohio', "OH"],['Oklahoma', "OK"],['Oregon', "OR"],['Pennsylvania', "PA"],['Rhode Island', "RI"],['South Carolina', "SC"],
110
+ ['South Dakota', "SD"],['Tennessee', "TN"],['Texas', "TX"],['Utah', "UT"],['Vermont', "VT"],['Virginia', "VA"],['Washington', "WA"],
111
+ ['West Virginia', "WV"],['Wisconsin', "WI"],['Wyoming', "WY"]
112
+ ].each do |state|
113
+ should_abbr = options.delete(:abbreviate)
114
+ state_options << (should_abbr ? state : [state.first, state.first])
115
+ end
116
+
117
+ select(method, @template.options_for_select(state_options, @object.try(:state)), options, html_options)
118
+
119
+ end
120
+
121
+ def text_field(method, options = {})
122
+ render_with_fluff(method, options) do
123
+ super(method, options)
124
+ end
125
+ end
126
+
127
+ def text_area(method, options = {})
128
+ render_with_fluff(method, options) do
129
+ super(method, options)
130
+ end
131
+ end
132
+
133
+ def url_field(method, options = {})
134
+ render_with_fluff(method, options) do
135
+ super(method, options.merge!('type' => 'url'))
136
+ end
137
+ end
138
+
139
+ end
140
+
141
+ end
142
+ end
@@ -0,0 +1,89 @@
1
+ require 'erb'
2
+ require 'fluffery/forms/validation/base'
3
+
4
+ module Fluffery
5
+ module Forms
6
+
7
+ module Utilities
8
+
9
+ # Simply shortening calls to content_tag since it is a method of @template
10
+ #
11
+ def content_tag(tag, content, options = {}, escape = true, &block)
12
+ @template.content_tag(tag, content, options, escape, &block)
13
+ end
14
+
15
+ # Adds data-confirm, or data-disable-with if set.
16
+ #
17
+ def confirm_or_disable(options)
18
+ options.stringify_keys!
19
+ options.merge!("data-disable-with" => options["disable_with"]) if options.delete("disable_with")
20
+ options.merge!("data-confirm" => options["confirm"]) if options.delete("confirm")
21
+ options
22
+ end
23
+
24
+ # Allows us to call something like f.error_console to log form errors
25
+ # to a javascript console such as firebug
26
+ #
27
+ def error_console
28
+ "<script type=\"text/javascript\" charset=\"utf-8\">
29
+ //<![CDATA[
30
+ try{ console.log(\"#{@template.escape_javascript(@object.errors.inspect)}\")}catch(e){}
31
+ //]]>
32
+ </script>".html_safe
33
+ end
34
+
35
+ # Quick helper to see if an option is nil, blank, or false
36
+ #
37
+ def option_exists?(opt)
38
+ !(opt.nil? || opt.to_s.blank? || opt.to_s === "false")
39
+ end
40
+
41
+ # Generate additional options on our fields.
42
+ # 1. If a field has errors, wrap it with the defined error template.
43
+ # 2. Also add our error class to the field itself.
44
+ #
45
+ def render_with_fluff(method, options, html_options = nil, &block)
46
+ _options = html_options.nil? ? options : html_options
47
+ _options = validator.add_html_attributes(method, _options)
48
+ # If no errors, simply return.
49
+ unless validator.errors_for?(method)
50
+ return block.call
51
+ end
52
+
53
+ configs = Fluffery::Config.forms
54
+ template = configs[:error_template]
55
+ error_class = configs[:error_class]
56
+ _options = Fluffery::Utils::Internal.merge_html_classes(_options, error_class)
57
+ options = _options if html_options.nil?
58
+
59
+ # Capture the original html tag with any updated options.
60
+ html_tag = block.call
61
+ return html_tag if template.nil? or template.blank?
62
+
63
+ renderer = ERB.new(template)
64
+ messages = @object.errors[method.to_sym]
65
+ message_error_class = configs[:message_error_class]
66
+ renderer.result(
67
+ OpenStruct.new(configs.merge!(:messages => messages)).send(:binding)
68
+ ).to_s.html_safe
69
+
70
+ end
71
+
72
+ def validator
73
+ @validator ||= Fluffery::Forms::Validation::Base.new(@object)
74
+ end
75
+
76
+ # Override the default error proc for our forms, making sure to
77
+ # set it back when we are finished to avoid compatibility issues.
78
+ #
79
+ def without_error_proc
80
+ default_proc = ActionView::Base.field_error_proc
81
+ ActionView::Base.field_error_proc, proc = lambda{ |html_tag, instance| html_tag }
82
+ yield
83
+ ActionView::Base.field_error_proc = default_proc
84
+ end
85
+
86
+ end
87
+
88
+ end
89
+ end
@@ -0,0 +1,178 @@
1
+ module Fluffery
2
+ module Forms
3
+ module Validation
4
+
5
+ class Base
6
+
7
+ require 'fluffery/forms/validation/validators'
8
+
9
+ attr_accessor :object
10
+
11
+ def initialize(form_object)
12
+ @object = form_object
13
+ end
14
+
15
+ def add_html_attributes(attribute, options)
16
+ options = Presence.create(attribute, options) if attribute_required?(attribute)
17
+ matcher = attribute_format_validator(attribute)
18
+ options = Pattern.create(attribute, options, matcher) unless matcher.nil?
19
+ options.reverse_merge!(default_messages_for(attribute))
20
+ options
21
+ end
22
+
23
+ # Checks to see if the particular attribute is required, used primarily on labels.
24
+ #
25
+ def attribute_required?(attribute, options = nil)
26
+ options.stringify_keys! if options.is_a?(Hash)
27
+ unless options.nil?
28
+ return true if options.has_key?('required') and options['required'] === true
29
+ end
30
+ valid_items = validators_for(attribute).find do |validator|
31
+ ([:presence, :inclusion].include?(validator.kind)) &&
32
+ (validator.options.present? ? options_require_validation?(validator.options) : true)
33
+ end
34
+ !valid_items.nil?
35
+ end
36
+
37
+ # Checks to see if a particular attribute contains a Regex format validator
38
+ #
39
+ def attribute_format_validator(attribute)
40
+ format_validator = validators_for(attribute).detect{ |v| v.kind == :format }
41
+ return nil unless !format_validator.nil?
42
+ return nil unless format_validator.options.has_key?(:with) && format_validator.options[:with].is_a?(Regexp)
43
+ matcher = format_validator.options[:with]
44
+ end
45
+
46
+ # Looks up the default error message so it may be used in our data-message attribute
47
+ #
48
+ def default_messages_for(attribute)
49
+ validators = validators_for(attribute)
50
+ return {} if validators.empty?
51
+ message_data = validators.inject({}) do |hash, validator|
52
+ message = validator.options.has_key?(:message) ? validator.options[:message] : MessageBuilder.message_for(@object, attribute, validator)
53
+ hash.merge!(validator.kind.to_s => message)
54
+ end
55
+ attr_hash = {'data-validation-messages' => CGI::escape(message_data.to_json) }
56
+
57
+ # Create a list of data-validates-* attrs on the field so we can catch them with javascript
58
+ # Skip presence and format because they have their own valid HTML5 attrs.
59
+ #
60
+ validators.reject{ |v| v.kind.to_s.match(/(presence|format)/i) }.each{ |v| attr_hash.merge!("data-validates-#{v.kind.to_s}" => 'true') }
61
+
62
+ attr_hash
63
+
64
+ end
65
+
66
+ # Checks to see if the particular attribute has errors
67
+ #
68
+ def errors_for?(method)
69
+ !(@object.nil? || @object.errors.empty? || !@object.errors.key?(method.to_sym) || [@object.errors[method.to_sym]].flatten.empty?)
70
+ end
71
+
72
+ # Checks to see if the validation is required
73
+ # Courtesy Justin French and Formtastic
74
+ #
75
+ def options_require_validation?(options)
76
+ allow_blank = options[:allow_blank]
77
+ return !allow_blank unless allow_blank.nil?
78
+ if_condition = !options[:if].nil?
79
+ condition = if_condition ? options[:if] : options[:unless]
80
+
81
+ condition = if condition.respond_to?(:call)
82
+ condition.call(@object)
83
+ elsif condition.is_a?(::Symbol) && @object.respond_to?(condition)
84
+ @object.send(condition)
85
+ else
86
+ condition
87
+ end
88
+
89
+ if_condition ? !!condition : !condition
90
+ end
91
+
92
+ # Finds all existing validations for the current object and method
93
+ #
94
+ def validators_for(attribute)
95
+ return [] unless !@object.nil? and @object.class.respond_to?(:validators_on)
96
+ attribute = attribute.to_s.sub(/_id$/, '').to_sym
97
+ validators = @object.class.validators_on(attribute).uniq
98
+ end
99
+
100
+ def validators_for?(method)
101
+ !validators_for(method).empty?
102
+ end
103
+
104
+ end
105
+
106
+ class MessageBuilder
107
+ def self.message_for(object, attribute, validator)
108
+ message = self.get_validation_message(validator)
109
+ message = self.defaults(validator.kind) unless message.match(/translation missing/i).nil?
110
+ message
111
+ end
112
+
113
+ private
114
+
115
+ def self.defaults(validator)
116
+ {
117
+ :presence => "required",
118
+ :format => 'invalid',
119
+ :length => "wrong length",
120
+ :numericality => "not a number",
121
+ :uniqueness => 'taken',
122
+ :confirmation => 'required',
123
+ :acceptance => 'required',
124
+ :inclusion => 'invalid',
125
+ :exclusion => 'invalid'
126
+ }[validator]
127
+ end
128
+
129
+ def self.get_validation_message(validator)
130
+ key = {
131
+ :presence => "blank",
132
+ :format => 'invalid',
133
+ :length => self.length_options(validator.options),
134
+ :numericality => self.numericality_options(validator.options),
135
+ :uniqueness => 'taken',
136
+ :confirmation => 'confirmation',
137
+ :acceptance => 'accepted',
138
+ :inclusion => 'inclusion',
139
+ :exclusion => 'exclusion'
140
+ }[validator.kind]
141
+ key.is_a?(Array) ? I18n.translate("errors.messages.#{key.first}").sub("%{#{:count}}", key.last.to_s) : I18n.translate("errors.messages.#{key}")
142
+ end
143
+
144
+ def self.length_options(opts)
145
+ if count = opts[:is]
146
+ ["wrong_length", count]
147
+ elsif count = opts[:minimum]
148
+ ["too_short", count]
149
+ elsif count = opts[:maximum]
150
+ ["too_long", count]
151
+ end
152
+ end
153
+
154
+ def self.numericality_options(opts)
155
+ if opts[:only_integer]
156
+ 'not_a_number'
157
+ elsif count = opts[:greater_than]
158
+ ['greater_than', count]
159
+ elsif count = opts[:greater_than_or_equal_to]
160
+ ['greater_than_or_equal_to', count]
161
+ elsif count = opts[:less_than]
162
+ ['less_than', count]
163
+ elsif count = opts[:less_than_or_equal_to]
164
+ ['less_than_or_equal_to', count]
165
+ elsif opts[:odd]
166
+ 'odd'
167
+ elsif opts[:even]
168
+ 'even'
169
+ else
170
+ 'not_a_number'
171
+ end
172
+ end
173
+
174
+ end
175
+
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,21 @@
1
+ module Fluffery
2
+ module Forms
3
+ module Validation
4
+
5
+ class Presence < Fluffery::Forms::Validation::Base
6
+ def self.create(attribute ,options)
7
+ options.merge!('required' => 'required') unless options.has_key?('required') && options['required'] === false
8
+ options
9
+ end
10
+ end
11
+
12
+ class Pattern < Fluffery::Forms::Validation::Base
13
+ def self.create(attribute, options, matcher)
14
+ options.reverse_merge!('pattern' => matcher.inspect) unless matcher.nil?
15
+ options
16
+ end
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,57 @@
1
+ module Fluffery
2
+ module Helpers
3
+
4
+ module Elements
5
+
6
+ # Simply overriding the default form_for to add additional html options/attributes.
7
+ def form_for(record_or_name_or_array, *args, &block)
8
+
9
+ options = args.last.is_a?(Hash) ? args.pop : {}
10
+ options[:html] ||= {}
11
+
12
+ # Add support for the 'ajax' uploader.
13
+ options[:html].merge!('data-remote-uploadable' => true) if options.delete(:remote_upload)
14
+ # Add support for javascript validation.
15
+ options[:html].merge!('data-js-validatable' => true) if options.delete(:validate)
16
+
17
+ args = (args << options)
18
+ super(record_or_name_or_array, *args, &block)
19
+
20
+ end
21
+
22
+ # Creates a common format for CSS buttons
23
+ # Example: button_link('Blog', '/blog') yields <a href="/blog" class="button"><span>Blog</span></a>
24
+
25
+ def button_link(txt, path, attrs = {})
26
+ inline_classes = attrs.has_key?(:class) ? "#{attrs[:class]} " : ""
27
+ link_to "<span>#{txt}</span>".html_safe, path, attrs.merge({ :class => "#{inline_classes}button" })
28
+ end
29
+
30
+ # Outputs all flash messages. This allows you to call <%= flash_messages %> once in your
31
+ # application's layout file. The output is a div with the class flash_message, and the type used. It also renders
32
+ # a "close" tag, which can be overridden or set to "". By default this is a span containing 'X'
33
+ #
34
+ # <div class="flash_message error">
35
+ # Your error message from flash[:error]
36
+ # <span>X</span>
37
+ # </div>
38
+ #
39
+ #
40
+ def flash_messages(attrs = {})
41
+ wrapper = attrs.delete(:wrapper) || :div
42
+ closer = attrs.delete(:close) || "<span>X</span>"
43
+ classes = (attrs.key?(:class)) ? attrs[:class].split(' ') : []
44
+ classes << "flash_message"
45
+ content = ""
46
+ flash.each_key do |k|
47
+ classes << "flash_message_#{k.to_s.underscore}"
48
+ msg_attrs = attrs.merge(:class => [k.to_s, classes].flatten.join(' '))
49
+ content.concat content_tag(wrapper, "#{flash[k]} #{closer}".html_safe, msg_attrs).html_safe
50
+ end
51
+ content.html_safe
52
+ end
53
+
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,20 @@
1
+ module Fluffery
2
+ module Helpers
3
+
4
+ module Includes
5
+
6
+ # Wraps output in IE conditional tags, the condition should be specified in the same
7
+ # format as it would in the conditional itself. For example:
8
+ # ie_conditional('lte IE 8') yields [if lte IE 8]
9
+ #
10
+ def ie_conditional(condition, &block)
11
+ output = ["<!--[if #{condition}]>"]
12
+ output << capture(&block)
13
+ output << "<![endif]-->"
14
+ output.join("\n").html_safe
15
+ end
16
+
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,47 @@
1
+ module Fluffery
2
+ module Helpers
3
+ module Navigation
4
+
5
+ # Creates a navigation link (by default a list item) that has the class 'on' if we are on that particular page or a
6
+ # page beneath it.
7
+ # Example: nav_link_to('Blog', 'blog') will have the class of 'on' should we be on /blog or /blog/some_path
8
+
9
+ def nav_link_to(txt, path, attrs = {}, wrapper = :li)
10
+
11
+ path_validation = false
12
+ path_validation = attrs.has_key?(:proc) ? attrs[:proc].call(path) : (request.path == path || request.path.match(/#{path}\/.*/i))
13
+ path_validation = request.path.match(/#{attrs[:matcher].gsub("_path", path)}/i) if attrs.has_key?(:matcher)
14
+ attrs.delete(:proc)
15
+ attrs.delete(:matcher)
16
+
17
+ wrapper_attrs = attrs.delete(:wrapper)
18
+ attrs, wrapper_attrs = merge_html_classes(attrs, path_validation), merge_html_classes(wrapper_attrs, path_validation)
19
+
20
+ return_val = link_to_unless(path_validation, txt, path, attrs) do
21
+ link_to(txt, path, attrs)
22
+ end
23
+
24
+ (wrapper.eql? false) ? return_val : content_tag(wrapper, return_val, wrapper_attrs)
25
+
26
+ end
27
+
28
+ # Creates a nested navigation block, generally used for lists/nested lists.
29
+ def navigation(txt, path, attrs = {}, options = {}, &block)
30
+ options.reverse_merge!(:container => :ol, :wrapper => :li)
31
+ navigation_content = content_tag(options[:container], capture(&block))
32
+ wrapper_attrs = attrs.delete(:wrapper)
33
+ parent_link = nav_link_to(txt, path, attrs, false)
34
+ content_tag(options[:wrapper], "#{parent_link}\n#{navigation_content}".html_safe, (wrapper_attrs || {}))
35
+ end
36
+
37
+ private
38
+
39
+ def merge_html_classes(attrs, add_on = false)
40
+ attrs ||= {}
41
+ Fluffery::Utils::Internal.merge_html_classes(attrs, 'on') if add_on
42
+ attrs
43
+ end
44
+
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,51 @@
1
+ module Fluffery
2
+ module Helpers
3
+
4
+ module PageVariables
5
+
6
+ def page_default(param, data = nil)
7
+ create_variable("helpful_#{param}", data) unless data.nil? or data.blank?
8
+ end
9
+
10
+ def page_id(content = nil)
11
+ create_internal_variable(:helpful_page_id, content) and return unless content.nil?
12
+ return retrieve_variable(:helpful_page_id) if content_for?(:helpful_page_id)
13
+ cname = controller.class.to_s.gsub(/controller$/i,'').underscore.split("/").join('_')
14
+ aname = controller.action_name
15
+ "#{cname}_#{aname}"
16
+ end
17
+
18
+ def page_title(content = nil)
19
+ (content.nil?) ? retrieve_variable(:helpful_page_title) : create_internal_variable(:helpful_page_title, content)
20
+ end
21
+
22
+ def keywords(content = nil)
23
+ (content.nil?) ? retrieve_variable(:helpful_keywords) : create_internal_variable(:helpful_keywords, content)
24
+ end
25
+
26
+ def description(content = nil)
27
+ (content.nil?) ? retrieve_variable(:helpful_description) : create_internal_variable(:helpful_description, content)
28
+ end
29
+
30
+ def create_variable(var, content, new_method = true)
31
+ content_for(var.to_sym) do
32
+ content
33
+ end
34
+ self.class_eval{ define_method("#{var.to_s}"){ retrieve_variable(var.to_sym) } } if new_method
35
+ return ""
36
+ end
37
+
38
+ private
39
+
40
+ def create_internal_variable(var, content)
41
+ create_variable(var, content, false)
42
+ end
43
+
44
+ def retrieve_variable(var)
45
+ (content_for?(var.to_sym) ? content_for(var.to_sym) : "")
46
+ end
47
+
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,14 @@
1
+ module Fluffery
2
+ class Railtie < Rails::Railtie
3
+
4
+ initializer :after_initialize do
5
+ # Configure ActionView with any addons.
6
+ ActionView::Base.send :include, Fluffery::Helpers::Navigation
7
+ ActionView::Base.send :include, Fluffery::Helpers::PageVariables
8
+ ActionView::Base.send :include, Fluffery::Helpers::Elements
9
+ ActionView::Base.send :include, Fluffery::Helpers::Includes
10
+ ActionView::Base.send :default_form_builder=, Fluffery::Forms::Builder
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ module Fluffery
2
+ module Utils
3
+
4
+ class Configurator
5
+
6
+ end
7
+
8
+ end
9
+ end
@@ -0,0 +1,19 @@
1
+ module Fluffery
2
+ module Utils
3
+
4
+ class Internal
5
+
6
+ # Merge any new classes with existing html classes
7
+ #
8
+ def self.merge_html_classes(options, classes)
9
+ classes = [classes].flatten
10
+ options.stringify_keys!
11
+ return options.merge!('class' => classes.join(' ')) unless options.has_key?('class')
12
+ old_classes = options['class'].split(' ')
13
+ options.merge!('class' => [classes, old_classes].flatten.join(' '))
14
+ end
15
+
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,3 @@
1
+ module Fluffery
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluffery
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - kurb media
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-03-10 00:00:00 -05:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: rails
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ~>
23
+ - !ruby/object:Gem::Version
24
+ version: 3.0.0
25
+ type: :development
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: actionpack
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ~>
34
+ - !ruby/object:Gem::Version
35
+ version: 3.0.0
36
+ type: :development
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: rspec
40
+ prerelease: false
41
+ requirement: &id003 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ version: "2.3"
47
+ type: :development
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
50
+ name: bundler
51
+ prerelease: false
52
+ requirement: &id004 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ~>
56
+ - !ruby/object:Gem::Version
57
+ version: 1.0.0
58
+ type: :development
59
+ version_requirements: *id004
60
+ description: Random fluffage for Rails applications.
61
+ email: info@kurbmedia.com
62
+ executables: []
63
+
64
+ extensions: []
65
+
66
+ extra_rdoc_files: []
67
+
68
+ files:
69
+ - .gitignore
70
+ - Gemfile
71
+ - Rakefile
72
+ - fluffery.gemspec
73
+ - lib/fluffery.rb
74
+ - lib/fluffery/config.rb
75
+ - lib/fluffery/forms/builder.rb
76
+ - lib/fluffery/forms/utilities.rb
77
+ - lib/fluffery/forms/validation/base.rb
78
+ - lib/fluffery/forms/validation/validators.rb
79
+ - lib/fluffery/helpers/elements.rb
80
+ - lib/fluffery/helpers/includes.rb
81
+ - lib/fluffery/helpers/navigation.rb
82
+ - lib/fluffery/helpers/page_variables.rb
83
+ - lib/fluffery/railtie.rb
84
+ - lib/fluffery/utils/configurator.rb
85
+ - lib/fluffery/utils/internal.rb
86
+ - lib/fluffery/version.rb
87
+ has_rdoc: true
88
+ homepage: http://github.com/kurbmedia/fluffery
89
+ licenses:
90
+ - MIT
91
+ post_install_message:
92
+ rdoc_options: []
93
+
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: "0"
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ none: false
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: "0"
108
+ requirements: []
109
+
110
+ rubyforge_project: fluffery
111
+ rubygems_version: 1.6.1
112
+ signing_key:
113
+ specification_version: 3
114
+ summary: ummm.. Adds misc fluffery to yer apps.
115
+ test_files: []
116
+