Question

In a Rails 4 multidomain app, I would need a set of locale files for 4 languages for each domain (3 domains total).

Some of the translations overlap between the domains but some of them are very specific, so I am thinking about a structure that would go somewhat like this:

config/locales/en.yml ..fr.yml ..de.yml ..it.yml  #is picked up by all domains
config/locales/domain1/en.yml ..fr.yml ..de.yml ..it.yml  #is picked up by domain 1
config/locales/domain2/en.yml ..fr.yml ..de.yml ..it.yml  #is picked up by domain 2
config/locales/domain3/en.yml ..fr.yml ..de.yml ..it.yml  #is picked up by domain 3

Is this possible in Rails 4? And if so what would be the best way to go about this setup?

Was it helpful?

Solution

in config/application you would have:

some_domain = Rails.root.basename.to_s # this will give us "myapp.com" if the app is in "/var/www/myapp.com"
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', some_domain, '*.{rb,yml}').to_s]

this will load only the required files and should overwrite any duplicate keys with the later data, but i haven't tested that bit.

OTHER TIPS

Please try with i18n-active_record.in that all the locales we can store it in database.

in this gem they are using translation model with no relation,in your case you could create relation between relation and domain,then you could store all locales with domain based when getting locales you could overwrite default gem method.

==> your keys should contain use domain name for find the domain or you can use some other way to get the domain name like in thread or env you can save your value.

# my guess key should be login-label-test.com domain = Domain.where(:name => namespace.split("-").last).first

inside gem where ever they are finding translation just overwrite that method please try it.

i am not sure please try once like that

first migrate your locale file to db

require 'yaml'

namespace :locale do
 desc "Copy translations from yml yo db. Non-overwriting."
  task :yml_to_db, [:environment, :locale,:domain] => :environment do |t, args|
    info = YAML::load(IO.read("#{Rails.root}/config/locales/#{args[:locale]}-#{args[:domain]}.yml"))
    domain = Domain.where(:name => args[:domain]).first
    info["#{args[:locale]}"].each do |key, value|
    translation = domain.translations.where(:key => key)
    domain.translations.create!(:key => key, :value => value, :locale => args[:locale]) if translation.blank?
   end
  end
 end

i have tried to overwrite one method in gem :

require 'active_record'

  module I18n
   module Backend
   class ActiveRecord
    class Translation < ::ActiveRecord::Base

    belongs_to :domain

    TRUTHY_CHAR = "\001"
    FALSY_CHAR = "\002"

    self.table_name = 'translations'

    serialize :value
    serialize :interpolations, Array

      def lookup(keys, *separator)
        # in your keys should contain use domain name for find the domain or you can use some other way to get the domain name like in thread or env you can save your value.

        column_name = connection.quote_column_name('key')
        keys = Array(keys).map! { |key| key.to_s }

        unless separator.empty?
          warn "[DEPRECATION] Giving a separator to Translation.lookup is deprecated. " <<
            "You can change the internal separator by overwriting FLATTEN_SEPARATOR."
        end

        namespace = "#{keys.last}#{I18n::Backend::Flatten::FLATTEN_SEPARATOR}%"
        # my guess key should be login-label-test.com
        domain =  Domain.where(:name => namespace.split("-").last).first
        where("#{column_name} IN (?) OR #{column_name} LIKE ?", keys, namespace).where(:id => domain.id)
       end
   end
  end
 end

Please try like this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top