Search code examples
rubyinternationalizationmongoidpadrino

i18n Padrino 0.12.2 with Mongoid 3.0.23 + Auto Locale


Repository: https://github.com/bcsantos/translate

Live instance: http://ta-translate.herokuapp.com/

Live instance admin: http://ta-translate.herokuapp.com/admin (email: [email protected] pwd: foobar)


Note

as explained below, at the moment the only way I can change locale in admin is with

set :locales, []

and refreshing both website front-end and admin. this doesn't seem to work on the live instance.

I18n.default_locale = :pt_br

in admin/app.rb is the only way I could find until now to set locale in admin, whereas

I18n.locale = :pt_br

doesn't work.

https://github.com/bcsantos/translate/blob/master/admin/app.rb


#boot.rb

Padrino.before_load do
  I18n.locale = :en
end

require 'padrino-contrib/auto_locale'

https://github.com/bcsantos/translate/blob/master/config/boot.rb

#app.rb

set :locales, [:en, :pt_br]

https://github.com/bcsantos/translate/blob/master/app/app.rb


Problem A

switch_to_lang(:lang)

isn't working in this context

%li.divider
%li
  =link_to "EN", switch_to_lang(:en)
%li.divider
%li
  =link_to "PT", switch_to_lang(:pt_br)

https://github.com/bcsantos/translate/blob/master/app/views/partials/_menu.haml

as it stands, the only ways i can find to set locale are

set :locales, [:en, :pt_br] # in front-end

I18n.default_locale = :pt_br # in admin

Problem B

is the a way to include all paths under a certain route?

the only urls that are being localized are generated by

get :image, with: [:id, :name] do
  # params[:splat] still contains whatever is entered at the end
  amenity = Amenity.find(params[:id])
  content_type amenity.picture.content_type      
  #response.headers['Content-Length'] = amenity.picture.length
  response.write(amenity.picture.read)
  response.finish
end

https://github.com/bcsantos/translate/blob/master/app/controllers/amenities.rb

which should generate http://tourapart.herokuapp.com/artworks/image/53ac2904895e9fa4f4000018/picture.jpg/picture but under the current branch in localhost gets something like

/amenities/image/5391dbdef2c796e026000001/picture.jpg?lang=en

therefore not found. is there a way to

set :locale_exclusive_paths, ['/amenities/image/']

to include all routes under that one? regex

set :locale_exclusive_paths, ['/\/amenities\/image\/*/']

isn't working.


Problem C, ...

Pages are gone, not found, and renaming the templates to include locale in filename has done nothing until this point, locale data works for links but not model attributes:

%a= link_to "#{t "links.amenities"}".upcase!, '/amenities'

works, but:

class Amenity
  include Mongoid::Document
  include Mongoid::Timestamps # adds created_at and updated_at fields

  # field <name>, :type => <type>, :default => <value>

  field :name, localize: true, :type => String
  field :description, localize: true, :type => String
  field :category, localize: true, :type => String
  field :price, localize: true, :type => Integer
  field :phone, :type => String

  mount_uploader :picture, Uploader

  field :featured, :type => Boolean

  # You can define indexes on documents using the index macro:
  # index :field <, :unique => true>

  # You can create a composite key in mongoid to replace the default id using the key macro:
  # key :field <, :another_field, :one_more ....>
end

https://github.com/bcsantos/translate/blob/master/app/models/amenity.rb

does change attribute names in admin, with this yml:

pt_br:
  models:
    amenity: 
      name: Complemento
      attributes:
        created_at: Criado em
        updated_at: Actualizado em
        name: Nome
        description: Descrição
        category: Categoria
        price: Preço
        phone: Telefone
        medium: Meio
        featured: Destacado
        picture: Imagem

but doesn't translate model names themselves

https://github.com/bcsantos/translate/blob/master/app/locale/models/amenity/pt_br.yml

finally,

url('path')

not generating localized urls, should it not?

In short,

  • only the homepage is showing in front-end;

  • the images route is broken;

  • admin does translate user onterface and model attribute names but doesn't translate model names, in menu;

  • admin does however correctly show the fields for each locale, when changed via set :locales [] (in development mode only), and data is persisted.

Solution

  • Let's try this. One step at a time.

    Use the right gem versions

    You should be using the HEAD padrino-contrib. From the latest published stable (v0.1.13) until the master, they seem to have fixed lots of bugs regarding auto_locale.

    # Gemfile
    gem "padrino-contrib", github: "padrino/padrino-contrib"
    

    Setting locales

    Forget about default_locale. It was used in older versions. Setting I18n.locale= in the before_load is the right way of doing it.

    Notwithstanding, when using auto_locale, this setting gets overridden by the first locale set in the locales variable. And it is not set at all, it defaults to en.

    That said, for the sake of consistency, I'd set I18n.locale= to the same value of the first element of the locales array. In case it is used by other libraries, e.g. generators.

    Problem A

    With the above set, switch_to_lang works as expected. All it does is append the passed lang argument to the request.path_info, thus generating:

    # GET /admin
    switch_to_lang(:en) # => /admin/en
    

    Problem B

    Yes, you can use regular expressions in the locale_exclusive_paths, but be aware that quoting a regular expression transforms it into a String. And padrino checks the type of the input to decide what to exclude.

    > "/foo/".is_a?(Regexp) # => false
    > "/foo/".is_a?(String) # => true
    > /foo/.is_a?(Regexp)   # => true
    > /foo/.is_a?(String)   # => false
    

    Problem C

    I've never used padrino-admin, so I can't help much on that. But have you tried the model_translate (or mt) view helper?

    Finally, url generates localized urls, but only for mapped routes, e.g.

    # GET /en
    # Suppose there is in your controller the following definition
    # get :index { ... }
    url("/") # => /
    url(:index) # => /en
    

    I really hope that helps. Padrino seems an interesting project, but there are still room for improvements. Should your project become more complex, i.e. more models, controllers, etc. you might consider switching it to rails.

    Best!