any_view 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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 %>