Multi lang support?


(Bricesanchez) #1

Hello,

Thanks for your awesome contribution to the Rails community!

What are your plans to support multi lang websites? Will you use Globalize?

Thanks!

Brice


(Netzc) #2

Seconded!

I have a pretty dirty hack in place so far:

I have an array of languages I support in application.rb

config.available_locales = [
	{name: 'german', abbr: 'de'},
	{name: 'english', abbr: 'en'}
]

Then I create the user-facing fields for my node types for both languages, for example in my node type “feature”:

Rails.configuration.available_locales.each do |locale|
  field "#{locale[:abbr]}_headline".to_sym, :string
  field "#{locale[:abbr]}_body".to_sym, :wysiwyg
end

… which I admit is b*tt-ugly!

Then I monkey-patched PushType::Node to have a translation helper:

module PushType
  class Node < ActiveRecord::Base
    def t(field)
	self.send("#{I18n.locale}_#{field}")
    end
  end
end

and in the view I just call this:

#haml:
%h2= @feature.t('headline')
%div= @feature.t('body')

I understand, this is in dire need of a refactor :slight_smile:


(Aaron Russell) #3

@bricesanchez thank you.

My immediate focus over the coming months is the admin UI. That’s going to receive an overhaul and redesign and I’ll use the opportunity to add better i18n support throughout the UI.

In terms of supporting multi-lingual sites, truth is there are no plans as yet. I’m not very familiar with Globalize but at a glance I’m not sure if that might make things more complicated than it needs to be. As @netzc has figured, you can just add a new field for each of the locales and hack a solution. An approach like that could be packaged in a dedicated field type.

Imagine something like this:

field :body, :multilang, type: :wysiwyg, langs: [:en, :es]

Internally a JSON structure looking something like this:

{
  "body": {
    "en": "Hello",
    "es": "Ola"
  }
}

And no need for any helper methods because in our multilang field type we can override FieldType#value with:

def value
  json_value[I18n.locale]
end

Oh, and a UI that presents the multiple fields in a friendly way…


(Bricesanchez) #4

Thanks @netzc and @aaron for your answers, i will take a closer look on your project soon :slight_smile:


(Netzc) #5

Quick follow up …

@aaron was kind enough to point out how to create “hard-coded” presenter classes for node types here, which have turned out to be an excellent place to handle multilanguage stuff in a still hacky, but a little cleaner way until I wrap my brain around creating a dedicated field type for this.

Get the current locale in the presenter class with h.locale.


(Aaron Russell) #6

Until such a time as there’s a dedicated multilang field, here’s a good temporary solution.

1. Create a Structure for each of the field types you want to translate. Eg:

$ rails g push_type:structure multilang_wysiwyg
class MultilangWysiwyg < PushType::Structure
  [:en, :es, :de].each do |lang|
    field lang, :wysiwyg
  end
end

2. Use your multilang structures in nodes where needed

class Page < PushType::Node
  field :body, :structure, class: :multilang_wysiwyg
end

3. Generate a presenter and override your multilang method

$ rails g push_type:presenter page
class PagePresenter < PushType::Presenter
  def body
    super.send(I18n.locale)
  end
end

If you’ve got lots of languages to support, or are just unsatisfied with how the admin UI displays multiple fields like this, it’s possible to create your own html component as a view and pass it as an option to the field, eg:

field :body, :structure, class: :multilang_wysiwyg, template: 'multilang_component'