middleman 2.0.4 → 2.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (172) hide show
  1. data/CHANGELOG +8 -0
  2. data/lib/middleman.rb +7 -1
  3. data/lib/middleman/vendor/padrino-core-0.10.0/.document +5 -0
  4. data/lib/middleman/vendor/padrino-core-0.10.0/.gitignore +22 -0
  5. data/lib/middleman/vendor/padrino-core-0.10.0/LICENSE +20 -0
  6. data/lib/middleman/vendor/padrino-core-0.10.0/README.rdoc +294 -0
  7. data/lib/middleman/vendor/padrino-core-0.10.0/Rakefile +5 -0
  8. data/lib/middleman/vendor/padrino-core-0.10.0/bin/padrino +9 -0
  9. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core.rb +119 -0
  10. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/application.rb +259 -0
  11. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/application/rendering.rb +228 -0
  12. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/application/routing.rb +821 -0
  13. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/application/showexceptions.rb +18 -0
  14. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/caller.rb +45 -0
  15. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/cli/adapter.rb +24 -0
  16. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/cli/base.rb +152 -0
  17. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/cli/console.rb +20 -0
  18. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/cli/rake.rb +24 -0
  19. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/cli/rake_tasks.rb +59 -0
  20. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/command.rb +27 -0
  21. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/images/404.png +0 -0
  22. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/images/500.png +0 -0
  23. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/loader.rb +182 -0
  24. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/cz.yml +30 -0
  25. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/da.yml +30 -0
  26. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/de.yml +30 -0
  27. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/en.yml +30 -0
  28. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/es.yml +30 -0
  29. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/fr.yml +30 -0
  30. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/hu.yml +30 -0
  31. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/it.yml +37 -0
  32. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/ja.yml +30 -0
  33. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/nl.yml +30 -0
  34. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/no.yml +31 -0
  35. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/pl.yml +30 -0
  36. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/pt_br.yml +37 -0
  37. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/ru.yml +30 -0
  38. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/tr.yml +30 -0
  39. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/uk.yml +30 -0
  40. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/zh_cn.yml +30 -0
  41. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/zh_tw.yml +30 -0
  42. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/logger.rb +344 -0
  43. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/mounter.rb +192 -0
  44. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/reloader.rb +247 -0
  45. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/router.rb +79 -0
  46. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/server.rb +70 -0
  47. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/support_lite.rb +135 -0
  48. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/tasks.rb +23 -0
  49. data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/version.rb +15 -0
  50. data/lib/middleman/vendor/padrino-core-0.10.0/padrino-core.gemspec +38 -0
  51. data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/apps/.components +6 -0
  52. data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/apps/.gitignore +7 -0
  53. data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/apps/complex.rb +27 -0
  54. data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/apps/simple.rb +33 -0
  55. data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/dependencies/a.rb +9 -0
  56. data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/dependencies/b.rb +4 -0
  57. data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/dependencies/c.rb +1 -0
  58. data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/dependencies/circular/e.rb +13 -0
  59. data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/dependencies/circular/f.rb +2 -0
  60. data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/dependencies/circular/g.rb +2 -0
  61. data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/dependencies/d.rb +4 -0
  62. data/lib/middleman/vendor/padrino-core-0.10.0/test/helper.rb +101 -0
  63. data/lib/middleman/vendor/padrino-core-0.10.0/test/test_application.rb +83 -0
  64. data/lib/middleman/vendor/padrino-core-0.10.0/test/test_core.rb +79 -0
  65. data/lib/middleman/vendor/padrino-core-0.10.0/test/test_dependencies.rb +44 -0
  66. data/lib/middleman/vendor/padrino-core-0.10.0/test/test_filters.rb +266 -0
  67. data/lib/middleman/vendor/padrino-core-0.10.0/test/test_logger.rb +91 -0
  68. data/lib/middleman/vendor/padrino-core-0.10.0/test/test_mounter.rb +176 -0
  69. data/lib/middleman/vendor/padrino-core-0.10.0/test/test_reloader_complex.rb +66 -0
  70. data/lib/middleman/vendor/padrino-core-0.10.0/test/test_reloader_simple.rb +97 -0
  71. data/lib/middleman/vendor/padrino-core-0.10.0/test/test_rendering.rb +437 -0
  72. data/lib/middleman/vendor/padrino-core-0.10.0/test/test_router.rb +146 -0
  73. data/lib/middleman/vendor/padrino-core-0.10.0/test/test_routing.rb +1491 -0
  74. data/lib/middleman/vendor/padrino-helpers-0.10.0/.document +5 -0
  75. data/lib/middleman/vendor/padrino-helpers-0.10.0/.gitignore +21 -0
  76. data/lib/middleman/vendor/padrino-helpers-0.10.0/LICENSE +20 -0
  77. data/lib/middleman/vendor/padrino-helpers-0.10.0/README.rdoc +239 -0
  78. data/lib/middleman/vendor/padrino-helpers-0.10.0/Rakefile +5 -0
  79. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers.rb +51 -0
  80. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/asset_tag_helpers.rb +288 -0
  81. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/form_builder/abstract_form_builder.rb +220 -0
  82. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/form_builder/standard_form_builder.rb +43 -0
  83. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/form_helpers.rb +446 -0
  84. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/format_helpers.rb +260 -0
  85. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/cz.yml +103 -0
  86. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/da.yml +91 -0
  87. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/de.yml +78 -0
  88. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/en.yml +103 -0
  89. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/es.yml +103 -0
  90. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/fr.yml +79 -0
  91. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/hu.yml +103 -0
  92. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/it.yml +85 -0
  93. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/ja.yml +103 -0
  94. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/nl.yml +78 -0
  95. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/no.yml +91 -0
  96. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/pl.yml +95 -0
  97. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/pt_br.yml +103 -0
  98. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/ru.yml +103 -0
  99. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/tr.yml +103 -0
  100. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/uk.yml +103 -0
  101. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/zh_cn.yml +103 -0
  102. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/zh_tw.yml +103 -0
  103. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/number_helpers.rb +273 -0
  104. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/output_helpers.rb +128 -0
  105. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/output_helpers/abstract_handler.rb +103 -0
  106. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/output_helpers/erb_handler.rb +79 -0
  107. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/output_helpers/haml_handler.rb +64 -0
  108. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/output_helpers/slim_handler.rb +82 -0
  109. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/render_helpers.rb +40 -0
  110. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/tag_helpers.rb +59 -0
  111. data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/translation_helpers.rb +21 -0
  112. data/lib/middleman/vendor/padrino-helpers-0.10.0/padrino-helpers.gemspec +27 -0
  113. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/app.rb +73 -0
  114. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/capture_concat.erb +14 -0
  115. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/capture_concat.haml +12 -0
  116. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/capture_concat.slim +13 -0
  117. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/content_for.erb +11 -0
  118. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/content_for.haml +9 -0
  119. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/content_for.slim +9 -0
  120. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/content_tag.erb +11 -0
  121. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/content_tag.haml +9 -0
  122. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/content_tag.slim +9 -0
  123. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/current_engine.erb +5 -0
  124. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/current_engine.haml +5 -0
  125. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/current_engine.slim +5 -0
  126. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/fields_for.erb +20 -0
  127. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/fields_for.haml +15 -0
  128. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/fields_for.slim +15 -0
  129. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/form_for.erb +56 -0
  130. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/form_for.haml +47 -0
  131. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/form_for.slim +47 -0
  132. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/form_tag.erb +56 -0
  133. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/form_tag.haml +45 -0
  134. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/form_tag.slim +45 -0
  135. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/link_to.erb +5 -0
  136. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/link_to.haml +4 -0
  137. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/link_to.slim +4 -0
  138. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/mail_to.erb +3 -0
  139. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/mail_to.haml +3 -0
  140. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/mail_to.slim +3 -0
  141. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/meta_tag.erb +3 -0
  142. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/meta_tag.haml +3 -0
  143. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/meta_tag.slim +3 -0
  144. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/partials/_erb.erb +1 -0
  145. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/partials/_haml.haml +1 -0
  146. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/partials/_slim.slim +1 -0
  147. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/simple_partial.erb +1 -0
  148. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/simple_partial.haml +1 -0
  149. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/simple_partial.slim +1 -0
  150. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/app.rb +45 -0
  151. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/views/current_engine.haml +5 -0
  152. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/views/current_engines/_erb.erb +1 -0
  153. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/views/current_engines/_haml.haml +1 -0
  154. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/views/current_engines/_slim.slim +1 -0
  155. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/views/erb/test.erb +1 -0
  156. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/views/explicit_engine.haml +5 -0
  157. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/views/haml/test.haml +1 -0
  158. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/views/template/_user.haml +7 -0
  159. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/views/template/haml_template.haml +1 -0
  160. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/views/template/some_template.haml +2 -0
  161. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/helper.rb +78 -0
  162. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/test_asset_tag_helpers.rb +320 -0
  163. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/test_form_builder.rb +998 -0
  164. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/test_form_helpers.rb +645 -0
  165. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/test_format_helpers.rb +227 -0
  166. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/test_number_helpers.rb +136 -0
  167. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/test_output_helpers.rb +133 -0
  168. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/test_render_helpers.rb +69 -0
  169. data/lib/middleman/vendor/padrino-helpers-0.10.0/test/test_tag_helpers.rb +100 -0
  170. data/lib/middleman/version.rb +1 -1
  171. data/middleman.gemspec +6 -2
  172. metadata +218 -67
@@ -0,0 +1,220 @@
1
+ module Padrino
2
+ module Helpers
3
+ module FormBuilder #:nodoc:
4
+ class AbstractFormBuilder #:nodoc:
5
+ attr_accessor :template, :object
6
+
7
+ def initialize(template, object, options={})
8
+ @template = template
9
+ @object = build_object(object)
10
+ @options = options
11
+ raise "FormBuilder template must be initialized!" unless template
12
+ raise "FormBuilder object must be not be nil value. If there's no object, use a symbol instead! (i.e :user)" unless object
13
+ end
14
+
15
+ # f.error_messages
16
+ def error_messages(*params)
17
+ params.unshift object
18
+ @template.error_messages_for(*params)
19
+ end
20
+
21
+ # f.error_message_on(field)
22
+ def error_message_on(field, options={})
23
+ @template.error_message_on(object, field, options)
24
+ end
25
+
26
+ # f.label :username, :caption => "Nickname"
27
+ def label(field, options={})
28
+ options.reverse_merge!(:caption => "#{field_human_name(field)}: ")
29
+ @template.label_tag(field_id(field), options)
30
+ end
31
+
32
+ # f.hidden_field :session_id, :value => "45"
33
+ def hidden_field(field, options={})
34
+ options.reverse_merge!(:value => field_value(field), :id => field_id(field))
35
+ @template.hidden_field_tag field_name(field), options
36
+ end
37
+
38
+ # f.text_field :username, :value => "(blank)", :id => 'username'
39
+ def text_field(field, options={})
40
+ options.reverse_merge!(:value => field_value(field), :id => field_id(field))
41
+ options.merge!(:class => field_error(field, options))
42
+ @template.text_field_tag field_name(field), options
43
+ end
44
+
45
+ # f.text_area :summary, :value => "(enter summary)", :id => 'summary'
46
+ def text_area(field, options={})
47
+ options.reverse_merge!(:value => field_value(field), :id => field_id(field))
48
+ options.merge!(:class => field_error(field, options))
49
+ @template.text_area_tag field_name(field), options
50
+ end
51
+
52
+ # f.password_field :password, :id => 'password'
53
+ def password_field(field, options={})
54
+ options.reverse_merge!(:value => field_value(field), :id => field_id(field))
55
+ options.merge!(:class => field_error(field, options))
56
+ @template.password_field_tag field_name(field), options
57
+ end
58
+
59
+ # f.select :color, :options => ['red', 'green'], :include_blank => true
60
+ # f.select :color, :collection => @colors, :fields => [:name, :id]
61
+ def select(field, options={})
62
+ options.reverse_merge!(:id => field_id(field), :selected => field_value(field))
63
+ options.merge!(:class => field_error(field, options))
64
+ @template.select_tag field_name(field), options
65
+ end
66
+
67
+ # f.check_box :remember_me, :value => 'true', :uncheck_value => '0'
68
+ def check_box(field, options={})
69
+ unchecked_value = options.delete(:uncheck_value) || '0'
70
+ options.reverse_merge!(:id => field_id(field), :value => '1')
71
+ options.reverse_merge!(:checked => true) if values_matches_field?(field, options[:value])
72
+ html = @template.hidden_field_tag(options[:name] || field_name(field), :value => unchecked_value, :id => nil)
73
+ html << @template.check_box_tag(field_name(field), options)
74
+ end
75
+
76
+ # f.radio_button :gender, :value => 'male'
77
+ def radio_button(field, options={})
78
+ options.reverse_merge!(:id => field_id(field, options[:value]))
79
+ options.reverse_merge!(:checked => true) if values_matches_field?(field, options[:value])
80
+ @template.radio_button_tag field_name(field), options
81
+ end
82
+
83
+ # f.file_field :photo, :class => 'avatar'
84
+ def file_field(field, options={})
85
+ options.reverse_merge!(:id => field_id(field))
86
+ options.merge!(:class => field_error(field, options))
87
+ @template.file_field_tag field_name(field), options
88
+ end
89
+
90
+ # f.submit "Update", :class => 'large'
91
+ def submit(caption="Submit", options={})
92
+ @template.submit_tag caption, options
93
+ end
94
+
95
+ # f.image_submit "buttons/submit.png", :class => 'large'
96
+ def image_submit(source, options={})
97
+ @template.image_submit_tag source, options
98
+ end
99
+
100
+ # Supports nested fields for a child model within a form
101
+ # f.fields_for :addresses
102
+ # f.fields_for :addresses, address
103
+ # f.fields_for :addresses, @addresses
104
+ def fields_for(child_association, instance_or_collection=nil, &block)
105
+ default_collection = self.object.send(child_association)
106
+ include_index = default_collection.respond_to?(:each)
107
+ nested_options = { :parent => self, :association => child_association }
108
+ nested_objects = instance_or_collection ? Array(instance_or_collection) : Array(default_collection)
109
+ result = nested_objects.each_with_index.map do |child_instance, index|
110
+ nested_options[:index] = include_index ? index : nil
111
+ @template.fields_for(child_instance, { :nested => nested_options }, &block)
112
+ end.join("\n")
113
+ end
114
+
115
+ protected
116
+ # Returns the known field types for a formbuilder
117
+ def self.field_types
118
+ [:hidden_field, :text_field, :text_area, :password_field, :file_field, :radio_button, :check_box, :select]
119
+ end
120
+
121
+ # Returns true if the value matches the value in the field
122
+ # field_has_value?(:gender, 'male')
123
+ def values_matches_field?(field, value)
124
+ value.present? && (field_value(field).to_s == value.to_s || field_value(field).to_s == 'true')
125
+ end
126
+
127
+ # Add a :invalid css class to the field if it contain an error
128
+ def field_error(field, options)
129
+ error = @object.errors[field] rescue nil
130
+ error.blank? ? options[:class] : [options[:class], :invalid].flatten.compact.join(" ")
131
+ end
132
+
133
+ # Returns the human name of the field. Look that use builtin I18n.
134
+ def field_human_name(field)
135
+ I18n.translate("#{object_model_name}.attributes.#{field}", :count => 1, :default => field.to_s.humanize, :scope => :models)
136
+ end
137
+
138
+ # Returns the name for the given field
139
+ # field_name(:username) => "user[username]"
140
+ # field_name(:number) => "user[telephone_attributes][number]"
141
+ # field_name(:street) => "user[addresses_attributes][0][street]"
142
+ def field_name(field=nil)
143
+ result = []
144
+ if root_form?
145
+ result << object_model_name
146
+ elsif nested_form?
147
+ parent_form = @options[:nested][:parent]
148
+ attributes_name = "#{@options[:nested][:association]}_attributes"
149
+ nested_index = @options[:nested][:index]
150
+ fragment = [parent_form.field_name, "[#{attributes_name}", "]"]
151
+ fragment.insert(2, "][#{nested_index}") if nested_index
152
+ result << fragment
153
+ end
154
+ result << "[#{field}]" unless field.blank?
155
+ result.flatten.join
156
+ end
157
+
158
+ # Returns the id for the given field
159
+ # field_id(:username) => "user_username"
160
+ # field_id(:gender, :male) => "user_gender_male"
161
+ # field_name(:number) => "user_telephone_attributes_number"
162
+ # field_name(:street) => "user_addresses_attributes_0_street"
163
+ def field_id(field=nil, value=nil)
164
+ result = []
165
+ if root_form?
166
+ result << object_model_name
167
+ elsif nested_form?
168
+ parent_form = @options[:nested][:parent]
169
+ attributes_name = "#{@options[:nested][:association]}_attributes"
170
+ nested_index = @options[:nested][:index]
171
+ fragment = [parent_form.field_id, "_#{attributes_name}"]
172
+ fragment.push("_#{nested_index}") if nested_index
173
+ result << fragment
174
+ end
175
+ result << "_#{field}" unless field.blank?
176
+ result << "_#{value}" unless value.blank?
177
+ result.flatten.join
178
+ end
179
+
180
+ # Returns the child object if it exists
181
+ def nested_object_id
182
+ nested_form? && object.respond_to?(:new_record?) && !object.new_record? && object.id
183
+ end
184
+
185
+ # Returns true if this form object is nested in a parent form
186
+ def nested_form?
187
+ @options[:nested] && @options[:nested][:parent] && @options[:nested][:parent].respond_to?(:object)
188
+ end
189
+
190
+ # Returns the value for the object's field
191
+ # field_value(:username) => "Joey"
192
+ def field_value(field)
193
+ @object && @object.respond_to?(field) ? @object.send(field) : ""
194
+ end
195
+
196
+ # explicit_object is either a symbol or a record
197
+ # Returns a new record of the type specified in the object
198
+ def build_object(object_or_symbol)
199
+ object_or_symbol.is_a?(Symbol) ? @template.instance_variable_get("@#{object_or_symbol}") || object_class(object_or_symbol).new : object_or_symbol
200
+ end
201
+
202
+ # Returns the object's models name
203
+ # => user_assignment
204
+ def object_model_name(explicit_object=object)
205
+ explicit_object.is_a?(Symbol) ? explicit_object : explicit_object.class.to_s.underscore.gsub(/\//, '_')
206
+ end
207
+
208
+ # Returns the class type for the given object
209
+ def object_class(explicit_object)
210
+ explicit_object.is_a?(Symbol) ? explicit_object.to_s.camelize.constantize : explicit_object.class
211
+ end
212
+
213
+ # Returns true if this form is the top-level (not nested)
214
+ def root_form?
215
+ !nested_form?
216
+ end
217
+ end # AbstractFormBuilder
218
+ end # FormBuilder
219
+ end # Helpers
220
+ end # Padrino
@@ -0,0 +1,43 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/abstract_form_builder') unless defined?(AbstractFormBuilder)
2
+
3
+ module Padrino
4
+ module Helpers
5
+ module FormBuilder #:nodoc:
6
+ class StandardFormBuilder < AbstractFormBuilder #:nodoc:
7
+
8
+ ##
9
+ # StandardFormBuilder
10
+ #
11
+ # text_field_block(:username, { :class => 'long' }, { :class => 'wide-label' })
12
+ # text_area_block(:summary, { :class => 'long' }, { :class => 'wide-label' })
13
+ # password_field_block(:password, { :class => 'long' }, { :class => 'wide-label' })
14
+ # file_field_block(:photo, { :class => 'long' }, { :class => 'wide-label' })
15
+ # check_box_block(:remember_me, { :class => 'long' }, { :class => 'wide-label' })
16
+ # select_block(:color, :options => ['green', 'black'])
17
+ #
18
+ (self.field_types - [ :hidden_field, :radio_button ]).each do |field_type|
19
+ class_eval <<-EOF
20
+ def #{field_type}_block(field, options={}, label_options={})
21
+ label_options.reverse_merge!(:caption => options.delete(:caption)) if options[:caption]
22
+ field_html = label(field, label_options)
23
+ field_html << #{field_type}(field, options)
24
+ @template.content_tag(:p, field_html)
25
+ end
26
+ EOF
27
+ end
28
+
29
+ # submit_block("Update")
30
+ def submit_block(caption, options={})
31
+ submit_html = self.submit(caption, options)
32
+ @template.content_tag(:p, submit_html)
33
+ end
34
+
35
+ # image_submit_block("submit.png")
36
+ def image_submit_block(source, options={})
37
+ submit_html = self.image_submit(source, options)
38
+ @template.content_tag(:p, submit_html)
39
+ end
40
+ end # StandardFormBuilder
41
+ end # FormBuilder
42
+ end # Helpers
43
+ end # Padrino
@@ -0,0 +1,446 @@
1
+ module Padrino
2
+ module Helpers
3
+ module FormHelpers
4
+ ##
5
+ # Constructs a form for object using given or default form_builder
6
+ #
7
+ # ==== Examples
8
+ #
9
+ # form_for :user, '/register' do |f| ... end
10
+ # form_for @user, '/register', :id => 'register' do |f| ... end
11
+ #
12
+ def form_for(object, url, settings={}, &block)
13
+ form_html = capture_html(builder_instance(object, settings), &block)
14
+ form_tag(url, settings) { form_html }
15
+ end
16
+
17
+ ##
18
+ # Constructs form fields for an object using given or default form_builder
19
+ # Used within an existing form to allow alternate objects within one form
20
+ #
21
+ # ==== Examples
22
+ #
23
+ # fields_for @user.assignment do |assignment| ... end
24
+ # fields_for :assignment do |assigment| ... end
25
+ #
26
+ def fields_for(object, settings={}, &block)
27
+ instance = builder_instance(object, settings)
28
+ fields_html = capture_html(instance, &block)
29
+ fields_html << instance.hidden_field(:id) if instance.send(:nested_object_id)
30
+ concat_content fields_html
31
+ end
32
+
33
+ ##
34
+ # Constructs a form without object based on options
35
+ #
36
+ # ==== Examples
37
+ #
38
+ # form_tag '/register' do ... end
39
+ #
40
+ def form_tag(url, options={}, &block)
41
+ desired_method = options[:method]
42
+ data_method = options.delete(:method) if options[:method].to_s !~ /get|post/i
43
+ options.reverse_merge!(:method => "post", :action => url)
44
+ options[:enctype] = "multipart/form-data" if options.delete(:multipart)
45
+ options["data-remote"] = "true" if options.delete(:remote)
46
+ options["data-method"] = data_method if data_method
47
+ options["accept-charset"] ||= "UTF-8"
48
+ inner_form_html = hidden_form_method_field(desired_method)
49
+ inner_form_html += capture_html(&block)
50
+ concat_content content_tag(:form, inner_form_html, options)
51
+ end
52
+
53
+ ##
54
+ # Returns the hidden method field for 'put' and 'delete' forms
55
+ # Only 'get' and 'post' are allowed within browsers;
56
+ # 'put' and 'delete' are just specified using hidden fields with form action still 'put'.
57
+ #
58
+ # ==== Examples
59
+ #
60
+ # # Generate: <input name="_method" value="delete" />
61
+ # hidden_form_method_field('delete')
62
+ #
63
+ def hidden_form_method_field(desired_method)
64
+ return '' if desired_method.blank? || desired_method.to_s =~ /get|post/i
65
+ hidden_field_tag(:_method, :value => desired_method)
66
+ end
67
+
68
+ ##
69
+ # Constructs a field_set to group fields with given options
70
+ #
71
+ # ==== Examples
72
+ #
73
+ # field_set_tag("Office", :class => 'office-set')
74
+ #
75
+ def field_set_tag(*args, &block)
76
+ options = args.extract_options!
77
+ legend_text = args[0].is_a?(String) ? args.first : nil
78
+ legend_html = legend_text.blank? ? '' : content_tag(:legend, legend_text)
79
+ field_set_content = legend_html + capture_html(&block)
80
+ concat_content content_tag(:fieldset, field_set_content, options)
81
+ end
82
+
83
+ ##
84
+ # Constructs list html for the errors for a given symbol
85
+ #
86
+ # ==== Options
87
+ #
88
+ # :header_tag:: Used for the header of the error div (default: "h2").
89
+ # :id:: The id of the error div (default: "errorExplanation").
90
+ # :class:: The class of the error div (default: "errorExplanation").
91
+ # :object:: The object (or array of objects) for which to display errors,
92
+ # if you need to escape the instance variable convention.
93
+ # :object_name:: The object name to use in the header, or any text that you prefer.
94
+ # If +:object_name+ is not set, the name of the first object will be used.
95
+ # :header_message:: The message in the header of the error div. Pass +nil+
96
+ # or an empty string to avoid the header message altogether. (Default: "X errors
97
+ # prohibited this object from being saved").
98
+ # :message:: The explanation message after the header message and before
99
+ # the error list. Pass +nil+ or an empty string to avoid the explanation message
100
+ # altogether. (Default: "There were problems with the following fields:").
101
+ #
102
+ # ==== Examples
103
+ #
104
+ # error_messages_for :user
105
+ #
106
+ def error_messages_for(*objects)
107
+ options = objects.extract_options!.symbolize_keys
108
+ objects = objects.map {|object_name| object_name.is_a?(Symbol) ? instance_variable_get("@#{object_name}") : object_name }.compact
109
+ count = objects.inject(0) {|sum, object| sum + object.errors.size }
110
+
111
+ unless count.zero?
112
+ html = {}
113
+ [:id, :class, :style].each do |key|
114
+ if options.include?(key)
115
+ value = options[key]
116
+ html[key] = value unless value.blank?
117
+ else
118
+ html[key] = 'field-errors' unless key == :style
119
+ end
120
+ end
121
+
122
+ options[:object_name] ||= objects.first.class
123
+
124
+ I18n.with_options :locale => options[:locale], :scope => [:models, :errors, :template] do |locale|
125
+ header_message = if options.include?(:header_message)
126
+ options[:header_message]
127
+ else
128
+ object_name = options[:object_name].to_s.underscore.gsub(/\//, ' ')
129
+ object_name = I18n.t(:name, :default => object_name.humanize, :scope => [:models, object_name], :count => 1)
130
+ locale.t :header, :count => count, :model => object_name
131
+ end
132
+ message = options.include?(:message) ? options[:message] : locale.t(:body)
133
+ error_messages = objects.map { |object|
134
+ object_name = options[:object_name].to_s.underscore.gsub(/\//, ' ')
135
+ object.errors.map { |f, msg|
136
+ field = I18n.t(f, :default => f.to_s.humanize, :scope => [:models, object_name, :attributes])
137
+ content_tag(:li, "%s %s" % [field, msg])
138
+ }
139
+ }.join
140
+
141
+ contents = ''
142
+ contents << content_tag(options[:header_tag] || :h2, header_message) unless header_message.blank?
143
+ contents << content_tag(:p, message) unless message.blank?
144
+ contents << content_tag(:ul, error_messages)
145
+
146
+ content_tag(:div, contents, html)
147
+ end
148
+ else
149
+ ''
150
+ end
151
+ end
152
+
153
+ ##
154
+ # Returns a string containing the error message attached to the +method+ on the +object+ if one exists.
155
+ #
156
+ # ==== Options
157
+ #
158
+ # :tag:: The tag that enclose your error. (Default 'div')
159
+ # :prepend:: Text to add before error.
160
+ # :append:: Text to add after error.
161
+ #
162
+ # ==== Examples
163
+ #
164
+ # # => <span class="error">can't be blank</div>
165
+ # error_message_on :post, :title
166
+ # error_message_on @post, :title
167
+ #
168
+ # # => <div class="custom" style="border:1px solid red">can't be blank</div>
169
+ # error_message_on :post, :title, :tag => :id, :class => :custom, :style => "border:1px solid red"
170
+ #
171
+ # # => <div class="error">This title can't be blank (or it won't work)</div>
172
+ # error_message_on :post, :title, :prepend => "This title", :append => "(or it won't work)"
173
+ #
174
+ def error_message_on(object, field, options={})
175
+ object = object.is_a?(Symbol) ? instance_variable_get("@#{object}") : object
176
+ error = object.errors[field] rescue nil
177
+ if error
178
+ options.reverse_merge!(:tag => :span, :class => :error)
179
+ tag = options.delete(:tag)
180
+ # Array(error).first is necessary because some orm give us an array others directly a value
181
+ error = [options.delete(:prepend), Array(error).first, options.delete(:append)].compact.join(" ")
182
+ content_tag(tag, error, options)
183
+ else
184
+ ''
185
+ end
186
+ end
187
+
188
+ ##
189
+ # Constructs a label tag from the given options
190
+ #
191
+ # ==== Examples
192
+ #
193
+ # label_tag :username, :class => 'long-label'
194
+ # label_tag :username, :class => 'long-label' do ... end
195
+ #
196
+ def label_tag(name, options={}, &block)
197
+ options.reverse_merge!(:caption => "#{name.to_s.humanize}: ", :for => name)
198
+ caption_text = options.delete(:caption)
199
+ caption_text << "<span class='required'>*</span> " if options.delete(:required)
200
+ if block_given? # label with inner content
201
+ label_content = caption_text + capture_html(&block)
202
+ concat_content(content_tag(:label, label_content, options))
203
+ else # regular label
204
+ content_tag(:label, caption_text, options)
205
+ end
206
+ end
207
+
208
+ ##
209
+ # Constructs a hidden field input from the given options
210
+ #
211
+ # ==== Examples
212
+ #
213
+ # hidden_field_tag :session_key, :value => "__secret__"
214
+ #
215
+ def hidden_field_tag(name, options={})
216
+ options.reverse_merge!(:name => name)
217
+ input_tag(:hidden, options)
218
+ end
219
+
220
+ ##
221
+ # Constructs a text field input from the given options
222
+ #
223
+ # ==== Examples
224
+ #
225
+ # text_field_tag :username, :class => 'long'
226
+ #
227
+ def text_field_tag(name, options={})
228
+ options.reverse_merge!(:name => name)
229
+ input_tag(:text, options)
230
+ end
231
+
232
+ ##
233
+ # Constructs a text area input from the given options
234
+ #
235
+ # ==== Examples
236
+ #
237
+ # text_area_tag :username, :class => 'long', :value => "Demo?"
238
+ #
239
+ def text_area_tag(name, options={})
240
+ options.reverse_merge!(:name => name, :rows => "", :cols => "")
241
+ content_tag(:textarea, options.delete(:value).to_s, options)
242
+ end
243
+
244
+ ##
245
+ # Constructs a password field input from the given options
246
+ #
247
+ # ==== Examples
248
+ #
249
+ # password_field_tag :password, :class => 'long'
250
+ #
251
+ def password_field_tag(name, options={})
252
+ options.reverse_merge!(:name => name)
253
+ input_tag(:password, options)
254
+ end
255
+
256
+ ##
257
+ # Constructs a select from the given options
258
+ #
259
+ # ==== Examples
260
+ #
261
+ # options = [['caption', 'value'], ['Green', 'green1'], ['Blue', 'blue1'], ['Black', "black1"]]
262
+ # options = ['option', 'red', 'yellow' ]
263
+ # select_tag(:favorite_color, :options => ['red', 'yellow'], :selected => 'green1')
264
+ # select_tag(:country, :collection => @countries, :fields => [:name, :code], :include_blank => 'None')
265
+ #
266
+ # # Optgroups can be generated using :grouped_options => (Hash or nested Array)
267
+ # grouped_options = [['Friends',['Yoda',['Obiwan',1]]],['Enemies',['Palpatine',['Darth Vader',3]]]]
268
+ # grouped_options = {'Friends' => ['Yoda',['Obiwan',1]],'Enemies' => ['Palpatine',['Darth Vader',3]]}
269
+ # select_tag(:color, :grouped_options => [['warm',['red','yellow']],['cool',['blue', 'purple']]])
270
+ #
271
+ # # Optgroups can be generated using :grouped_options => (Hash or nested Array)
272
+ # grouped_options = [['Friends',['Yoda',['Obiwan',1]]],['Enemies',['Palpatine',['Darth Vader',3]]]]
273
+ # grouped_options = {'Friends' => ['Yoda',['Obiwan',1]],'Enemies' => ['Palpatine',['Darth Vader',3]]}
274
+ # select_tag(:color, :grouped_options => [['warm',['red','yellow']],['cool',['blue', 'purple']]])
275
+ #
276
+ def select_tag(name, options={})
277
+ options.reverse_merge!(:name => name)
278
+ collection, fields = options.delete(:collection), options.delete(:fields)
279
+ options[:options] = options_from_collection(collection, fields) if collection
280
+ prompt = options.delete(:include_blank)
281
+ select_options_html = if options[:options]
282
+ options_for_select(options.delete(:options), options.delete(:selected))
283
+ elsif options[:grouped_options]
284
+ grouped_options_for_select(options.delete(:grouped_options), options.delete(:selected), prompt)
285
+ end
286
+ select_options_html = select_options_html.unshift(blank_option(prompt)) if select_options_html.is_a?(Array)
287
+ options.merge!(:name => "#{options[:name]}[]") if options[:multiple]
288
+ content_tag(:select, select_options_html, options)
289
+ end
290
+
291
+ ##
292
+ # Constructs a check_box from the given options
293
+ #
294
+ # ==== Examples
295
+ #
296
+ # check_box_tag :remember_me, :value => 'Yes'
297
+ #
298
+ def check_box_tag(name, options={})
299
+ options.reverse_merge!(:name => name, :value => '1')
300
+ input_tag(:checkbox, options)
301
+ end
302
+
303
+ ##
304
+ # Constructs a radio_button from the given options
305
+ #
306
+ # ==== Examples
307
+ #
308
+ # radio_button_tag :remember_me, :value => 'true'
309
+ #
310
+ def radio_button_tag(name, options={})
311
+ options.reverse_merge!(:name => name)
312
+ input_tag(:radio, options)
313
+ end
314
+
315
+ ##
316
+ # Constructs a file field input from the given options
317
+ #
318
+ # ==== Examples
319
+ #
320
+ # file_field_tag :photo, :class => 'long'
321
+ #
322
+ def file_field_tag(name, options={})
323
+ options.reverse_merge!(:name => name)
324
+ input_tag(:file, options)
325
+ end
326
+
327
+ ##
328
+ # Constructs a submit button from the given options
329
+ #
330
+ # ==== Examples
331
+ #
332
+ # submit_tag "Create", :class => 'success'
333
+ #
334
+ def submit_tag(caption="Submit", options={})
335
+ options.reverse_merge!(:value => caption)
336
+ input_tag(:submit, options)
337
+ end
338
+
339
+ ##
340
+ # Constructs a button input from the given options
341
+ #
342
+ # ==== Examples
343
+ #
344
+ # button_tag "Cancel", :class => 'clear'
345
+ #
346
+ def button_tag(caption, options = {})
347
+ options.reverse_merge!(:value => caption)
348
+ input_tag(:button, options)
349
+ end
350
+
351
+ # Constructs a submit button from the given options
352
+ #
353
+ # ==== Examples
354
+ #
355
+ # submit_tag "Create", :class => 'success'
356
+ #
357
+ def image_submit_tag(source, options={})
358
+ options.reverse_merge!(:src => image_path(source))
359
+ input_tag(:image, options)
360
+ end
361
+
362
+ ##
363
+ # Returns an array of option items for a select field based on the given collection
364
+ # fields is an array containing the fields to display from each item in the collection
365
+ #
366
+ def options_from_collection(collection, fields)
367
+ collection.map { |item| [ item.send(fields.first), item.send(fields.last) ] }
368
+ end
369
+
370
+ #
371
+ # Returns the options tags for a select based on the given option items
372
+ #
373
+ def options_for_select(option_items, selected_value=nil)
374
+ return '' if option_items.blank?
375
+ option_items.map do |caption, value|
376
+ value ||= caption
377
+ content_tag(:option, caption, :value => value, :selected => option_is_selected?(value, caption, selected_value))
378
+ end
379
+ end
380
+
381
+ #
382
+ # Returns the optgroups with options tags for a select based on the given :grouped_options items
383
+ #
384
+ def grouped_options_for_select(collection,selected=nil,prompt=false)
385
+ if collection.is_a?(Hash)
386
+ collection.map do |key, value|
387
+ content_tag :optgroup, :label => key do
388
+ options_for_select(value, selected)
389
+ end
390
+ end
391
+ elsif collection.is_a?(Array)
392
+ collection.map do |optgroup|
393
+ content_tag :optgroup, :label => optgroup.first do
394
+ options_for_select(optgroup.last, selected)
395
+ end
396
+ end
397
+ end
398
+ end
399
+
400
+ #
401
+ # Returns the blank option serving as a prompt if passed
402
+ #
403
+ def blank_option(prompt)
404
+ return unless prompt
405
+ case prompt
406
+ when String then content_tag(:option, prompt, :value => '')
407
+ when Array then content_tag(:option, prompt.first, :value => prompt.last)
408
+ else content_tag(:option, '', :value => '')
409
+ end
410
+ end
411
+
412
+ private
413
+ ##
414
+ # Returns the FormBuilder class to use based on all available setting sources
415
+ # If explicitly defined, returns that, otherwise returns defaults.
416
+ #
417
+ # configured_form_builder_class(nil) => StandardFormBuilder
418
+ #
419
+ def configured_form_builder_class(explicit_builder=nil)
420
+ default_builder = self.respond_to?(:settings) && self.settings.default_builder
421
+ configured_builder = explicit_builder || default_builder || 'StandardFormBuilder'
422
+ configured_builder = "Padrino::Helpers::FormBuilder::#{configured_builder}".constantize if configured_builder.is_a?(String)
423
+ configured_builder
424
+ end
425
+
426
+ ##
427
+ # Returns an initialized builder instance for the given object and settings
428
+ #
429
+ # builder_instance(@account, :nested => { ... }) => <FormBuilder>
430
+ #
431
+ def builder_instance(object, settings={})
432
+ builder_class = configured_form_builder_class(settings.delete(:builder))
433
+ builder_class.new(self, object, settings)
434
+ end
435
+
436
+ ##
437
+ # Returns whether the option should be selected or not
438
+ #
439
+ def option_is_selected?(value, caption, selected_values)
440
+ Array(selected_values).any? do |selected|
441
+ [value.to_s, caption.to_s].include?(selected.to_s)
442
+ end
443
+ end
444
+ end # FormHelpers
445
+ end # Helpers
446
+ end # Padrino