any_view 0.1.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 (52) hide show
  1. data/.document +5 -0
  2. data/.gitignore +21 -0
  3. data/LICENSE +47 -0
  4. data/README.rdoc +369 -0
  5. data/Rakefile +57 -0
  6. data/lib/any_view/asset_tag_helpers.rb +103 -0
  7. data/lib/any_view/core_ext/array.rb +7 -0
  8. data/lib/any_view/core_ext/hash.rb +41 -0
  9. data/lib/any_view/core_ext/string.rb +17 -0
  10. data/lib/any_view/form_builder/abstract_form_builder.rb +128 -0
  11. data/lib/any_view/form_builder/standard_form_builder.rb +37 -0
  12. data/lib/any_view/form_helpers.rb +217 -0
  13. data/lib/any_view/format_helpers.rb +49 -0
  14. data/lib/any_view/tag_helpers.rb +47 -0
  15. data/lib/any_view/tilt_base.rb +94 -0
  16. data/lib/any_view.rb +30 -0
  17. data/test/fixtures/basic_form_for.erb +3 -0
  18. data/test/fixtures/builder_type_form_for.erb +3 -0
  19. data/test/fixtures/capture_concat.erb +14 -0
  20. data/test/fixtures/capture_concat.haml +13 -0
  21. data/test/fixtures/content_for.erb +11 -0
  22. data/test/fixtures/content_for.haml +9 -0
  23. data/test/fixtures/content_tag.erb +11 -0
  24. data/test/fixtures/content_tag.haml +9 -0
  25. data/test/fixtures/delete_form_for.erb +3 -0
  26. data/test/fixtures/field_set_tag.erb +3 -0
  27. data/test/fixtures/fields_for.erb +8 -0
  28. data/test/fixtures/fields_for.haml +6 -0
  29. data/test/fixtures/fields_for_basic.erb +3 -0
  30. data/test/fixtures/fields_for_nil.erb +3 -0
  31. data/test/fixtures/form_for.erb +56 -0
  32. data/test/fixtures/form_for.haml +47 -0
  33. data/test/fixtures/form_for_nil.erb +3 -0
  34. data/test/fixtures/form_tag.erb +57 -0
  35. data/test/fixtures/form_tag.haml +45 -0
  36. data/test/fixtures/form_tag_methods.erb +19 -0
  37. data/test/fixtures/form_tag_methods.haml +15 -0
  38. data/test/fixtures/link_to.erb +5 -0
  39. data/test/fixtures/link_to.haml +4 -0
  40. data/test/fixtures/mail_to.erb +3 -0
  41. data/test/fixtures/mail_to.haml +3 -0
  42. data/test/fixtures/multipart.erb +12 -0
  43. data/test/fixtures/multipart_form_for.erb +3 -0
  44. data/test/fixtures/put_form_for.erb +3 -0
  45. data/test/fixtures/standard_form_builder.erb +3 -0
  46. data/test/helper.rb +121 -0
  47. data/test/test_asset_tag_helpers.rb +176 -0
  48. data/test/test_form_builder.rb +607 -0
  49. data/test/test_form_helpers.rb +453 -0
  50. data/test/test_format_helpers.rb +59 -0
  51. data/test/test_tag_helpers.rb +65 -0
  52. metadata +160 -0
@@ -0,0 +1,128 @@
1
+ module AnyView
2
+ module Helpers
3
+ module FormBuilder
4
+ class AbstractFormBuilder
5
+ attr_accessor :view_context, :object
6
+
7
+ def initialize(view_context, object)
8
+ @view_context = view_context
9
+ @object = object
10
+ raise "FormBuilder view_context must be initialized!" unless view_context
11
+ raise "FormBuilder object must be not be nil value. If there's no object, use a symbol instead! (i.e :user)" unless object
12
+ end
13
+
14
+ # f.error_messages
15
+ def error_messages(options={})
16
+ @view_context.error_messages_for(@object, options)
17
+ end
18
+
19
+ # f.label :username, :caption => "Nickname"
20
+ def label(field, options={})
21
+ options.reverse_merge!(:caption => field.to_s.titleize)
22
+ @view_context.label_tag(field_id(field), options)
23
+ end
24
+
25
+ # f.hidden_field :session_id, :value => "45"
26
+ def hidden_field(field, options={})
27
+ options.reverse_merge!(:value => field_value(field), :id => field_id(field))
28
+ @view_context.hidden_field_tag field_name(field), options
29
+ end
30
+
31
+ # f.text_field :username, :value => "(blank)", :id => 'username'
32
+ def text_field(field, options={})
33
+ options.reverse_merge!(:value => field_value(field), :id => field_id(field))
34
+ @view_context.text_field_tag field_name(field), options
35
+ end
36
+
37
+ # f.text_area :summary, :value => "(enter summary)", :id => 'summary'
38
+ def text_area(field, options={})
39
+ options.reverse_merge!(:value => field_value(field), :id => field_id(field))
40
+ @view_context.text_area_tag field_name(field), options
41
+ end
42
+
43
+ # f.password_field :password, :id => 'password'
44
+ def password_field(field, options={})
45
+ options.reverse_merge!(:value => field_value(field), :id => field_id(field))
46
+ @view_context.password_field_tag field_name(field), options
47
+ end
48
+
49
+ # f.select :color, :options => ['red', 'green'], :include_blank => true
50
+ # f.select :color, :collection => @colors, :fields => [:name, :id]
51
+ def select(field, options={})
52
+ options.reverse_merge!(:id => field_id(field), :selected => field_value(field))
53
+ @view_context.select_tag field_name(field), options
54
+ end
55
+
56
+ # f.check_box :remember_me, :value => 'true', :uncheck_value => '0'
57
+ def check_box(field, options={})
58
+ unchecked_value = options.delete(:uncheck_value) || '0'
59
+ options.reverse_merge!(:id => field_id(field), :value => '1')
60
+ options.merge!(:checked => true) if values_matches_field?(field, options[:value])
61
+ html = @view_context.check_box_tag field_name(field), options
62
+ html << hidden_field(field, :value => unchecked_value, :id => nil)
63
+ end
64
+
65
+ # f.radio_button :gender, :value => 'male'
66
+ def radio_button(field, options={})
67
+ options.reverse_merge!(:id => field_id(field, options[:value]))
68
+ options.merge!(:checked => true) if values_matches_field?(field, options[:value])
69
+ @view_context.radio_button_tag field_name(field), options
70
+ end
71
+
72
+ # f.file_field :photo, :class => 'avatar'
73
+ def file_field(field, options={})
74
+ options.reverse_merge!(:id => field_id(field))
75
+ @view_context.file_field_tag field_name(field), options
76
+ end
77
+
78
+ # f.submit "Update", :class => 'large'
79
+ def submit(caption="Submit", options={})
80
+ @view_context.submit_tag caption, options
81
+ end
82
+
83
+ # f.simage_submitubmit "buttons/submit.png", :class => 'large'
84
+ def image_submit(source, options={})
85
+ @view_context.image_submit_tag source, options
86
+ end
87
+
88
+ protected
89
+
90
+ # Returns the known field types for a formbuilder
91
+ def self.field_types
92
+ [:hidden_field, :text_field, :text_area, :password_field, :file_field, :radio_button, :check_box, :select]
93
+ end
94
+
95
+ # Returns the object's models name
96
+ # => user_assignment
97
+ def object_name
98
+ object.is_a?(Symbol) ? object : object.class.to_s.underscore
99
+ end
100
+
101
+ # Returns true if the value matches the value in the field
102
+ # field_has_value?(:gender, 'male')
103
+ def values_matches_field?(field, value)
104
+ value.present? && (field_value(field).to_s == value.to_s || field_value(field).to_s == 'true')
105
+ end
106
+
107
+ # Returns the value for the object's field
108
+ # field_value(:username) => "Joey"
109
+ def field_value(field)
110
+ @object && @object.respond_to?(field) ? @object.send(field) : ""
111
+ end
112
+
113
+ # Returns the name for the given field
114
+ # field_name(:username) => "user[username]"
115
+ def field_name(field)
116
+ "#{object_name}[#{field}]"
117
+ end
118
+
119
+ # Returns the id for the given field
120
+ # field_id(:username) => "user_username"
121
+ # field_id(:gender, :male) => "user_gender_male"
122
+ def field_id(field, value=nil)
123
+ value.blank? ? "#{object_name}_#{field}" : "#{object_name}_#{field}_#{value}"
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,37 @@
1
+ module AnyView
2
+ module Helpers
3
+ module FormBuilder
4
+ class StandardFormBuilder < AbstractFormBuilder
5
+
6
+ # text_field_block(:username, { :class => 'long' }, { :class => 'wide-label' })
7
+ # text_area_block(:summary, { :class => 'long' }, { :class => 'wide-label' })
8
+ # password_field_block(:password, { :class => 'long' }, { :class => 'wide-label' })
9
+ # file_field_block(:photo, { :class => 'long' }, { :class => 'wide-label' })
10
+ # check_box_block(:remember_me, { :class => 'long' }, { :class => 'wide-label' })
11
+ # select_block(:color, :options => ['green', 'black'])
12
+ (self.field_types - [ :hidden_field, :radio_button ]).each do |field_type|
13
+ class_eval <<-EOF
14
+ def #{field_type}_block(field, options={}, label_options={})
15
+ label_options.reverse_merge!(:caption => options.delete(:caption)) if options[:caption]
16
+ field_html = label(field, label_options)
17
+ field_html << #{field_type}(field, options)
18
+ @view_context.content_tag(:p, field_html)
19
+ end
20
+ EOF
21
+ end
22
+
23
+ # submit_block("Update")
24
+ def submit_block(caption, options={})
25
+ submit_html = self.submit(caption, options)
26
+ @view_context.content_tag(:p, submit_html)
27
+ end
28
+
29
+ # image_submit_block("submit.png")
30
+ def image_submit_block(source, options={})
31
+ submit_html = self.image_submit(source, options)
32
+ @view_context.content_tag(:p, submit_html)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,217 @@
1
+ module AnyView
2
+ module Helpers
3
+ module FormHelpers
4
+ # Constructs a form for object using given or default form_builder
5
+ # form_for @user, '/register', :id => 'register' do |f| ... end
6
+ def form_for(object, url, settings={}, &block)
7
+ builder_class = configured_form_builder_class(settings[:builder])
8
+ settings[:builder] = builder_class.new(self, object)
9
+ form_tag(url, settings, &block)
10
+ end
11
+
12
+ # Constructs form fields for an object using given or default form_builder
13
+ # Used within an existing form to allow alternate objects within one form
14
+ # fields_for @user.assignment do |assignment| ... end
15
+ # fields_for :assignment do |assigment| ... end
16
+ def fields_for(object, settings={}, &block)
17
+ builder_class = configured_form_builder_class(settings[:builder])
18
+ fields_html = capture_content(builder_class.new(self, object), &block)
19
+ concat_content fields_html
20
+ end
21
+
22
+ # Constructs a form without object based on options
23
+ # form_tag '/register' do ... end
24
+ def form_tag(url, options={}, &block)
25
+ options.reverse_merge!(:method => 'post', :action => url)
26
+
27
+ @_multi_enc_type = options.delete(:multipart)
28
+ fake_method = hidden_form_method_field(options[:method])
29
+ real_method = real_method_for_fake(options[:method])
30
+ options[:method] = real_method
31
+ builder = options.delete(:builder)
32
+
33
+ inner_form_html = fake_method.to_s
34
+ inner_form_html += if builder
35
+ capture_content(builder, &block)
36
+ else
37
+ capture_content(&block)
38
+ end
39
+
40
+ options[:enctype] = "multipart/form-data" if @_multi_enc_type
41
+ @_multi_enc_type = nil
42
+ concat_content content_tag('form', inner_form_html, options)
43
+ end
44
+
45
+ # Constructs a field_set to group fields with given options
46
+ # field_set_tag("Office", :class => 'office-set')
47
+ # parameters: legend_text=nil, options={}
48
+ def field_set_tag(*args, &block)
49
+ options = args.extract_options!
50
+ legend_text = args[0].is_a?(String) ? args.first : nil
51
+ legend_html = legend_text.blank? ? '' : content_tag(:legend, legend_text)
52
+ field_set_content = legend_html + capture_content(&block)
53
+ concat_content content_tag('fieldset', field_set_content, options)
54
+ end
55
+
56
+ # Constructs list html for the errors for a given object
57
+ # error_messages_for @user
58
+ def error_messages_for(record, options={})
59
+ return "" if record.blank? or record.errors.none?
60
+ options.reverse_merge!(:header_message => "The #{record.class.to_s.downcase} could not be saved!")
61
+ error_messages = record.errors.full_messages
62
+ error_items = error_messages.collect { |er| content_tag(:li, er) }.join("\n")
63
+ error_html = content_tag(:p, options.delete(:header_message))
64
+ error_html << content_tag(:ul, error_items, :class => 'errors-list')
65
+ content_tag(:div, error_html, :class => 'field-errors')
66
+ end
67
+
68
+ # Constructs a label tag from the given options
69
+ # label_tag :username, :class => 'long-label'
70
+ # label_tag :username, :class => 'long-label' do ... end
71
+ def label_tag(name, options={}, &block)
72
+ options.reverse_merge!(:caption => name.to_s.titleize, :for => name)
73
+ caption_text = options.delete(:caption) + ": "
74
+ if block_given? # label with inner content
75
+ label_content = caption_text + capture_content(&block)
76
+ concat_content(content_tag(:label, label_content, options))
77
+ else # regular label
78
+ content_tag(:label, caption_text, options)
79
+ end
80
+ end
81
+
82
+ # Constructs a hidden field input from the given options
83
+ # hidden_field_tag :session_key, :value => "__secret__"
84
+ def hidden_field_tag(name, options={})
85
+ options.reverse_merge!(:name => name)
86
+ input_tag(:hidden, options)
87
+ end
88
+
89
+ # Constructs a text field input from the given options
90
+ # text_field_tag :username, :class => 'long'
91
+ def text_field_tag(name, options={})
92
+ options.reverse_merge!(:name => name)
93
+ input_tag(:text, options)
94
+ end
95
+
96
+ # Constructs a text area input from the given options
97
+ # text_area_tag :username, :class => 'long'
98
+ def text_area_tag(name, options={})
99
+ options.reverse_merge!(:name => name)
100
+ content_tag(:textarea, '', options)
101
+ end
102
+
103
+ # Constructs a password field input from the given options
104
+ # password_field_tag :password, :class => 'long'
105
+ def password_field_tag(name, options={})
106
+ options.reverse_merge!(:name => name)
107
+ input_tag(:password, options)
108
+ end
109
+
110
+ # Constructs a check_box from the given options
111
+ # options = [['caption', 'value'], ['Green', 'green1'], ['Blue', 'blue1'], ['Black', "black1"]]
112
+ # options = ['option', 'red', 'yellow' ]
113
+ # select_tag(:favorite_color, :options => ['red', 'yellow'], :selected => 'green1')
114
+ # select_tag(:country, :collection => @countries, :fields => [:name, :code])
115
+ def select_tag(name, options={})
116
+ options.reverse_merge!(:name => name)
117
+ collection, fields = options.delete(:collection), options.delete(:fields)
118
+ options[:options] = options_from_collection(collection, fields) if collection
119
+ options[:options].unshift('') if options.delete(:include_blank)
120
+ select_options_html = options_for_select(options.delete(:options), options.delete(:selected)).join
121
+ options.merge!(:name => "#{options[:name]}[]") if options[:multiple]
122
+ content_tag(:select, select_options_html, options)
123
+ end
124
+
125
+ # Constructs a check_box from the given options
126
+ # check_box_tag :remember_me, :value => 'Yes'
127
+ def check_box_tag(name, options={})
128
+ options.reverse_merge!(:name => name, :value => '1')
129
+ input_tag(:checkbox, options)
130
+ end
131
+
132
+ # Constructs a radio_button from the given options
133
+ # radio_button_tag :remember_me, :value => 'true'
134
+ def radio_button_tag(name, options={})
135
+ options.reverse_merge!(:name => name)
136
+ input_tag(:radio, options)
137
+ end
138
+
139
+ # Constructs a file field input from the given options
140
+ # file_field_tag :photo, :class => 'long'
141
+ def file_field_tag(name, options={})
142
+ @_multi_enc_type = true
143
+ options.reverse_merge!(:name => name)
144
+ input_tag(:file, options)
145
+ end
146
+
147
+ # Constructs a submit button from the given options
148
+ # submit_tag "Create", :class => 'success'
149
+ def submit_tag(caption="Submit", options={})
150
+ options.reverse_merge!(:value => caption)
151
+ input_tag(:submit, options)
152
+ end
153
+
154
+ # Constructs a button input from the given options
155
+ # button_tag "Cancel", :class => 'clear'
156
+ def button_tag(caption, options = {})
157
+ options.reverse_merge!(:value => caption)
158
+ input_tag(:button, options)
159
+ end
160
+
161
+ # Constructs a submit button from the given options
162
+ # submit_tag "Create", :class => 'success'
163
+ def image_submit_tag(source, options={})
164
+ options.reverse_merge!(:src => image_path(source))
165
+ input_tag(:image, options)
166
+ end
167
+
168
+ protected
169
+
170
+ # Returns an array of option items for a select field based on the given collection
171
+ # fields is an array containing the fields to display from each item in the collection
172
+ def options_from_collection(collection, fields)
173
+ return '' if collection.blank?
174
+ collection.collect { |item| [ item.send(fields.first), item.send(fields.last) ] }
175
+ end
176
+
177
+ # Returns the options tags for a select based on the given option items
178
+ def options_for_select(option_items, selected_value=nil)
179
+ return '' if option_items.blank?
180
+ option_items.collect do |caption, value|
181
+ value ||= caption
182
+ content_tag(:option, caption, :value => value, :selected => selected_value.to_s =~ /#{value}|#{caption}/)
183
+ end
184
+ end
185
+
186
+ # returns the hidden method field for 'put' and 'delete' forms
187
+ # Only 'get' and 'post' are allowed within browsers;
188
+ # 'put' and 'delete' are just specified using hidden fields with form action still 'put'.
189
+ # hidden_form_method_field('delete') => <input name="_method" value="delete" />
190
+ def hidden_form_method_field(desired_method)
191
+ case desired_method
192
+ when :get, :GET, :POST, :post, /get/i, /post/i
193
+ ''
194
+ else
195
+ hidden_field_tag(:_method, :value => desired_method)
196
+ end
197
+ end
198
+
199
+ def real_method_for_fake(desired_method)
200
+ case desired_method
201
+ when :get, :GET, :delete, :DELETE, /get/i, /delete/i
202
+ 'get'
203
+ else
204
+ 'post'
205
+ end
206
+ end
207
+
208
+ # Returns the FormBuilder class to use based on all available setting sources
209
+ # If explicitly defined, returns that, otherwise returns defaults
210
+ # configured_form_builder_class(nil) => StandardFormBuilder
211
+ def configured_form_builder_class(explicit_builder=nil)
212
+ default_builder = self.respond_to?(:options) && self.options.default_builder
213
+ explicit_builder || default_builder || FormBuilder::StandardFormBuilder
214
+ end
215
+ end
216
+ end
217
+ end
@@ -0,0 +1,49 @@
1
+ module AnyView
2
+ module Helpers
3
+ module FormatHelpers
4
+
5
+ # Returns escaped text to protect against malicious content
6
+ def escape_html(text)
7
+ Rack::Utils.escape_html(text)
8
+ end
9
+ alias h escape_html
10
+ alias sanitize_html escape_html
11
+
12
+ # Returns escaped text to protect against malicious content
13
+ # Returns blank if the text is empty
14
+ def h!(text, blank_text = '&nbsp;')
15
+ return blank_text if text.nil? || text.empty?
16
+ h text
17
+ end
18
+
19
+ # Truncates a given text after a given :length if text is longer than :length (defaults to 30).
20
+ # The last characters will be replaced with the :omission (defaults to "…") for a total length not exceeding :length.
21
+ # truncate("Once upon a time in a world far far away", :length => 8) => "Once upon..."
22
+ def truncate(text, *args)
23
+ options = args.extract_options!
24
+ options = options.dup
25
+ options.reverse_merge!(:length => 30, :omission => "...")
26
+ if text
27
+ len = options[:length] - options[:omission].length
28
+ chars = text
29
+ (chars.length > options[:length] ? chars[0...len] + options[:omission] : text).to_s
30
+ end
31
+ end
32
+
33
+
34
+ # Returns text transformed into HTML using simple formatting rules. Two or more consecutive newlines(\n\n) are considered
35
+ # as a paragraph and wrapped in <p> tags. One newline (\n) is considered as a linebreak and a <br /> tag is appended.
36
+ # This method does not remove the newlines from the text.
37
+ # simple_format("hello\nworld") # => "<p>hello<br/>world</p>"
38
+ def simple_format(text, html_options={})
39
+ start_tag = tag('p', html_options.merge(:open => true))
40
+ text = text.to_s.dup
41
+ text.gsub!(/\r\n?/, "\n") # \r\n and \r -> \n
42
+ text.gsub!(/\n\n+/, "</p>\n\n#{start_tag}") # 2+ newline -> paragraph
43
+ text.gsub!(/([^\n]\n)(?=[^\n])/, '\1<br />') # 1 newline -> br
44
+ text.insert 0, start_tag
45
+ text << "</p>"
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,47 @@
1
+ module AnyView
2
+ module Helpers
3
+ module TagHelpers
4
+ # Creates an html input field with given type and options
5
+ # input_tag :text, :class => "test"
6
+ def input_tag(type, options = {})
7
+ options = options.dup
8
+ options[:type] = type
9
+ tag(:input, options)
10
+ end
11
+
12
+ # Creates an html tag with given name, content and options
13
+ # @example
14
+ # content_tag(:p, "hello", :class => 'light')
15
+ # content_tag(:p, :class => 'dark') do ... end
16
+ # parameters: content_tag(name, content=nil, options={}, &block)
17
+ # Writes directly to the buffer
18
+ def content_tag(*args, &block)
19
+ name = args.first
20
+ options = args.extract_options!
21
+ tag_html = block_given? ? capture_content(options, &block) : args[1]
22
+ tag_result = tag(name, options.merge(:content => tag_html))
23
+ block.nil? ? tag_result : concat_content(tag_result)
24
+ end
25
+
26
+ # Creates an html tag with the given name and options
27
+ # @example
28
+ # tag(:br, :style => 'clear:both')
29
+ # tag(:p, :content => "hello", :class => 'large')
30
+ # @return a string
31
+ def tag(name, options={})
32
+ content, open_tag = options.delete(:content), options.delete(:open)
33
+ identity_tag_attributes.each { |attr| options[attr] = attr.to_s if options[attr] }
34
+ html_attrs = options.collect { |a, v| v.blank? ? nil : "#{a}=\"#{v}\"" }.compact.join(" ")
35
+ base_tag = (html_attrs.present? ? "<#{name} #{html_attrs}" : "<#{name}")
36
+ base_tag << (open_tag ? ">" : (content ? ">#{content}</#{name}>" : " />"))
37
+ end
38
+
39
+ protected
40
+
41
+ # Returns a list of attributes which can only contain an identity value (i.e selected)
42
+ def identity_tag_attributes
43
+ [:checked, :disabled, :selected, :multiple]
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,94 @@
1
+ require 'tilt'
2
+
3
+ class Tilt::Template
4
+ def render_with_any_view(scope=Object.new, locals = {}, &blk)
5
+ scope.template_type = self.class if scope.respond_to?(:template_type=)
6
+ render_without_any_view(scope, locals, &blk)
7
+ end
8
+ alias_method :render_without_any_view, :render
9
+ alias_method :render, :render_with_any_view
10
+ end
11
+
12
+ module AnyView
13
+ # Provides capture and concat methods for use inside templates with the Tilt gem.
14
+ module TiltBase
15
+ class Error < StandardError; end
16
+ class CaptureMethodNotFound < Error; end
17
+ class ContentMethodNotFound < Error; end
18
+
19
+ def self.included(base)
20
+ base.class_eval do
21
+ attr_writer :template_type unless self.method_defined?(:template_type=)
22
+ attr_reader :template_type unless self.method_defined?(:template_type)
23
+ end
24
+ end
25
+
26
+ class << self
27
+ # Keeps track of the concatenation methods for each template type.
28
+ # If you have your own template types, then you should add them here
29
+ def concat_methods
30
+ @concat_methods ||= {}
31
+ end
32
+
33
+ def capture_methods
34
+ @capture_methods ||= {}
35
+ end
36
+
37
+ def capture_method_for(template)
38
+ capture_methods[template]
39
+ end
40
+
41
+ def concat_method_for(template)
42
+ concat_methods[template]
43
+ end
44
+ end
45
+
46
+ capture_methods[::Tilt::HamlTemplate ] = :_haml_capture
47
+ capture_methods[::Tilt::ERBTemplate ] = :_erb_capture
48
+ capture_methods[::Tilt::ErubisTemplate] = :_erb_capture
49
+
50
+ concat_methods[ ::Tilt::HamlTemplate ] = :_haml_concat
51
+ concat_methods[ ::Tilt::ERBTemplate ] = :_erb_concat
52
+ concat_methods[ ::Tilt::ErubisTemplate] = :_erb_concat
53
+
54
+ def capture_content(*args, &blk)
55
+ opts = args.extract_options!
56
+ opts[:template_type] ||= template_type
57
+ capture_method = AnyView::TiltBase.capture_method_for(opts[:template_type])
58
+
59
+ raise CaptureMethodNotFound, "Capture Method not found for Template Type: #{opts[:template_type].inspect}" unless capture_method
60
+ send(capture_method, *args, &blk)
61
+ end
62
+
63
+ def concat_content(string, opts = {})
64
+ opts[:template_type] ||= template_type
65
+ concat_method = AnyView::TiltBase.concat_method_for(opts[:template_type])
66
+
67
+ raise ConcatMethodNotFound, "Concat Method not found for Template Type: #{opts[:template_type].inspect}" unless concat_method
68
+ send(concat_method, string)
69
+ end
70
+
71
+ def _haml_capture(*args, &block)
72
+ with_haml_buffer Haml::Buffer.new(nil, :encoding => "UTF-8") do
73
+ capture_haml(*args, &block)
74
+ end
75
+ end
76
+
77
+ def _erb_capture(*args, &block)
78
+ _out_buf, @_out_buf = @_out_buf, ""
79
+ block.call(*args)
80
+ ret = @_out_buf
81
+ @_out_buf = _out_buf
82
+ ret
83
+ end
84
+
85
+ def _haml_concat(string)
86
+ haml_concat(string)
87
+ end
88
+
89
+ def _erb_concat(string)
90
+ @_out_buf << string
91
+ end
92
+ end
93
+ end
94
+
data/lib/any_view.rb ADDED
@@ -0,0 +1,30 @@
1
+ require 'dirge'
2
+ require ~'./any_view/core_ext/string'
3
+ require ~'./any_view/core_ext/hash'
4
+ require ~'./any_view/core_ext/array'
5
+
6
+ module AnyView
7
+ autoload :TiltBase, ~'./any_view/tilt_base'
8
+
9
+ module Helpers
10
+ autoload :TagHelpers, ~'./any_view/tag_helpers'
11
+ autoload :AssetTagHelpers, ~'./any_view/asset_tag_helpers'
12
+ autoload :FormatHelpers, ~'./any_view/format_helpers'
13
+ autoload :FormHelpers, ~'./any_view/form_helpers'
14
+
15
+ module FormBuilder
16
+ autoload :AbstractFormBuilder, ~'./any_view/form_builder/abstract_form_builder'
17
+ autoload :StandardFormBuilder, ~'./any_view/form_builder/standard_form_builder'
18
+ end
19
+ end
20
+
21
+
22
+ def self.included(base)
23
+ ah = AnyView::Helpers
24
+ base.class_eval do
25
+ include ah::TagHelpers, ah::AssetTagHelpers, ah::FormHelpers, ah::FormatHelpers
26
+ end
27
+ end
28
+ end
29
+
30
+
@@ -0,0 +1,3 @@
1
+ <% form_for MarkupUser.new, '/register', :id => 'register', :method => :post do |f| %>
2
+ <div>Demo</div>
3
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <% form_for MarkupUser.new, "/register", :builder => AnyView::Helpers::FormBuilder::AbstractFormBuilder do |f| %>
2
+ <%= f.text_field_block(:name) %>
3
+ <% end %>
@@ -0,0 +1,14 @@
1
+ <% @content = captured_content do %>
2
+ <span>Captured Line 1</span>
3
+ <span>Captured Line 2</span>
4
+ <% end %>
5
+ <%= @content %>
6
+
7
+ <% concat_in_p('Concat Line 3') %>
8
+
9
+ <% determine_block_is_template('erb') do %>
10
+ <span>This is erb</span>
11
+ <span>This is erb</span>
12
+ <% end %>
13
+
14
+ <% ruby_not_template_block %>
@@ -0,0 +1,13 @@
1
+ - @content = captured_content do
2
+ %span Captured Line 1
3
+ %span Captured Line 2
4
+ = @content
5
+
6
+ - concat_in_p('Concat Line 3')
7
+
8
+ - determine_block_is_template('haml') do
9
+ %span This is haml
10
+ %span This is haml
11
+
12
+ - ruby_not_template_block
13
+
@@ -0,0 +1,11 @@
1
+ <% content_for :demo do %>
2
+ <h1>This is content yielded from a content_for</h1>
3
+ <% end %>
4
+
5
+ <div class='demo'><%= yield_content :demo %></p>
6
+
7
+ <% content_for :demo2 do |fname, lname| %>
8
+ <h1>This is content yielded with name <%= fname + " " + lname %></h1>
9
+ <% end %>
10
+
11
+ <div class='demo2'><%= yield_content :demo2, "Johnny", "Smith" %></div>
@@ -0,0 +1,9 @@
1
+ - content_for :demo do
2
+ %h1 This is content yielded from a content_for
3
+
4
+ .demo= yield_content :demo
5
+
6
+ - content_for :demo2 do |fname, lname|
7
+ %h1 This is content yielded with name #{fname + " " + lname}
8
+
9
+ .demo2= yield_content :demo2, "Johnny", "Smith"
@@ -0,0 +1,11 @@
1
+ <%= content_tag :p, "Test 1", :class => 'test', :id => "test1" %>
2
+
3
+ <%= content_tag :p, "Test 2" %>
4
+
5
+ <% content_tag(:p, :class => 'test', :id => 'test3') do %>
6
+ <span>Test 3</span>
7
+ <% end %>
8
+
9
+ <% content_tag(:p) do %>
10
+ <span>Test 4</span>
11
+ <% end %>