diff options
-rw-r--r-- | actionview/CHANGELOG.md | 7 | ||||
-rw-r--r-- | actionview/lib/action_view/helpers/tags/label.rb | 68 | ||||
-rw-r--r-- | actionview/test/template/form_helper_test.rb | 9 | ||||
-rw-r--r-- | activemodel/lib/active_model/model.rb | 14 | ||||
-rw-r--r-- | activesupport/test/transliterate_test.rb | 2 | ||||
-rw-r--r-- | guides/source/4_2_release_notes.md | 41 |
6 files changed, 91 insertions, 50 deletions
diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md index 552a902349..396249ac37 100644 --- a/actionview/CHANGELOG.md +++ b/actionview/CHANGELOG.md @@ -1,3 +1,10 @@ +* Provide a `builder` object when using the `label` form helper in block form. + + The new `builder` object responds to `translation`, allowing I18n fallback support + when you want to customize how a particular label is presented. + + *Alex Robbin* + * Add I18n support for input/textarea placeholder text. Placeholder I18n follows the same convention as `label` I18n. diff --git a/actionview/lib/action_view/helpers/tags/label.rb b/actionview/lib/action_view/helpers/tags/label.rb index 39b2f48c39..08a23e497e 100644 --- a/actionview/lib/action_view/helpers/tags/label.rb +++ b/actionview/lib/action_view/helpers/tags/label.rb @@ -2,6 +2,39 @@ module ActionView module Helpers module Tags # :nodoc: class Label < Base # :nodoc: + class LabelBuilder # :nodoc: + attr_reader :object + + def initialize(template_object, object_name, method_name, object, tag_value) + @template_object = template_object + @object_name = object_name + @method_name = method_name + @object = object + @tag_value = tag_value + end + + def translation + method_and_value = @tag_value.present? ? "#{@method_name}.#{@tag_value}" : @method_name + @object_name.gsub!(/\[(.*)_attributes\]\[\d+\]/, '.\1') + + if object.respond_to?(:to_model) + key = object.model_name.i18n_key + i18n_default = ["#{key}.#{method_and_value}".to_sym, ""] + end + + i18n_default ||= "" + content = I18n.t("#{@object_name}.#{method_and_value}", :default => i18n_default, :scope => "helpers.label").presence + + content ||= if object && object.class.respond_to?(:human_attribute_name) + object.class.human_attribute_name(method_and_value) + end + + content ||= @method_name.humanize + + content + end + end + def initialize(object_name, method_name, template_object, content_or_options = nil, options = nil) options ||= {} @@ -32,33 +65,24 @@ module ActionView options.delete("namespace") options["for"] = name_and_id["id"] unless options.key?("for") - if block_given? - content = @template_object.capture(&block) - else - method_and_value = tag_value.present? ? "#{@method_name}.#{tag_value}" : @method_name - content = if @content.blank? - @object_name.gsub!(/\[(.*)_attributes\]\[\d+\]/, '.\1') - - if object.respond_to?(:to_model) - key = object.model_name.i18n_key - i18n_default = ["#{key}.#{method_and_value}".to_sym, ""] - end - - i18n_default ||= "" - I18n.t("#{@object_name}.#{method_and_value}", :default => i18n_default, :scope => "helpers.label").presence - else - @content.to_s - end - - content ||= if object && object.class.respond_to?(:human_attribute_name) - object.class.human_attribute_name(method_and_value) - end + builder = LabelBuilder.new(@template_object, @object_name, @method_name, @object, tag_value) - content ||= @method_name.humanize + content = if block_given? + @template_object.capture(builder, &block) + elsif @content.present? + @content.to_s + else + render_component(builder) end label_tag(name_and_id["id"], content, options) end + + private + + def render_component(builder) + builder.translation + end end end end diff --git a/actionview/test/template/form_helper_test.rb b/actionview/test/template/form_helper_test.rb index 6910769183..6f82462425 100644 --- a/actionview/test/template/form_helper_test.rb +++ b/actionview/test/template/form_helper_test.rb @@ -319,6 +319,15 @@ class FormHelperTest < ActionView::TestCase ) end + def test_label_with_block_and_builder + with_locale :label do + assert_dom_equal( + '<label for="post_body"><b>Write entire text here</b></label>', + label(:post, :body) { |b| "<b>#{b.translation}</b>".html_safe } + ) + end + end + def test_label_with_block_in_erb assert_equal( %{<label for="post_message">\n Message\n <input id="post_message" name="post[message]" type="text" />\n</label>}, diff --git a/activemodel/lib/active_model/model.rb b/activemodel/lib/active_model/model.rb index 640024eaa1..d51d6ddcc9 100644 --- a/activemodel/lib/active_model/model.rb +++ b/activemodel/lib/active_model/model.rb @@ -56,13 +56,13 @@ module ActiveModel # refer to the specific modules included in <tt>ActiveModel::Model</tt> # (see below). module Model - def self.included(base) #:nodoc: - base.class_eval do - extend ActiveModel::Naming - extend ActiveModel::Translation - include ActiveModel::Validations - include ActiveModel::Conversion - end + extend ActiveSupport::Concern + include ActiveModel::Validations + include ActiveModel::Conversion + + included do + extend ActiveModel::Naming + extend ActiveModel::Translation end # Initializes a new model with the given +params+. diff --git a/activesupport/test/transliterate_test.rb b/activesupport/test/transliterate_test.rb index e0f85f4e7c..6833ae68a7 100644 --- a/activesupport/test/transliterate_test.rb +++ b/activesupport/test/transliterate_test.rb @@ -11,7 +11,7 @@ class TransliterateTest < ActiveSupport::TestCase end def test_transliterate_should_approximate_ascii - # create string with range of Unicode"s western characters with + # create string with range of Unicode's western characters with # diacritics, excluding the division and multiplication signs which for # some reason or other are floating in the middle of all the letters. string = (0xC0..0x17E).to_a.reject {|c| [0xD7, 0xF7].include?(c)}.pack("U*") diff --git a/guides/source/4_2_release_notes.md b/guides/source/4_2_release_notes.md index 176cdadabf..c50a105cbf 100644 --- a/guides/source/4_2_release_notes.md +++ b/guides/source/4_2_release_notes.md @@ -37,10 +37,10 @@ Major Features Active Job is a new framework in Rails 4.2. It is an adapter layer on top of queuing systems like Resque, Delayed Job, Sidekiq, and more. You can write your -jobs to Active Job, and it'll run on all these queues with no changes. (It comes -pre-configured with an inline runner.) +jobs with the Active Job API, and it'll run on all these queues with no changes +(it comes pre-configured with an inline runner). -Building on top of Active Job, Action Mailer now comes with a #deliver_later +Building on top of Active Job, Action Mailer now comes with a `#deliver_later` method, which adds your email to be sent as a job to a queue, so it doesn't bog down the controller or model. @@ -63,16 +63,16 @@ TODO: add some technical details New applications generated from Rails 4.2 now comes with the Web Console gem by default. -Web Console is a set of debugging tools for your Rails application. It comes -with an interactive console for every error page, a `console` view helper and -VT100 compatible terminal. +Web Console is a set of debugging tools for your Rails application. It will add +an interactive console on every error page, a `console` view helper and a VT100 +compatible terminal. The interactive console on the error pages lets you execute code where the exception originated. It's quite handy to introspect the state that led to the error. -The `console` view helper launches an interactive console with the context of -the view right on the page it's invoked on. +The `console` view helper launches an interactive console within the context of +the view where it is invoked. Finally, you can launch a VT100 terminal that runs `rails console`. If you need to create or modify existing test data, you can do that straight from the @@ -184,7 +184,8 @@ Please refer to the [Changelog][railties] for detailed changes. * Introduced an API to register new extensions for `rake notes`. ([Pull Request](https://github.com/rails/rails/pull/14379)) -* Introduced `Rails.gem_version` as a convenience method to return `Gem::Version.new(Rails.version)`. +* Introduced `Rails.gem_version` as a convenience method to return + `Gem::Version.new(Rails.version)`. ([Pull Request](https://github.com/rails/rails/pull/14101)) @@ -265,8 +266,8 @@ Please refer to the [Changelog][action-pack] for detailed changes. * Added HTTP method `MKCALENDAR` from RFC-4791 ([Pull Request](https://github.com/rails/rails/pull/15121)) -* `*_fragment.action_controller` notifications now include the controller and action name - in the payload. +* `*_fragment.action_controller` notifications now include the controller + and action name in the payload. ([Pull Request](https://github.com/rails/rails/pull/14137)) * Segments that are passed into URL helpers are now automatically escaped. @@ -334,7 +335,7 @@ Please refer to the [Changelog][action-mailer] for detailed changes. ### Notable changes * Introduced `deliver_later` which enqueues a job on the application's queue - to deliver the mailer asynchronously. + to deliver emails asynchronously. ([Pull Request](https://github.com/rails/rails/pull/16485)) * Added the `show_previews` configuration option for enabling mailer previews @@ -345,9 +346,7 @@ Please refer to the [Changelog][action-mailer] for detailed changes. Active Record ------------- -Please refer to the -[Changelog](https://github.com/rails/rails/blob/4-2-stable/activerecord/CHANGELOG.md) -for detailed changes. +Please refer to the [Changelog][active-record] for detailed changes. ### Removals @@ -363,7 +362,7 @@ for detailed changes. * Removed unused `:timestamp` type. Transparently alias it to `:datetime` in all cases. Fixes inconsistencies when column types are sent outside of - `ActiveRecord`, such as for XML Serialization. + `ActiveRecord`, such as for XML serialization. ([Pull Request](https://github.com/rails/rails/pull/15184)) ### Deprecations @@ -458,7 +457,7 @@ for detailed changes. * `sqlite3:///some/path` now resolves to the absolute system path `/some/path`. For relative paths, use `sqlite3:some/path` instead. (Previously, `sqlite3:///some/path` resolved to the relative path - `some/path`. This behaviour was deprecated on Rails 4.1.) + `some/path`. This behaviour was deprecated on Rails 4.1). ([Pull Request](https://github.com/rails/rails/pull/14569)) * Introduced `#validate` as an alias for `#valid?`. @@ -490,17 +489,19 @@ Please refer to the [Changelog][active-model] for detailed changes. ### Deprecations -* Deprecated reset_#{attribute} in favor of restore_#{attribute}. +* Deprecated `reset_#{attribute}` in favor of `restore_#{attribute}`. ([Pull Request](https://github.com/rails/rails/pull/16180)) -* Deprecated ActiveModel::Dirty#reset_changes in favor of #clear_changes_information. +* Deprecated `ActiveModel::Dirty#reset_changes` in favor of + `#clear_changes_information`. ([Pull Request](https://github.com/rails/rails/pull/16180)) ### Notable changes * Introduced the `restore_attributes` method in `ActiveModel::Dirty` to restore the changed (dirty) attributes to their previous values. - (Pull Request [1](https://github.com/rails/rails/pull/14861), [2](https://github.com/rails/rails/pull/16180)) + (Pull Request [1](https://github.com/rails/rails/pull/14861), + [2](https://github.com/rails/rails/pull/16180)) * `has_secure_password` no longer disallow blank passwords (i.e. passwords that contains only spaces) by default. |