formtastic 3.1.2 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (135) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +1 -0
  3. data/.github/workflows/test.yml +61 -0
  4. data/.gitignore +3 -2
  5. data/CHANGELOG.md +52 -0
  6. data/Gemfile.lock +105 -0
  7. data/MIT-LICENSE +1 -1
  8. data/{README.textile → README.md} +178 -167
  9. data/RELEASE_PROCESS +3 -1
  10. data/Rakefile +20 -1
  11. data/app/assets/stylesheets/formtastic.css +1 -1
  12. data/bin/appraisal +8 -0
  13. data/formtastic.gemspec +10 -16
  14. data/gemfiles/rails_5.2/Gemfile +5 -0
  15. data/gemfiles/rails_6.0/Gemfile +5 -0
  16. data/gemfiles/rails_6.1/Gemfile +5 -0
  17. data/gemfiles/rails_edge/Gemfile +13 -0
  18. data/lib/formtastic.rb +9 -11
  19. data/lib/formtastic/actions.rb +6 -3
  20. data/lib/formtastic/deprecation.rb +1 -38
  21. data/lib/formtastic/engine.rb +3 -1
  22. data/lib/formtastic/form_builder.rb +11 -24
  23. data/lib/formtastic/helpers.rb +1 -1
  24. data/lib/formtastic/helpers/action_helper.rb +1 -48
  25. data/lib/formtastic/helpers/enum.rb +13 -0
  26. data/lib/formtastic/helpers/errors_helper.rb +2 -2
  27. data/lib/formtastic/helpers/fieldset_wrapper.rb +13 -9
  28. data/lib/formtastic/helpers/form_helper.rb +1 -1
  29. data/lib/formtastic/helpers/input_helper.rb +23 -77
  30. data/lib/formtastic/helpers/inputs_helper.rb +27 -22
  31. data/lib/formtastic/i18n.rb +1 -1
  32. data/lib/formtastic/inputs.rb +32 -29
  33. data/lib/formtastic/inputs/base/choices.rb +1 -1
  34. data/lib/formtastic/inputs/base/collections.rb +43 -10
  35. data/lib/formtastic/inputs/base/database.rb +7 -2
  36. data/lib/formtastic/inputs/base/errors.rb +4 -4
  37. data/lib/formtastic/inputs/base/hints.rb +1 -1
  38. data/lib/formtastic/inputs/base/html.rb +7 -6
  39. data/lib/formtastic/inputs/base/naming.rb +4 -4
  40. data/lib/formtastic/inputs/base/options.rb +2 -3
  41. data/lib/formtastic/inputs/base/timeish.rb +5 -1
  42. data/lib/formtastic/inputs/base/validations.rb +38 -12
  43. data/lib/formtastic/inputs/check_boxes_input.rb +13 -5
  44. data/lib/formtastic/inputs/color_input.rb +0 -1
  45. data/lib/formtastic/inputs/country_input.rb +3 -1
  46. data/lib/formtastic/inputs/radio_input.rb +20 -0
  47. data/lib/formtastic/inputs/select_input.rb +29 -1
  48. data/lib/formtastic/inputs/time_zone_input.rb +16 -6
  49. data/lib/formtastic/localizer.rb +20 -22
  50. data/lib/formtastic/namespaced_class_finder.rb +1 -1
  51. data/lib/formtastic/version.rb +1 -1
  52. data/lib/generators/formtastic/form/form_generator.rb +1 -1
  53. data/lib/generators/formtastic/input/input_generator.rb +46 -0
  54. data/lib/generators/templates/formtastic.rb +14 -13
  55. data/lib/generators/templates/input.rb +19 -0
  56. data/sample/basic_inputs.html +1 -1
  57. data/script/integration-template.rb +74 -0
  58. data/script/integration.sh +19 -0
  59. data/spec/action_class_finder_spec.rb +1 -1
  60. data/spec/actions/button_action_spec.rb +8 -8
  61. data/spec/actions/generic_action_spec.rb +60 -60
  62. data/spec/actions/input_action_spec.rb +7 -7
  63. data/spec/actions/link_action_spec.rb +10 -10
  64. data/spec/builder/custom_builder_spec.rb +37 -21
  65. data/spec/builder/error_proc_spec.rb +4 -4
  66. data/spec/builder/semantic_fields_for_spec.rb +27 -27
  67. data/spec/fast_spec_helper.rb +12 -0
  68. data/spec/generators/formtastic/form/form_generator_spec.rb +25 -25
  69. data/spec/generators/formtastic/input/input_generator_spec.rb +124 -0
  70. data/spec/generators/formtastic/install/install_generator_spec.rb +9 -9
  71. data/spec/helpers/action_helper_spec.rb +328 -10
  72. data/spec/helpers/actions_helper_spec.rb +17 -17
  73. data/spec/helpers/form_helper_spec.rb +37 -37
  74. data/spec/helpers/input_helper_spec.rb +975 -2
  75. data/spec/helpers/inputs_helper_spec.rb +120 -105
  76. data/spec/helpers/reflection_helper_spec.rb +3 -3
  77. data/spec/helpers/semantic_errors_helper_spec.rb +22 -22
  78. data/spec/i18n_spec.rb +26 -26
  79. data/spec/input_class_finder_spec.rb +1 -1
  80. data/spec/inputs/base/collections_spec.rb +76 -0
  81. data/spec/inputs/base/validations_spec.rb +480 -0
  82. data/spec/inputs/boolean_input_spec.rb +55 -55
  83. data/spec/inputs/check_boxes_input_spec.rb +155 -108
  84. data/spec/inputs/color_input_spec.rb +51 -63
  85. data/spec/inputs/country_input_spec.rb +20 -20
  86. data/spec/inputs/custom_input_spec.rb +2 -6
  87. data/spec/inputs/datalist_input_spec.rb +1 -1
  88. data/spec/inputs/date_picker_input_spec.rb +42 -42
  89. data/spec/inputs/date_select_input_spec.rb +51 -37
  90. data/spec/inputs/datetime_picker_input_spec.rb +46 -46
  91. data/spec/inputs/datetime_select_input_spec.rb +53 -37
  92. data/spec/inputs/email_input_spec.rb +5 -5
  93. data/spec/inputs/file_input_spec.rb +6 -6
  94. data/spec/inputs/hidden_input_spec.rb +18 -18
  95. data/spec/inputs/include_blank_spec.rb +8 -8
  96. data/spec/inputs/label_spec.rb +20 -20
  97. data/spec/inputs/number_input_spec.rb +112 -112
  98. data/spec/inputs/password_input_spec.rb +5 -5
  99. data/spec/inputs/phone_input_spec.rb +5 -5
  100. data/spec/inputs/placeholder_spec.rb +5 -5
  101. data/spec/inputs/radio_input_spec.rb +84 -58
  102. data/spec/inputs/range_input_spec.rb +66 -66
  103. data/spec/inputs/readonly_spec.rb +50 -0
  104. data/spec/inputs/search_input_spec.rb +5 -5
  105. data/spec/inputs/select_input_spec.rb +149 -93
  106. data/spec/inputs/string_input_spec.rb +23 -23
  107. data/spec/inputs/text_input_spec.rb +16 -16
  108. data/spec/inputs/time_picker_input_spec.rb +43 -43
  109. data/spec/inputs/time_select_input_spec.rb +67 -54
  110. data/spec/inputs/time_zone_input_spec.rb +54 -28
  111. data/spec/inputs/url_input_spec.rb +5 -5
  112. data/spec/inputs/with_options_spec.rb +7 -7
  113. data/spec/localizer_spec.rb +17 -17
  114. data/spec/namespaced_class_finder_spec.rb +2 -2
  115. data/spec/schema.rb +21 -0
  116. data/spec/spec_helper.rb +165 -253
  117. data/spec/support/custom_macros.rb +72 -75
  118. data/spec/support/shared_examples.rb +0 -1232
  119. data/spec/support/test_environment.rb +23 -9
  120. metadata +69 -176
  121. data/.travis.yml +0 -29
  122. data/Appraisals +0 -29
  123. data/CHANGELOG +0 -31
  124. data/DEPRECATIONS +0 -49
  125. data/gemfiles/rails_3.2.gemfile +0 -7
  126. data/gemfiles/rails_4.0.4.gemfile +0 -7
  127. data/gemfiles/rails_4.1.gemfile +0 -7
  128. data/gemfiles/rails_4.2.gemfile +0 -7
  129. data/gemfiles/rails_4.gemfile +0 -7
  130. data/gemfiles/rails_edge.gemfile +0 -10
  131. data/lib/formtastic/util.rb +0 -57
  132. data/spec/helpers/namespaced_action_helper_spec.rb +0 -43
  133. data/spec/helpers/namespaced_input_helper_spec.rb +0 -36
  134. data/spec/support/deferred_garbage_collection.rb +0 -21
  135. data/spec/util_spec.rb +0 -66
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: cb44ea01df970135604cdddd0ac7b762ea56077f915810c4c8fe6be3487cafa3
4
+ data.tar.gz: 18630a8282b76e40d0c6e9faad19f99112dfd9e22ba22e7b025d8730ebf26ace
5
+ SHA512:
6
+ metadata.gz: 73a3ad17e91765150e4e15e03d3031f5b9efd975a09bbb21c7f404709b7d2462e9cf16c708beaf2745b783def3a631ca1b3bd47278d79c16012d79ba1f549fc0
7
+ data.tar.gz: d418a7e65f928dedfd36627c3ece7c4fe7e371984500ddc4bcb6c5929087264541476c469be6520270000a0e8348bc2cd41415e94d46c86da2e48021bf54d4be
data/.gitattributes ADDED
@@ -0,0 +1 @@
1
+ CHANGELOG merge=union
@@ -0,0 +1,61 @@
1
+ name: test
2
+
3
+ on:
4
+ push:
5
+ pull_request:
6
+
7
+ jobs:
8
+ test:
9
+ runs-on: ubuntu-20.04
10
+
11
+ strategy:
12
+ fail-fast: false
13
+
14
+ matrix:
15
+ gemfile:
16
+ - gemfiles/rails_5.2/Gemfile
17
+ - gemfiles/rails_6.0/Gemfile
18
+ - gemfiles/rails_6.1/Gemfile
19
+ - gemfiles/rails_edge/Gemfile
20
+
21
+ ruby:
22
+ - 2.4.10
23
+ - 2.5.8
24
+ - 2.6.6
25
+ - 2.7.2
26
+ - 3.0.0
27
+
28
+ exclude:
29
+ - ruby: 2.4.10
30
+ gemfile: gemfiles/rails_6.0/Gemfile
31
+
32
+ - ruby: 2.4.10
33
+ gemfile: gemfiles/rails_6.1/Gemfile
34
+
35
+ - ruby: 2.4.10
36
+ gemfile: gemfiles/rails_edge/Gemfile
37
+
38
+ - ruby: 3.0.0
39
+ gemfile: gemfiles/rails_5.2/Gemfile
40
+
41
+ env:
42
+ BUNDLE_GEMFILE: ${{ matrix.gemfile }}
43
+
44
+ steps:
45
+ - uses: actions/checkout@v2
46
+
47
+ - uses: actions/setup-node@v2
48
+ with:
49
+ node-version: 11
50
+
51
+ - name: Set up Ruby
52
+ uses: ruby/setup-ruby@v1
53
+ with:
54
+ ruby-version: ${{ matrix.ruby }}
55
+ bundler-cache: true
56
+
57
+ - name: Run tests
58
+ run: |
59
+ bundle exec rake spec
60
+ script/integration.sh
61
+ continue-on-error: ${{ matrix.gemfile == 'gemfiles/rails_edge/Gemfile' }}
data/.gitignore CHANGED
@@ -9,9 +9,10 @@ pkg
9
9
  log/*
10
10
  .rvmrc
11
11
  .ruby-version
12
+ \.ruby-gemset
12
13
  .bundle
13
- Gemfile.lock
14
14
  .yardoc
15
15
  doc/
16
16
  tmp
17
- gemfiles/*.lock
17
+ gemfiles/*/Gemfile.lock
18
+ /dummy/
data/CHANGELOG.md ADDED
@@ -0,0 +1,52 @@
1
+ ## master / 4.0.0
2
+ * Fixed default_columns_for_object when object has non-standard foreign keys (#1241)
3
+ * Fixed missing constants in production (#911)
4
+ * Removed support for Rails 3 and 4.0 (#1108)
5
+ * Removed deprecated input/action finder methods (#1139)
6
+ * Changed boolean label padding to margin (#1202)
7
+ * Added mapping hstore column to text input (#1203)
8
+ * Added support for Rails 5 Attributes API (#1188)
9
+ * Changed required Ruby version to >= 2.0 (#1210)
10
+ * Default to input types text for json & jsonb, string for citext columns (#1229)
11
+ * Allow symbols for numericality options (#1258)
12
+ * Support for rubies under 2.4.0 has been dropped (#1292)
13
+ * Support for Rails under 5.2.0 has been dropped (#1293)
14
+ * Support for Rails 6.0 has been added (#1300)
15
+ * Support for Rails 6.1 has been added (#1324)
16
+ * Support for Ruby 3 has been added (#1323)
17
+
18
+ ## 3.1.2
19
+
20
+ * Fixed that we specified 4.0.4 instead of 4.1 in the Rails version deprecation message
21
+
22
+ ## 3.1.1
23
+
24
+ * Fixed class custom input & action class loading in test environments
25
+ * Added documentation of custom input & action class finders
26
+ * Added a link to documentation & wiki from custom class deprecation warnings
27
+
28
+ ## 3.1.0
29
+
30
+ * Performance and documentation improvements
31
+
32
+ ## 3.1.0.rc2
33
+
34
+ * Deprecated :member_value and :member_label options
35
+
36
+ ## 3.1.0.rc1
37
+
38
+ * Deprecated support for Rails version < 4.1.0
39
+ * Fixed synchronization issues with custom_namespace configuration
40
+ * Fixed bug where boolean (checkbox) inputs were not being correctly checked (also in 2.3.1)
41
+ * Fixed (silenced) Rails 5 deprecation on column_for_attribute that we're handling fine
42
+ * Added new DatalistInput (:as => :datalist) for HTML5 datalists
43
+ * Added configurable namespaces for custom inputs
44
+ * Various performance and documentation improvements
45
+
46
+ ---
47
+
48
+ See 3.0-stable branch for 3.0.x changes
49
+ https://github.com/formtastic/formtastic/blob/3.0-stable/CHANGELOG
50
+
51
+ See 2.3-stable branch for 2.3.x and earlier releases
52
+ https://github.com/formtastic/formtastic/blob/2.3-stable/CHANGELOG
data/Gemfile.lock ADDED
@@ -0,0 +1,105 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ formtastic (4.0.0.rc1)
5
+ actionpack (>= 5.2.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ actionpack (6.1.1)
11
+ actionview (= 6.1.1)
12
+ activesupport (= 6.1.1)
13
+ rack (~> 2.0, >= 2.0.9)
14
+ rack-test (>= 0.6.3)
15
+ rails-dom-testing (~> 2.0)
16
+ rails-html-sanitizer (~> 1.0, >= 1.2.0)
17
+ actionview (6.1.1)
18
+ activesupport (= 6.1.1)
19
+ builder (~> 3.1)
20
+ erubi (~> 1.4)
21
+ rails-dom-testing (~> 2.0)
22
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
23
+ activesupport (6.1.1)
24
+ concurrent-ruby (~> 1.0, >= 1.0.2)
25
+ i18n (>= 1.6, < 2)
26
+ minitest (>= 5.1)
27
+ tzinfo (~> 2.0)
28
+ zeitwerk (~> 2.3)
29
+ ammeter (1.1.4)
30
+ activesupport (>= 3.0)
31
+ railties (>= 3.0)
32
+ rspec-rails (>= 2.2)
33
+ builder (3.2.4)
34
+ concurrent-ruby (1.1.8)
35
+ crass (1.0.6)
36
+ diff-lcs (1.3)
37
+ erubi (1.10.0)
38
+ i18n (1.8.7)
39
+ concurrent-ruby (~> 1.0)
40
+ loofah (2.9.0)
41
+ crass (~> 1.0.2)
42
+ nokogiri (>= 1.5.9)
43
+ method_source (1.0.0)
44
+ mini_portile2 (2.5.0)
45
+ minitest (5.14.3)
46
+ nokogiri (1.11.1)
47
+ mini_portile2 (~> 2.5.0)
48
+ racc (~> 1.4)
49
+ racc (1.5.2)
50
+ rack (2.2.3)
51
+ rack-test (1.1.0)
52
+ rack (>= 1.0, < 3)
53
+ rails-dom-testing (2.0.3)
54
+ activesupport (>= 4.2.0)
55
+ nokogiri (>= 1.6)
56
+ rails-html-sanitizer (1.3.0)
57
+ loofah (~> 2.3)
58
+ railties (6.1.1)
59
+ actionpack (= 6.1.1)
60
+ activesupport (= 6.1.1)
61
+ method_source
62
+ rake (>= 0.8.7)
63
+ thor (~> 1.0)
64
+ rake (13.0.3)
65
+ rspec-core (3.9.2)
66
+ rspec-support (~> 3.9.3)
67
+ rspec-dom-testing (0.1.0)
68
+ rails-dom-testing (>= 1.0, < 3)
69
+ rspec-expectations (~> 3.0)
70
+ rspec-expectations (3.9.2)
71
+ diff-lcs (>= 1.2.0, < 2.0)
72
+ rspec-support (~> 3.9.0)
73
+ rspec-mocks (3.9.1)
74
+ diff-lcs (>= 1.2.0, < 2.0)
75
+ rspec-support (~> 3.9.0)
76
+ rspec-rails (3.9.1)
77
+ actionpack (>= 3.0)
78
+ activesupport (>= 3.0)
79
+ railties (>= 3.0)
80
+ rspec-core (~> 3.9.0)
81
+ rspec-expectations (~> 3.9.0)
82
+ rspec-mocks (~> 3.9.0)
83
+ rspec-support (~> 3.9.0)
84
+ rspec-support (3.9.3)
85
+ sqlite3 (1.4.2)
86
+ thor (1.1.0)
87
+ tzinfo (2.0.4)
88
+ concurrent-ruby (~> 1.0)
89
+ yard (0.9.25)
90
+ zeitwerk (2.4.2)
91
+
92
+ PLATFORMS
93
+ ruby
94
+
95
+ DEPENDENCIES
96
+ ammeter (~> 1.1.3)
97
+ formtastic!
98
+ rake
99
+ rspec-dom-testing (>= 0.1.0)
100
+ rspec-rails (~> 3.4)
101
+ sqlite3 (~> 1.4)
102
+ yard (~> 0.9.20)
103
+
104
+ BUNDLED WITH
105
+ 2.1.4
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2008-2010 Justin French
1
+ Copyright (c) 2008-2021
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -1,36 +1,31 @@
1
- h1. Formtastic
1
+ # Formtastic
2
2
 
3
- !https://travis-ci.org/justinfrench/formtastic.png?branch=master!:https://travis-ci.org/justinfrench/formtastic
4
- !http://inch-ci.org/github/justinfrench/formtastic.png!:http://inch-ci.org/github/justinfrench/formtastic
5
- !https://codeclimate.com/github/justinfrench/formtastic.png!:https://codeclimate.com/github/justinfrench/formtastic
6
- !https://badge.fury.io/rb/formtastic.png!:http://badge.fury.io/rb/formtastic
7
- !https://gemnasium.com/justinfrench/formtastic.png!:https://gemnasium.com/justinfrench/formtastic
3
+ [![Build Status](https://github.com/formtastic/formtastic/workflows/test/badge.svg)](https://github.com/formtastic/formtastic/actions)
4
+ [![Inline docs](https://inch-ci.org/github/justinfrench/formtastic.svg?branch=master)](https://inch-ci.org/github/justinfrench/formtastic)
5
+ [![Code Climate](https://codeclimate.com/github/formtastic/formtastic/badges/gpa.svg)](https://codeclimate.com/github/formtastic/formtastic)
6
+ [![Gem Version](https://badge.fury.io/rb/formtastic.svg)](https://badge.fury.io/rb/formtastic)
8
7
 
9
8
  Formtastic is a Rails FormBuilder DSL (with some other goodies) to make it far easier to create beautiful, semantically rich, syntactically awesome, readily stylable and wonderfully accessible HTML forms in your Rails applications.
10
9
 
10
+ ## Documentation & Support
11
11
 
12
- h2. Documentation & Support
12
+ * [Documentation is available on rdoc.info](https://rdoc.info/projects/formtastic/formtastic)
13
+ * [We track issues & bugs on GitHub](https://github.com/formtastic/formtastic/issues)
14
+ * [We have a wiki on GitHub](https://github.com/formtastic/formtastic/wiki)
15
+ * [StackOverflow can help](https://stackoverflow.com/questions/tagged/formtastic)
13
16
 
14
- * "Documentation is available on rdoc.info":http://rdoc.info/projects/justinfrench/formtastic
15
- * "We track issues & bugs on GitHub":http://github.com/justinfrench/formtastic/issues
16
- * "We have a wiki on GitHub":http://github.com/justinfrench/formtastic/wiki
17
- * "StackOverflow can help":http://stackoverflow.com/questions/tagged/formtastic
18
- * "Follow @formtastic on Twitter for news & updates":http://twitter.com/formtastic
17
+ ## Compatibility
19
18
 
20
-
21
- h2. Compatibility
22
-
23
- * Formtastic 4 will require Rails 4.1
19
+ * Formtastic 4 requires Rails 5.2 and Ruby 2.5 minimum
24
20
  * Formtastic 3 requires Rails 3.2.13 minimum
25
21
  * Formtastic 2 requires Rails 3
26
22
  * Formtastic, much like Rails, is very ActiveRecord-centric. Many are successfully using other ActiveModel-like ORMs and objects (DataMapper, MongoMapper, Mongoid, Authlogic, Devise...) but we're not guaranteeing full compatibility at this stage. Patches are welcome!
27
23
 
28
-
29
- h2. The Story
24
+ ## The Story
30
25
 
31
26
  One day, I finally had enough, so I opened up my text editor, and wrote a DSL for how I'd like to author forms:
32
27
 
33
- <pre>
28
+ ```erb
34
29
  <%= semantic_form_for @article do |f| %>
35
30
 
36
31
  <%= f.inputs :name => "Basic" do %>
@@ -60,15 +55,15 @@ One day, I finally had enough, so I opened up my text editor, and wrote a DSL fo
60
55
  <% end %>
61
56
 
62
57
  <% end %>
63
- </pre>
58
+ ```
64
59
 
65
- I also wrote the accompanying HTML output I expected, favoring something very similar to the fieldsets, lists and other semantic elements Aaron Gustafson presented in "Learning to Love Forms":http://www.slideshare.net/AaronGustafson/learning-to-love-forms-web-directions-south-07, hacking together enough Ruby to prove it could be done.
60
+ I also wrote the accompanying HTML output I expected, favoring something very similar to the fieldsets, lists and other semantic elements Aaron Gustafson presented in [Learning to Love Forms](https://www.slideshare.net/AaronGustafson/learning-to-love-forms-webvisions-07), hacking together enough Ruby to prove it could be done.
66
61
 
67
62
 
68
- h2. It's awesome because...
63
+ ## It's awesome because...
69
64
 
70
- * It can handle @belongs_to@ associations (like Post belongs_to :author), rendering a select or set of radio inputs with choices from the parent model.
71
- * It can handle @has_many@ and @has_and_belongs_to_many@ associations (like: Post has_many :tags), rendering a multi-select with choices from the child models.
65
+ * It can handle `belongs_to` associations (like Post belongs_to :author), rendering a select or set of radio inputs with choices from the parent model.
66
+ * It can handle `has_many` and `has_and_belongs_to_many` associations (like: Post has_many :tags), rendering a multi-select with choices from the child models.
72
67
  * It's Rails 3/4 compatible (including nested forms).
73
68
  * It has internationalization (I18n)!
74
69
  * It's _really_ quick to get started with a basic form in place (4 lines), then go back to add in more detail if you need it.
@@ -80,7 +75,7 @@ h2. It's awesome because...
80
75
  * It has growing HTML5 support (new inputs like email/phone/search, new attributes like required/min/max/step/placeholder)
81
76
 
82
77
 
83
- h2. Opinions
78
+ ## Opinions
84
79
 
85
80
  * It should be easier to do things the right way than the wrong way.
86
81
  * Sometimes _more mark-up_ is better.
@@ -88,82 +83,82 @@ h2. Opinions
88
83
  * Make the common things we do easy, yet ensure uncommon things are still possible.
89
84
 
90
85
 
91
- h2. Installation
86
+ ## Installation
92
87
 
93
88
  Simply add Formtastic to your Gemfile and bundle it up:
94
89
 
95
- <pre>
96
- gem 'formtastic', '~> 3.0'
97
- </pre>
90
+ ```ruby
91
+ gem 'formtastic', '~> 4.0'
92
+ ```
98
93
 
99
94
  Run the installation generator:
100
95
 
101
- <pre lang=shell>
102
- $ rails generate formtastic:install
103
- </pre>
96
+ ```shell
97
+ $ rails generate formtastic:install
98
+ ```
104
99
 
105
100
 
106
- h2. Stylesheets
101
+ ## Stylesheets
107
102
 
108
103
  A proof-of-concept set of stylesheets are provided which you can include in your layout. Customization is best achieved by overriding these styles in an additional stylesheet.
109
104
 
110
105
  Rails 3.1 introduces an asset pipeline that allows plugins like Formtastic to serve their own Stylesheets, Javascripts, etc without having to run generators that copy them across to the host application. Formtastic makes three stylesheets available as an Engine, you just need to require them in your global stylesheets.
111
106
 
112
- <pre>
107
+ ```css
113
108
  # app/assets/stylesheets/application.css
114
109
  *= require formtastic
115
110
  *= require my_formtastic_changes
116
- </pre>
111
+ ```
117
112
 
118
- Conditional stylesheets need to be compiled separately to prevent them being bundled and included with other application styles. Remove @require_tree .@ from application.css and specify required stylesheets individually.
113
+ Conditional stylesheets need to be compiled separately to prevent them being bundled and included with other application styles. Remove `require_tree .` from application.css and specify required stylesheets individually.
119
114
 
120
- <pre>
115
+ ```css
121
116
  # app/assets/stylesheets/ie6.css
122
117
  *= require formtastic_ie6
123
118
 
124
119
  # app/assets/stylesheets/ie7.css
125
120
  *= require formtastic_ie7
126
- </pre>
121
+ ```
127
122
 
128
- <pre>
123
+ ```erb
129
124
  # app/views/layouts/application.html.erb
130
125
  <%= stylesheet_link_tag 'application' %>
131
126
  <!--[if IE 6]><%= stylesheet_link_tag 'ie6' %><![endif]-->
132
127
  <!--[if IE 7]><%= stylesheet_link_tag 'ie7' %><![endif]-->
133
- </pre>
128
+ ```
134
129
 
135
- <pre>
130
+ ```ruby
136
131
  # config/environments/production.rb
137
132
  config.assets.precompile += %w( ie6.css ie7.css )
138
- </pre>
133
+ ```
139
134
 
140
- h2. Usage
135
+ ## Usage
141
136
 
142
137
  Forms are really boring to code... you want to get onto the good stuff as fast as possible.
143
138
 
144
- This renders a set of inputs (one for _most_ columns in the database table, and one for each ActiveRecord @belongs_to@-association), followed by default action buttons (an input submit button):
139
+ This renders a set of inputs (one for _most_ columns in the database table, and one for each ActiveRecord `belongs_to`-association), followed by default action buttons (an input submit button):
145
140
 
146
- <pre>
141
+ ```erb
147
142
  <%= semantic_form_for @user do |f| %>
148
143
  <%= f.inputs %>
149
144
  <%= f.actions %>
150
145
  <% end %>
151
- </pre>
146
+ ```
152
147
 
153
148
  This is a great way to get something up fast, but like scaffolding, it's *not recommended for production*. Don't be so lazy!
154
149
 
155
- To specify the order of the fields, skip some of the fields or even add in fields that Formtastic couldn't infer. You can pass in a list of field names to @inputs@ and list of action names to @actions@:
150
+ To specify the order of the fields, skip some of the fields or even add in fields that Formtastic couldn't infer. You can pass in a list of field names to `inputs` and list of action names to `actions`:
156
151
 
157
- <pre>
152
+ ```erb
158
153
  <%= semantic_form_for @user do |f| %>
159
154
  <%= f.inputs :title, :body, :section, :categories, :created_at %>
160
155
  <%= f.actions :submit, :cancel %>
161
156
  <% end %>
162
- </pre>
157
+ ```
163
158
 
164
- You probably want control over the input type Formtastic uses for each field. You can expand the @inputs@ and @actions@ to block helper format and use the @:as@ option to specify an exact input type:
159
+ You probably want control over the input type Formtastic uses for each field. You can expand the `inputs` and `actions` to block helper format and use the `:as` option to specify an exact input type:
165
160
 
166
- <pre>
161
+ ```erb
167
162
  <%= semantic_form_for @post do |f| %>
168
163
  <%= f.inputs do %>
169
164
  <%= f.input :title %>
@@ -177,11 +172,11 @@ You probably want control over the input type Formtastic uses for each field. Yo
177
172
  <%= f.action :cancel, :as => :link %>
178
173
  <% end %>
179
174
  <% end %>
180
- </pre>
175
+ ```
181
176
 
182
177
  If you want to customize the label text, or render some hint text below the field, specify which fields are required/optional, or break the form into two fieldsets, the DSL is pretty comprehensive:
183
178
 
184
- <pre>
179
+ ```erb
185
180
  <%= semantic_form_for @post do |f| %>
186
181
  <%= f.inputs "Basic", :id => "basic" do %>
187
182
  <%= f.input :title %>
@@ -198,17 +193,17 @@ If you want to customize the label text, or render some hint text below the fiel
198
193
  <%= f.action :submit %>
199
194
  <% end %>
200
195
  <% end %>
201
- </pre>
196
+ ```
202
197
 
203
198
  You can create forms for nested resources:
204
199
 
205
- <pre>
200
+ ```erb
206
201
  <%= semantic_form_for [@author, @post] do |f| %>
207
- </pre>
202
+ ```
208
203
 
209
- Nested forms are also supported (don't forget your models need to be setup correctly with @accepts_nested_attributes_for@). You can do it in the Rails way:
204
+ Nested forms are also supported (don't forget your models need to be setup correctly with `accepts_nested_attributes_for`). You can do it in the Rails way:
210
205
 
211
- <pre>
206
+ ```erb
212
207
  <%= semantic_form_for @post do |f| %>
213
208
  <%= f.inputs :title, :body, :created_at %>
214
209
  <%= f.semantic_fields_for :author do |author| %>
@@ -216,41 +211,41 @@ Nested forms are also supported (don't forget your models need to be setup corre
216
211
  <% end %>
217
212
  <%= f.actions %>
218
213
  <% end %>
219
- </pre>
214
+ ```
220
215
 
221
- Or the Formtastic way with the @:for@ option:
216
+ Or the Formtastic way with the `:for` option:
222
217
 
223
- <pre>
218
+ ```erb
224
219
  <%= semantic_form_for @post do |f| %>
225
220
  <%= f.inputs :title, :body, :created_at %>
226
221
  <%= f.inputs :first_name, :last_name, :for => :author, :name => "Author" %>
227
222
  <%= f.actions %>
228
223
  <% end %>
229
- </pre>
224
+ ```
230
225
 
231
- When working in has many association, you can even supply @"%i"@ in your fieldset name; they will be properly interpolated with the child index. For example:
226
+ When working in has many association, you can even supply `"%i"` in your fieldset name; they will be properly interpolated with the child index. For example:
232
227
 
233
- <pre>
228
+ ```erb
234
229
  <%= semantic_form_for @post do |f| %>
235
230
  <%= f.inputs %>
236
231
  <%= f.inputs :name => 'Category #%i', :for => :categories %>
237
232
  <%= f.actions %>
238
233
  <% end %>
239
- </pre>
234
+ ```
240
235
 
241
236
  Alternatively, the current index can be accessed via the `inputs` block's arguments for use anywhere:
242
237
 
243
- <pre>
238
+ ```erb
244
239
  <%= semantic_form_for @post do |f| %>
245
240
  <%= f.inputs :for => :categories do |category, i| %>
246
241
  ...
247
242
  <%= f.actions %>
248
243
  <% end %>
249
- </pre>
244
+ ```
250
245
 
251
246
  If you have more than one form on the same page, it may lead to HTML invalidation because of the way HTML element id attributes are assigned. You can provide a namespace for your form to ensure uniqueness of id attributes on form elements. The namespace attribute will be prefixed with underscore on the generate HTML id. For example:
252
247
 
253
- <pre>
248
+ ```erb
254
249
  <%= semantic_form_for(@post, :namespace => 'cat_form') do |f| %>
255
250
  <%= f.inputs do %>
256
251
  <%= f.input :title %> # id="cat_form_post_title"
@@ -259,11 +254,11 @@ If you have more than one form on the same page, it may lead to HTML invalidatio
259
254
  <% end %>
260
255
  <%= f.actions %>
261
256
  <% end %>
262
- </pre>
257
+ ```
263
258
 
264
- Customize HTML attributes for any input using the @:input_html@ option. Typically this is used to disable the input, change the size of a text field, change the rows in a textarea, or even to add a special class to an input to attach special behavior like "autogrow":http://plugins.jquery.com/project/autogrowtextarea textareas:
259
+ Customize HTML attributes for any input using the `:input_html` option. Typically this is used to disable the input, change the size of a text field, change the rows in a textarea, or even to add a special class to an input to attach special behavior like [autogrow](https://plugins.jquery.com/project/autogrowtextarea) textareas:
265
260
 
266
- <pre>
261
+ ```erb
267
262
  <%= semantic_form_for @post do |f| %>
268
263
  <%= f.inputs do %>
269
264
  <%= f.input :title, :input_html => { :size => 10 } %>
@@ -273,22 +268,22 @@ Customize HTML attributes for any input using the @:input_html@ option. Typicall
273
268
  <% end %>
274
269
  <%= f.actions %>
275
270
  <% end %>
276
- </pre>
271
+ ```
277
272
 
278
- The same can be done for actions with the @:button_html@ option:
273
+ The same can be done for actions with the `:button_html` option:
279
274
 
280
- <pre>
275
+ ```erb
281
276
  <%= semantic_form_for @post do |f| %>
282
277
  ...
283
278
  <%= f.actions do %>
284
279
  <%= f.action :submit, :button_html => { :class => "primary", :disable_with => 'Wait...' } %>
285
280
  <% end %>
286
281
  <% end %>
287
- </pre>
282
+ ```
288
283
 
289
- Customize the HTML attributes for the @<li>@ wrapper around every input with the @:wrapper_html@ option hash. There's one special key in the hash: (@:class@), which will actually _append_ your string of classes to the existing classes provided by Formtastic (like @"required string error"@).
284
+ Customize the HTML attributes for the `<li>` wrapper around every input with the `:wrapper_html` option hash. There's one special key in the hash: (`:class`), which will actually _append_ your string of classes to the existing classes provided by Formtastic (like `"required string error"`).
290
285
 
291
- <pre>
286
+ ```erb
292
287
  <%= semantic_form_for @post do |f| %>
293
288
  <%= f.inputs do %>
294
289
  <%= f.input :title, :wrapper_html => { :class => "important" } %>
@@ -297,11 +292,11 @@ Customize the HTML attributes for the @<li>@ wrapper around every input with the
297
292
  <% end %>
298
293
  ...
299
294
  <% end %>
300
- </pre>
295
+ ```
301
296
 
302
- Many inputs provide a collection of options to choose from (like @:select@, @:radio@, @:check_boxes@, @:boolean@). In many cases, Formtastic can find choices through the model associations, but if you want to use your own set of choices, the @:collection@ option is what you want. You can pass in an Array of objects, an array of Strings, a Hash... Throw almost anything at it! Examples:
297
+ Many inputs provide a collection of options to choose from (like `:select`, `:radio`, `:check_boxes`, `:boolean`). In many cases, Formtastic can find choices through the model associations, but if you want to use your own set of choices, the `:collection` option is what you want. You can pass in an Array of objects, an array of Strings, a Hash... Throw almost anything at it! Examples:
303
298
 
304
- <pre>
299
+ ```ruby
305
300
  f.input :authors, :as => :check_boxes, :collection => User.order("last_name ASC").all
306
301
  f.input :authors, :as => :check_boxes, :collection => current_user.company.users.active
307
302
  f.input :authors, :as => :check_boxes, :collection => [@justin, @kate]
@@ -319,58 +314,58 @@ Many inputs provide a collection of options to choose from (like @:select@, @:ra
319
314
  f.input :admin, :as => :radio, :collection => ["Yes!", "No"]
320
315
  f.input :book_id, :as => :select, :collection => Hash[Book.all.map{|b| [b.name,b.id]}]
321
316
  f.input :fav_book,:as => :datalist , :collection => Book.pluck(:name)
322
- </pre>
317
+ ```
323
318
 
324
319
 
325
- h2. The Available Inputs
320
+ ## The Available Inputs
326
321
 
327
322
  The Formtastic input types:
328
323
 
329
- * @:select@ - a select menu. Default for ActiveRecord associations: @belongs_to@, @has_many@, and @has_and_belongs_to_many@.
330
- * @:check_boxes@ - a set of check_box inputs. Alternative to @:select@ for ActiveRecord-associations: @has_many@, and @has_and_belongs_to_many@.
331
- * @:radio@ - a set of radio inputs. Alternative to @:select@ for ActiveRecord-associations: @belongs_to@.
332
- * @:time_zone@ - a select input. Default for column types: @:string@ with name matching @"time_zone"@.
333
- * @:password@ - a password input. Default for column types: @:string@ with name matching @"password"@.
334
- * @:text@ - a textarea. Default for column types: @:text@.
335
- * @:date_select@ - a date select. Default for column types: @:date@.
336
- * @:datetime_select@ - a date and time select. Default for column types: @:datetime@ and @:timestamp@.
337
- * @:time_select@ - a time select. Default for column types: @:time@.
338
- * @:boolean@ - a checkbox. Default for column types: @:boolean@.
339
- * @:string@ - a text field. Default for column types: @:string@.
340
- * @:number@ - a text field (just like string). Default for column types: @:integer@, @:float@, and @:decimal@.
341
- * @:file@ - a file field. Default for file-attachment attributes matching: "paperclip":http://github.com/thoughtbot/paperclip or "attachment_fu":http://github.com/technoweenie/attachment_fu.
342
- * @:country@ - a select menu of country names. Default for column types: :string with name @"country"@ - requires a *country_select* plugin to be installed.
343
- * @:email@ - a text field (just like string). Default for columns with name matching @"email"@. New in HTML5. Works on some mobile browsers already.
344
- * @:url@ - a text field (just like string). Default for columns with name matching @"url"@. New in HTML5. Works on some mobile browsers already.
345
- * @:phone@ - a text field (just like string). Default for columns with name matching @"phone"@ or @"fax"@. New in HTML5.
346
- * @:search@ - a text field (just like string). Default for columns with name matching @"search"@. New in HTML5. Works on Safari.
347
- * @:hidden@ - a hidden field. Creates a hidden field (added for compatibility).
348
- * @:range@ - a slider field.
349
- * @:datalist@ - a text field with a accompanying "datalist tag":https://developer.mozilla.org/en/docs/Web/HTML/Element/datalist which provides options for autocompletion
324
+ * `:select` - a select menu. Default for ActiveRecord associations: `belongs_to`, `has_many`, and `has_and_belongs_to_many`.
325
+ * `:check_boxes` - a set of check_box inputs. Alternative to `:select` for ActiveRecord-associations: `has_many`, and has_and_belongs_to_many`.
326
+ * `:radio` - a set of radio inputs. Alternative to `:select` for ActiveRecord-associations: `belongs_to`.
327
+ * `:time_zone` - a select input. Default for column types: `:string` with name matching `"time_zone"`.
328
+ * `:password` - a password input. Default for column types: `:string` with name matching `"password"`.
329
+ * `:text` - a textarea. Default for column types: `:text`.
330
+ * `:date_select` - a date select. Default for column types: `:date`.
331
+ * `:datetime_select` - a date and time select. Default for column types: `:datetime` and `:timestamp`.
332
+ * `:time_select` - a time select. Default for column types: `:time`.
333
+ * `:boolean` - a checkbox. Default for column types: `:boolean`.
334
+ * `:string` - a text field. Default for column types: `:string`.
335
+ * `:number` - a text field (just like string). Default for column types: `:integer`, `:float`, and `:decimal`.
336
+ * `:file` - a file field. Default for file-attachment attributes matching: [paperclip](https://github.com/thoughtbot/paperclip) or [attachment_fu](https://github.com/technoweenie/attachment_fu).
337
+ * `:country` - a select menu of country names. Default for column types: `:string` with name `"country"` - requires a *country_select* plugin to be installed.
338
+ * `:email` - a text field (just like string). Default for columns with name matching `"email"`. New in HTML5. Works on some mobile browsers already.
339
+ * `:url` - a text field (just like string). Default for columns with name matching `"url"`. New in HTML5. Works on some mobile browsers already.
340
+ * `:phone` - a text field (just like string). Default for columns with name matching `"phone"` or `"fax"`. New in HTML5.
341
+ * `:search` - a text field (just like string). Default for columns with name matching `"search"`. New in HTML5. Works on Safari.
342
+ * `:hidden` - a hidden field. Creates a hidden field (added for compatibility).
343
+ * `:range` - a slider field.
344
+ * `:datalist` - a text field with a accompanying [datalist tag](https://developer.mozilla.org/en/docs/Web/HTML/Element/datalist) which provides options for autocompletion
350
345
 
351
346
  The comments in the code are pretty good for each of these (what it does, what the output is, what the options are, etc.) so go check it out.
352
347
 
353
348
 
354
- h2. Delegation for label lookups
349
+ ## Delegation for label lookups
355
350
 
356
351
  Formtastic decides which label to use in the following order:
357
352
 
358
- <pre>
353
+ ```
359
354
  1. :label # :label => "Choose Title"
360
355
  2. Formtastic i18n # if either :label => true || i18n_lookups_by_default = true (see Internationalization)
361
356
  3. Activerecord i18n # if localization file found for the given attribute
362
357
  4. label_str_method # if nothing provided this defaults to :humanize but can be set to a custom method
363
- </pre>
358
+ ```
364
359
 
365
- h2. Internationalization (I18n)
360
+ ## Internationalization (I18n)
366
361
 
367
- h3. Basic Localization
362
+ ### Basic Localization
368
363
 
369
- Formtastic has some neat I18n-features. ActiveRecord object names and attributes are, by default, taken from calling @@object.human_name@ and @@object.human_attribute_name(attr)@ respectively. There are a few words specific to Formtastic that can be translated. See @lib/locale/en.yml@ for more information.
364
+ Formtastic has some neat I18n-features. ActiveRecord object names and attributes are, by default, taken from calling `@object.human_name` and `@object.human_attribute_name(attr)` respectively. There are a few words specific to Formtastic that can be translated. See `lib/locale/en.yml` for more information.
370
365
 
371
366
  Basic localization (labels only, with ActiveRecord):
372
367
 
373
- <pre>
368
+ ```erb
374
369
  <%= semantic_form_for @post do |f| %>
375
370
  <%= f.inputs do %>
376
371
  <%= f.input :title %> # => :label => I18n.t('activerecord.attributes.user.title') or 'Title'
@@ -378,23 +373,23 @@ Basic localization (labels only, with ActiveRecord):
378
373
  <%= f.input :section %> # => :label => I18n.t('activerecord.attributes.user.section') or 'Section'
379
374
  <% end %>
380
375
  <% end %>
381
- </pre>
376
+ ```
382
377
 
383
378
  *Note:* This is perfectly fine if you just want your labels/attributes and/or models to be translated using *ActiveRecord I18n attribute translations*, and you don't use input hints and legends. But what if you do? And what if you don't want same labels in all forms?
384
379
 
385
- h3. Enhanced Localization (Formtastic I18n API)
380
+ ### Enhanced Localization (Formtastic I18n API)
386
381
 
387
382
  Formtastic supports localized *labels*, *hints*, *legends*, *actions* using the I18n API for more advanced usage. Your forms can now be DRYer and more flexible than ever, and still fully localized. This is how:
388
383
 
389
- *1. Enable I18n lookups by default (@config/initializers/formtastic.rb@):*
384
+ *1. Enable I18n lookups by default (`config/initializers/formtastic.rb`):*
390
385
 
391
- <pre>
386
+ ```ruby
392
387
  Formtastic::FormBuilder.i18n_lookups_by_default = true
393
- </pre>
388
+ ```
394
389
 
395
- *2. Add some label-translations/variants (@config/locales/en.yml@):*
390
+ *2. Add some label-translations/variants (`config/locales/en.yml`):*
396
391
 
397
- <pre>
392
+ ```yml
398
393
  en:
399
394
  formtastic:
400
395
  titles:
@@ -421,11 +416,11 @@ Formtastic supports localized *labels*, *hints*, *legends*, *actions* using the
421
416
  reset: "Reset form"
422
417
  cancel: "Cancel and go back"
423
418
  dummie: "Launch!"
424
- </pre>
419
+ ```
425
420
 
426
421
  *3. ...and now you'll get:*
427
422
 
428
- <pre>
423
+ ```erb
429
424
  <%= semantic_form_for Post.new do |f| %>
430
425
  <%= f.inputs do %>
431
426
  <%= f.input :title %> # => :label => "Choose a title...", :hint => "Choose a good title for your post."
@@ -436,24 +431,24 @@ Formtastic supports localized *labels*, *hints*, *legends*, *actions* using the
436
431
  <%= f.action :submit %> # => "Create my %{model}"
437
432
  <% end %>
438
433
  <% end %>
439
- </pre>
434
+ ```
440
435
 
441
436
  *4. Localized titles (a.k.a. legends):*
442
437
 
443
438
  _Note: Slightly different because Formtastic can't guess how you group fields in a form. Legend text can be set with first (as in the sample below) specified value, or :name/:title options - depending on what flavor is preferred._
444
439
 
445
- <pre>
440
+ ```erb
446
441
  <%= semantic_form_for @post do |f| %>
447
442
  <%= f.inputs :post_details do %> # => :title => "Post details"
448
443
  # ...
449
444
  <% end %>
450
445
  # ...
451
446
  <% end %>
452
- </pre>
447
+ ```
453
448
 
454
449
  *5. Override I18n settings:*
455
450
 
456
- <pre>
451
+ ```erb
457
452
  <%= semantic_form_for @post do |f| %>
458
453
  <%= f.inputs do %>
459
454
  <%= f.input :title %> # => :label => "Choose a title...", :hint => "Choose a good title for your post."
@@ -464,17 +459,17 @@ _Note: Slightly different because Formtastic can't guess how you group fields in
464
459
  <%= f.action :submit, :label => :dummie %> # => "Launch!"
465
460
  <% end %>
466
461
  <% end %>
467
- </pre>
462
+ ```
468
463
 
469
464
  If I18n-lookups is disabled, i.e.:
470
465
 
471
- <pre>
466
+ ```ruby
472
467
  Formtastic::FormBuilder.i18n_lookups_by_default = false
473
- </pre>
468
+ ```
474
469
 
475
470
  ...then you can enable I18n within the forms instead:
476
471
 
477
- <pre>
472
+ ```erb
478
473
  <%= semantic_form_for @post do |f| %>
479
474
  <%= f.inputs do %>
480
475
  <%= f.input :title, :label => true %> # => :label => "Choose a title..."
@@ -485,25 +480,25 @@ If I18n-lookups is disabled, i.e.:
485
480
  <%= f.action :submit, :label => true %> # => "Update %{model}" (if we are in edit that is...)
486
481
  <% end %>
487
482
  <% end %>
488
- </pre>
483
+ ```
489
484
 
490
485
  *6. Advanced I18n lookups*
491
486
 
492
487
  For more flexible forms; Formtastic finds translations using a bottom-up approach taking the following variables in account:
493
488
 
494
- * @MODEL@, e.g. "post"
495
- * @ACTION@, e.g. "edit"
496
- * @KEY/ATTRIBUTE@, e.g. "title", :my_custom_key, ...
489
+ * `MODEL`, e.g. "post"
490
+ * `ACTION`, e.g. "edit"
491
+ * `KEY/ATTRIBUTE`, e.g. "title", :my_custom_key, ...
497
492
 
498
493
  ...in the following order:
499
494
 
500
- 1. @formtastic.{titles,labels,hints,actions}.MODEL.ACTION.ATTRIBUTE@ - by model and action
501
- 2. @formtastic.{titles,labels,hints,actions}.MODEL.ATTRIBUTE@ - by model
502
- 3. @formtastic.{titles,labels,hints,actions}.ATTRIBUTE@ - global default
495
+ 1. `formtastic.{titles,labels,hints,actions}.MODEL.ACTION.ATTRIBUTE` - by model and action
496
+ 2. `formtastic.{titles,labels,hints,actions}.MODEL.ATTRIBUTE` - by model
497
+ 3. `formtastic.{titles,labels,hints,actions}.ATTRIBUTE` - global default
503
498
 
504
499
  ...which means that you can define translations like this:
505
500
 
506
- <pre>
501
+ ```yml
507
502
  en:
508
503
  formtastic:
509
504
  labels:
@@ -517,100 +512,116 @@ For more flexible forms; Formtastic finds translations using a bottom-up approac
517
512
  edit:
518
513
  title: "Edit title"
519
514
  body: "Edit body"
520
- </pre>
515
+ ```
521
516
 
522
- Values for @labels@/@hints@/@actions@ are can take values: @String@ (explicit value), @Symbol@ (i18n-lookup-key relative to the current "type", e.g. actions:), @true@ (force I18n lookup), @false@ (force no I18n lookup). Titles (legends) can only take: @String@ and @Symbol@ - true/false have no meaning.
517
+ Values for `labels`/`hints`/`actions` are can take values: `String` (explicit value), `Symbol` (i18n-lookup-key relative to the current "type", e.g. actions:), `true` (force I18n lookup), `false` (force no I18n lookup). Titles (legends) can only take: `String` and `Symbol` - true/false have no meaning.
523
518
 
524
519
  *7. Basic Translations*
525
- If you want some basic translations, take a look on the "formtastic_i18n gem":https://github.com/timoschilling/formtastic_i18n.
520
+ If you want some basic translations, take a look on the [formtastic_i18n gem](https://github.com/timoschilling/formtastic_i18n).
526
521
 
527
- h2. Semantic errors
522
+ ## Semantic errors
528
523
 
529
524
  You can show errors on base (by default) and any other attribute just by passing its name to the semantic_errors method:
530
525
 
531
- <pre>
526
+ ```erb
532
527
  <%= semantic_form_for @post do |f| %>
533
528
  <%= f.semantic_errors :state %>
534
529
  <% end %>
535
- </pre>
530
+ ```
536
531
 
537
532
 
538
- h2. Modified & Custom Inputs
533
+ ## Modified & Custom Inputs
539
534
 
540
535
  You can modify existing inputs, subclass them, or create your own from scratch. Here's the basic process:
541
536
 
542
- * Create a file in @app/inputs@ with a filename ending in @_input.rb@. For example, @app/inputs/hat_size_input.rb@. Formtastic will automatically look in @app/inputs@ and find the file.
543
- * In that file, declare a classname ending in @Input@. For example, @class HatSizeInput@. It must have a @to_html@ method for rendering.
544
- * To use that input, leave off the word "input" in your @as@ statement. For example, @f.input(:size, :as => :hat_size)@
537
+ * Run the input generator and provide your custom input name. For example, `rails generate formtastic:input hat_size`. This creates the file `app/inputs/hat_size_input.rb`. You can also provide namespace to input name like `rails generate formtastic:input foo/custom` or `rails generate formtastic:input Foo::Custom`, this will create the file `app/inputs/foo/custom_input.rb` in both cases.
538
+ * To use that input, leave off the word "input" in your `as` statement. For example, `f.input(:size, :as => :hat_size)`
545
539
 
546
540
  Specific examples follow.
547
541
 
548
- h3. Changing Existing Input Behavior
542
+ ### Changing Existing Input Behavior
549
543
 
550
- To modify the behavior of @StringInput@, subclass it in a new file, @app/inputs/string_input.rb@:
544
+ To modify the behavior of `StringInput`, subclass it in a new file, `app/inputs/string_input.rb`:
551
545
 
552
- <pre>
546
+ ```ruby
553
547
  class StringInput < Formtastic::Inputs::StringInput
554
548
  def to_html
555
549
  puts "this is my modified version of StringInput"
556
550
  super
557
551
  end
558
552
  end
559
- </pre>
553
+ ```
554
+
555
+ Another way to modify behavior is by using the input generator:
556
+ ```shell
557
+ $ rails generate formtastic:input string --extend
558
+ ```
559
+
560
+ This generates the file `app/inputs/string_input.rb` with its respective content class.
560
561
 
561
- You can use your modified version with @:as => :string@.
562
+ You can use your modified version with `:as => :string`.
562
563
 
563
- h3. Creating New Inputs Based on Existing Ones
564
+ ### Creating New Inputs Based on Existing Ones
564
565
 
565
- To create your own new types of inputs based on existing inputs, the process is similar. For example, to create @FlexibleTextInput@ based on @StringInput@, put the following in @app/inputs/flexible_text_input.rb@:
566
+ To create your own new types of inputs based on existing inputs, the process is similar. For example, to create `FlexibleTextInput` based on `StringInput`, put the following in `app/inputs/flexible_text_input.rb`:
566
567
 
567
- <pre>
568
+ ```ruby
568
569
  class FlexibleTextInput < Formtastic::Inputs::StringInput
569
570
  def input_html_options
570
571
  super.merge(:class => "flexible-text-area")
571
572
  end
572
573
  end
573
- </pre>
574
+ ```
574
575
 
575
- You can use your new input with @:as => :flexible_text@.
576
+ You can also extend existing input behavior by using the input generator:
576
577
 
577
- h3. Creating New Inputs From Scratch
578
+ ```shell
579
+ $ rails generate formtastic:input FlexibleText --extend string
580
+ ```
578
581
 
579
- To create a custom @DatePickerInput@ from scratch, put the following in @app/inputs/date_picker_input.rb@:
582
+ This generates the file `app/inputs/flexible_text_input.rb` with its respective content class.
580
583
 
581
- <pre>
584
+ You can use your new input with `:as => :flexible_text`.
585
+
586
+ ### Creating New Inputs From Scratch
587
+
588
+ To create a custom `DatePickerInput` from scratch, put the following in `app/inputs/date_picker_input.rb`:
589
+
590
+ ```ruby
582
591
  class DatePickerInput
583
592
  include Formtastic::Inputs::Base
584
593
  def to_html
585
594
  # ...
586
595
  end
587
596
  end
588
- </pre>
597
+ ```
589
598
 
590
- You can use your new input with @:as => :date_picker@.
599
+ You can use your new input with `:as => :date_picker`.
591
600
 
592
601
 
593
- h2. Dependencies
602
+ ## Dependencies
594
603
 
595
604
  There are none other than Rails itself, but...
596
605
 
597
- * If you want to use the @:country@ input, you'll need to install the "country-select plugin":https://github.com/stefanpenner/country_select (or any other country_select plugin with the same API). Both 1.x and 2.x are supported, but they behave differently when storing data, so please see their "upgrade notes":https://github.com/stefanpenner/country_select/blob/master/UPGRADING.md if switching from 1.x.
606
+ * If you want to use the `:country` input, you'll need to install the [country-select plugin](https://github.com/stefanpenner/country_select) (or any other country_select plugin with the same API). Both 1.x and 2.x are supported, but they behave differently when storing data, so please see their [upgrade notes](https://github.com/stefanpenner/country_select/blob/master/UPGRADING.md) if switching from 1.x.
598
607
  * There are a bunch of development dependencies if you plan to contribute to Formtastic
599
608
 
600
609
 
601
- h2. How to contribute
610
+ ## How to contribute
602
611
 
603
612
  * Fork the project on Github
613
+ * Install development dependencies (`bundle install` and `bin/appraisal install`)
604
614
  * Create a topic branch for your changes
605
615
  * Ensure that you provide *documentation* and *test coverage* for your changes (patches won't be accepted without)
606
616
  * Ensure that all tests pass (`bundle exec rake`)
607
617
  * Create a pull request on Github (these are also a great place to start a conversation around a patch as early as possible)
608
618
 
609
619
 
610
- h2. Project Info
620
+ ## Project Info
621
+
622
+ Formtastic was created by [Justin French](https://www.justinfrench.com) with contributions from around 180 awesome developers. Run `git shortlog -n -s` to see the awesome.
611
623
 
612
- Formtastic was created by "Justin French":http://www.justinfrench.com with contributions from around 180 awesome developers. Run @git shortlog -n -s@ to see the awesome.
624
+ The project is hosted on Github: [https://github.com/formtastic/formtastic](https://github.com/formtastic/formtastic), where your contributions, forkings, comments, issues and feedback are greatly welcomed.
613
625
 
614
- The project is hosted on Github: "http://github.com/justinfrench/formtastic":http://github.com/justinfrench/formtastic, where your contributions, forkings, comments, issues and feedback are greatly welcomed.
626
+ Copyright (c) 2007-2021, released under the MIT license.
615
627
 
616
- Copyright (c) 2007-2014 Justin French, released under the MIT license.