How to display all translation's fields in one form with globalize and rails 4
Asked Answered
S

2

5

How am I supposed to write the forms for my models where I'm using rails 4 and https://github.com/globalize/globalize for translations. i want to display all translations in one form like below example. i have found a solution here https://github.com/rilla/batch_translations but i don't know how do i implement this. is this "batch translation" a gem or what? and how can i install it.

<h1>Editing post</h1> 

   <% form_for(@post) do |f| %>
     <%= f.error_messages %>

     <h2>English (default locale)</h2>
     <p><%= f.text_field :title %></p>
     <p><%= f.text_field :teaser %></p>
     <p><%= f.text_field :body %></p>

     <hr/>

     <h2>Spanish translation</h2>
     <% f.globalize_fields_for :es do |g| %>
       <p><%= g.text_field :title %></p>
       <p><%= g.text_field :teaser %></p>
       <p><%= g.text_field :body %></p>
     <% end %>

     <hr/>

     <h2>French translation</h2>
     <% f.globalize_fields_for :fr do |g| %>
       <p><%= g.text_field :title %></p>
       <p><%= g.text_field :teaser %></p>
       <p><%= g.text_field :body %></p>
     <% end %>

   <% end %>
September answered 22/10, 2013 at 18:33 Comment(4)
This is a module for extending FormBuilder you should be able to put it in the lib directory of your application and then require it where needed.Nianiabi
ok let me check it and if works then you can add this as answer and i ll happily accept the answerSeptember
it shows an error "undefined method `globalize_translations' for"September
That is telling me that the module was included correctly because it is calling globalize_fields_for but that it cannot find globalize_translations method for ''. Is that really all it says? Also you are missing = in your form_for should be <%= form_for(@post) do |f| %> this could be causing the issue.Nianiabi
C
3

Have you considered something like this?

<%= form_for(@post) do |f| %>
     <%= f.error_messages %>

    <% [:en, :es, :fr].each do |lang| %>
      <h2><%= lang %> translation</h2>
      <% f.globalize_fields_for lang do |g| %>
        <% [:title, :teaser, :body].each do |field| %>
          <p><%= g.text_field field %></p>
        <% end %>
      <% end %>
      <hr/>
    <% end %>
<% end %>

You should be able to get those lists of regions and fields automatically. Then you only need a map of region to language name, like { en: 'English', es: 'Spanish', fr: 'French'} and you can output the proper language name instead of the region code. (This might already be available somewhere as well.)

Cataplasia answered 22/10, 2013 at 20:44 Comment(6)
<p><%= g.text_field :title %></p> should be <p><%= g.text_field field %></p>Nianiabi
i exactly copy ur code but it still says "undefined method `globalize_translations' for"September
is this a separate solution for i18n or can it be used with combination of globalize. i am using only two languages :en and :ar and i can easily translate posts when locale is set but i want both forms on same page so i am using ur code in my views/posts/new.html.erb. sorry if it is stupid question.September
Hi Murtza, all I've done is taken your code from above and removed the repetitive parts; I'm not familiar with globalize.Cataplasia
<% [:en, :es, :fr].each do |lang| %> could be <% {en:'English',es:'Spanish',fr:'French'}.each do |sym,lang| %> that way the mapping is done in a hash and can be used with your h2 for and then <% f.globalize_fields_for sym do |g| %>Nianiabi
Yep, that would work fine. (My hope was that a hash mapping locale to language already existed somewhere, e.g groups.google.com/forum/m/#!topic/rails-i18n/cFbxHcOVfnA)Cataplasia
S
11

The batch translation gem is quite old and I've had difficulties using it with newer versions of Rails. I stumbled on another gem called globalize-accessors which supports Rails 4. What's great is that it gives you access to methods like title_en, teaser_es, title_fr and so on.

So for example if you had a Feature model with names that should be in all languages you could to the following:

# => Feature Model (feature.rb)
class Feature < ActiveRecord::Base
  translates :name
  globalize_accessors :attributes => [:name]
end

Using the Feature.globalize_attribute_names method would give an array of [:name_en, :name_es, :name_fr] that can be used in the form_for helper:

//New Feature (new.html.haml)
= form_for @feature do |f|
  - Feature.globalize_attribute_names.each do |lang|
    = f.text_field lang
  = f.submit
Springer answered 7/9, 2014 at 9:29 Comment(1)
@Adam Cooper This is nice for a single attribute_name, but when you have more than one globalize_attribute_names.each do |lang| turns into a stream of all attributes and all languages. Say, 5 times 7, and it looks like soup. Are there any helpers to sort matters out?Duckweed
C
3

Have you considered something like this?

<%= form_for(@post) do |f| %>
     <%= f.error_messages %>

    <% [:en, :es, :fr].each do |lang| %>
      <h2><%= lang %> translation</h2>
      <% f.globalize_fields_for lang do |g| %>
        <% [:title, :teaser, :body].each do |field| %>
          <p><%= g.text_field field %></p>
        <% end %>
      <% end %>
      <hr/>
    <% end %>
<% end %>

You should be able to get those lists of regions and fields automatically. Then you only need a map of region to language name, like { en: 'English', es: 'Spanish', fr: 'French'} and you can output the proper language name instead of the region code. (This might already be available somewhere as well.)

Cataplasia answered 22/10, 2013 at 20:44 Comment(6)
<p><%= g.text_field :title %></p> should be <p><%= g.text_field field %></p>Nianiabi
i exactly copy ur code but it still says "undefined method `globalize_translations' for"September
is this a separate solution for i18n or can it be used with combination of globalize. i am using only two languages :en and :ar and i can easily translate posts when locale is set but i want both forms on same page so i am using ur code in my views/posts/new.html.erb. sorry if it is stupid question.September
Hi Murtza, all I've done is taken your code from above and removed the repetitive parts; I'm not familiar with globalize.Cataplasia
<% [:en, :es, :fr].each do |lang| %> could be <% {en:'English',es:'Spanish',fr:'French'}.each do |sym,lang| %> that way the mapping is done in a hash and can be used with your h2 for and then <% f.globalize_fields_for sym do |g| %>Nianiabi
Yep, that would work fine. (My hope was that a hash mapping locale to language already existed somewhere, e.g groups.google.com/forum/m/#!topic/rails-i18n/cFbxHcOVfnA)Cataplasia

© 2022 - 2024 — McMap. All rights reserved.