diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 4914ecc5d0fba..53787f505b053 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -500,8 +500,9 @@ def fields_for(record_or_name_or_array, *args, &block) end # Returns a label tag tailored for labelling an input field for a specified attribute (identified by +method+) on an object - # assigned to the template (identified by +object+). The text of label will default to the attribute name unless you specify - # it explicitly. Additional options on the label tag can be passed as a hash with +options+. These options will be tagged + # assigned to the template (identified by +object+). The text of label will default to the attribute name unless a translation + # is found in the current I18n locale (through views.labels..) or you specify it explicitly. + # Additional options on the label tag can be passed as a hash with +options+. These options will be tagged # onto the HTML as an HTML element attribute as in the example shown, except for the :value option, which is designed to # target labels for radio_button tags (where the value is used in the ID of the input tag). # @@ -509,6 +510,29 @@ def fields_for(record_or_name_or_array, *args, &block) # label(:post, :title) # # => # + # You can localize your labels based on model and attribute names. + # For example you can define the following in your locale (e.g. en.yml) + # + # views: + # labels: + # post: + # body: "Write your entire text here" + # + # Which then will result in + # + # label(:post, :body) + # # => + # + # Localization can also be based purely on the translation of the attribute-name like this: + # + # activerecord: + # attribute: + # post: + # cost: "Total cost" + # + # label(:post, :cost) + # # => + # # label(:post, :title, "A short title") # # => # @@ -739,7 +763,20 @@ def to_label_tag(text = nil, options = {}) add_default_name_and_id_for_value(tag_value, name_and_id) options.delete("index") options["for"] ||= name_and_id["id"] - content = (text.blank? ? nil : text.to_s) || method_name.humanize + + content = if text.blank? + i18n_label = I18n.t("views.labels.#{object_name}.#{method_name}", :default => "") + i18n_label if i18n_label.present? + else + text.to_s + end + + content ||= if object && object.class.respond_to?(:human_attribute_name) + object.class.human_attribute_name(method_name) + end + + content ||= method_name.humanize + label_tag(name_and_id["id"], content, options) end diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index f22302d3c9055..b63bdb791f3c7 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -92,6 +92,19 @@ class FormHelperTest < ActionView::TestCase tests ActionView::Helpers::FormHelper def setup + super + + # Create "label" locale for testing I18n label helpers + I18n.backend.store_translations 'label', { + :views => { + :labels => { + :post => { + :body => "Write entire text here" + } + } + } + } + @post = Post.new @comment = Comment.new def @post.errors() @@ -112,6 +125,10 @@ def @post.to_param; '123'; end @post.secret = 1 @post.written_on = Date.new(2004, 6, 15) + def Post.human_attribute_name(attribute) + attribute.to_s == "cost" ? "Total cost" : attribute.to_s.humanize + end + @controller = Class.new do attr_reader :url_for_options def url_for(options) @@ -137,6 +154,27 @@ def test_label_with_symbols assert_dom_equal('', label(:post, :secret?)) end + def test_label_with_locales_strings + old_locale, I18n.locale = I18n.locale, :label + assert_dom_equal('', label("post", "body")) + ensure + I18n.locale = old_locale + end + + def test_label_with_human_attribute_name + old_locale, I18n.locale = I18n.locale, :label + assert_dom_equal('', label(:post, :cost)) + ensure + I18n.locale = old_locale + end + + def test_label_with_locales_symbols + old_locale, I18n.locale = I18n.locale, :label + assert_dom_equal('', label(:post, :body)) + ensure + I18n.locale = old_locale + end + def test_label_with_for_attribute_as_symbol assert_dom_equal('', label(:post, :title, nil, :for => "my_for")) end