diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md index 552a902349a09fea24c848a74e192eecb4727921..396249ac377caa4e58aeffff0f4d595360e3873d 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 39b2f48c390b1000ce9e94581a428b6ae37ba900..08a23e497ed14665f17cebe8995d10711ce06f8b 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 @@ def render(&block) 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 69107691838962244f169b1e1a0d92f3297e8570..6f82462425c6d444881d45b8ad56f22b261da87b 100644 --- a/actionview/test/template/form_helper_test.rb +++ b/actionview/test/template/form_helper_test.rb @@ -319,6 +319,15 @@ def test_label_with_block_and_options ) end + def test_label_with_block_and_builder + with_locale :label do + assert_dom_equal( + '', + label(:post, :body) { |b| "#{b.translation}".html_safe } + ) + end + end + def test_label_with_block_in_erb assert_equal( %{},