Rails 4 multi-domain application with a set of locales for each i18n domain

In a multi-domain Rails 4 application, I need a set of language files for 4 languages ​​for each domain (3 domains in total).

Some of the translations overlap between domains, but some of them are very specific, so I’m thinking of a structure that will look something 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 do this setup?

+4
source share
2 answers

in config/applicationyou will 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 download only the necessary files and overwrite any duplicate keys with later data, but I have not tested this bit.

0

i18n-active_record. , locales database.

translation , relation domain, domain , gem .

== > , - , , thread env, .

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

gem, - translation, , .

, , .

locale 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

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

, .

0

Source: https://habr.com/ru/post/1537460/


All Articles