diff --git a/lib/formtastic/form_builder.rb b/lib/formtastic/form_builder.rb index 1d04a8a5b..583b62d6c 100644 --- a/lib/formtastic/form_builder.rb +++ b/lib/formtastic/form_builder.rb @@ -69,6 +69,12 @@ def self.configure(name, value = nil) # # @todo is there a way to test the params structure of the Rails helper we wrap to ensure forward compatibility? def semantic_fields_for(record_or_name_or_array, *args, &block) + # Add a :parent_builder to the args so that nested translations can be possible in Rails 3 + options = args.shift || {} + options[:parent_builder] ||= self + args.unshift(options) + + # Wrap the Rails helper fields_for(record_or_name_or_array, *args, &block) end diff --git a/lib/formtastic/localized_string.rb b/lib/formtastic/localized_string.rb index 631c04fc0..6bab5bc7f 100644 --- a/lib/formtastic/localized_string.rb +++ b/lib/formtastic/localized_string.rb @@ -35,6 +35,7 @@ def localized_string(key, value, type, options = {}) #:nodoc: if use_i18n model_name, nested_model_name = normalize_model_name(self.model_name.underscore) + action_name = template.params[:action].to_s rescue '' attribute_name = key.to_s @@ -73,9 +74,17 @@ def model_name end def normalize_model_name(name) - if name =~ /(.+)\[(.+)\]/ + if !name =~ /\[/ && self.respond_to?(:builder) && builder.respond_to?(:parent_builder) && builder.parent_builder.object_name + # Rails 3.1 nested builder case + [builder.parent_builder.object_name.to_s, name] + elsif name =~ /(.+)\[(.+)\]/ + # Rails 3 (and 3.1?) nested builder case with :post rather than @post [$1, $2] + elsif self.respond_to?(:builder) && builder.respond_to?(:options) && builder.options.key?(:parent_builder) + # Rails 3.0 nested builder work-around case, where :parent_builder is provided by f.semantic_form_for + [builder.options[:parent_builder].object_name.to_s, name] else + # Non-nested case [name] end end diff --git a/spec/i18n_spec.rb b/spec/i18n_spec.rb index 46f10ac00..31f7d47e9 100644 --- a/spec/i18n_spec.rb +++ b/spec/i18n_spec.rb @@ -87,14 +87,14 @@ ::I18n.backend.store_translations :en, {:formtastic => { :labels => { - :title => "Hello world!", + :author => { :name => "Top author name transation" }, :post => {:title => "Hello post!", :author => {:name => "Hello author name!"}}, :project => {:title => "Hello project!"}, - :line_item => {:name => "Hello line item name!"} } }, :helpers => { :label => { - :post => {:author => "Written by"} + :post => {:body => "Elaborate..." }, + :author => { :login => "Hello login" } } }} @@ -130,10 +130,10 @@ end end - xit 'should be able to translate nested objects with nested translations' do + it 'should be able to translate nested objects with nested translations' do with_config :i18n_lookups_by_default, true do concat(semantic_form_for(@new_post) do |builder| - concat(builder.fields_for(:author) do |f| + concat(builder.semantic_fields_for(@new_post.author) do |f| concat(f.input(:name)) end) end) @@ -141,23 +141,45 @@ end end - xit 'should be able to translate nested objects with top level translations' do + it 'should be able to translate nested objects with top level translations' do with_config :i18n_lookups_by_default, true do - concat(semantic_form_for(:order, :url => 'http://test.host') do |builder| - builder.fields_for(:line_item) do |f| + concat(semantic_form_for(@new_post) do |builder| + builder.semantic_fields_for(@new_post.author) do |f| concat(f.input(:name)) end end) - output_buffer.should have_tag("form label", /Hello line item name!/) + output_buffer.should have_tag("form label", /Hello author name!/) + end + end + + it 'should be able to translate nested forms with top level translations' do + with_config :i18n_lookups_by_default, true do + concat(semantic_form_for(:post) do |builder| + builder.semantic_fields_for(:author) do |f| + concat(f.input(:name)) + end + end) + output_buffer.should have_tag("form label", /Hello author name!/) end end - xit 'should be able to translate helper label as Rails does' do + it 'should be able to translate helper label as Rails does' do with_config :i18n_lookups_by_default, true do concat(semantic_form_for(@new_post) do |builder| - concat(builder.input(:author)) + concat(builder.input(:body)) + end) + output_buffer.should have_tag("form label", /Elaborate/) + end + end + + it 'should be able to translate nested helper label as Rails does' do + with_config :i18n_lookups_by_default, true do + concat(semantic_form_for(@new_post) do |builder| + concat(builder.inputs :for => @new_post.author do |f| + concat(f.input(:login)) + end) end) - output_buffer.should have_tag("form label", /Written by/) + output_buffer.should have_tag("form label", /Hello login/) end end