I have a rails app the uses the standard i18n translations gem. It's a multi-tenant app and relies on parsing the current tenant from the subdomain.
en:
foo:
bar: "Welcome to %{subdomain}"
I have a few keys (e.g. subdomain above) that I'm using very often in my translations. In my view I have to keep passing in the same key in various places
t("foo.bar", subdomain: current_subdomain)
Is there a way I can specify a default set of keys (like subdomain) that are always passed to the translations by default so I don't have to type it out all the time?
Thanks!
I'm using gem route_translator for some solutions.
Related
What I would like to do is utilize the I18n localization structure to handle organziation-specific naming schemas, independently of the users actual local. Something like:
Default Naming Schema
show.en.yml
en:
show:
title: Component
Organization A Nameing Schema
show.org_a.yml
org_a:
show:
title: Widget
Organization B Nameing Schema
show.org_b.yml
org_b:
show:
title: Sprocket
I've tried to just set a custom local using I18n.locale = organziation.slug.to_sym || I18n.default_locale (where slug would be org_a, org_b, etc.), but that just yields a :org_a is not a valid locale error. Unfortunately, searching for possible solutions has not been all that fruitful.
Is there a way to add custom locals, or should I be approaching this problem a different way (using Rails 6)?
This works in Rails 4.2 (since that is what I have easy access to right now) to allow for custom locales but it should work for Rails 6 as well (or something similar to this):
I18n.available_locales = I18n.available_locales + [:org_a, :org_b]
I18n.locale = organziation.slug.to_sym || I18n.default_locale
Maybe append to the available locales early on in a config file, or similar.
I want to match the locale code to the specific language name. Is there any build in function in I18n/rails which would return the language name to the corresponding locales. Is installing a gem is the only way?
It seems there is no method for this in I18n.
If you just need current language name, you can easily include it in corresponding locale file:
# config/locales/en.yml
en:
language_name: "English"
And get it as usual: I18n.t('language_name') or I18n.t('language_name', locale: :en).
For general purposes you could use: https://github.com/hexorx/countries or initialize your own mapping as a ruby hash: { en: 'English', ... }.
Without installing an additional gem, you could make your own key/value pairs (either store it in a json file or store it to DB) and then lookup key eg "de" and read the value (in this case, "German"). It requires a bit of manual work (or setup a rake task or something to build it for you in appropriate format from some info source) but you aren't dependent on an additional gem in that case (which, without going thoroughly through the code, might have a far greater impact on your app performance/memory wise than your custom implementation for your specific need for all you know).
I am not aware of any rails built in functions that would return the entire language name, though. You can return the language abbreviation (eg for use in html lang attribute), but I think it stops there as far as the built in functions are concerned).
Have a look the following post in google groups (Gist). I hope there is no default support for the required conversion in rails.
I have internationalized and localized my application using the standard rails mechanisms.
Everything is stored in en, fr, de.yml files.
My application is multi-tenant, based on the subdomain.
I would like to allow my users to override certain translations in the application (e.g. to change "Employee" to "Associate" because it matches their own terminology).
I've tried to change the load path of my yml files on a per-request basis, but to no avail.
Any idea how I could, for each request, look up first in my user-specific yaml file, and fall back to the default yaml file if the translation was not overriden?
Assuming you store the subdomain in an instance variable from a controller filter, you could override the translation helper to do a lookup with a subdomain-specific scope first, then fallback to the specified or default scope. Something like this:
module ApplicationHelper
def t(key, original_options = {})
options = original_options.dup
site_translation_scope = ['subdomain_overrides', #subdomain.name]
scope =
case options[:scope]
when nil
site_translation_scope
when Array
options[:scope] = site_translation_scope + options[:scope]
when String
[site_translation_scope, options[:scope]].join(".")
end
translate(key, options.merge(:scope => scope, :raise => true))
rescue I18n::MissingTranslationData
translate(key, original_options)
end
end
Then you add your subdomain-specific overrides likes this:
en:
customer: Customer
subdomain_overrides:
subdomain_1:
customer: Buyer
If you want to allow tenants to use specific language but fallback to the default, I have written a micro library that will get the job done:
https://github.com/ElMassimo/i18n_multitenant
It takes care of configuring I18n to fallback to the base locale, allowing you to use tenant-specific translations if available. It's designed to work with the default backend of static .yml files, but it should also work with other I18n backends.
I've recently created I18n_global_scope gem that does exactly what you are describing, please checkout the source code https://github.com/mobilityhouse/i18n_global_scope and let me know your feedback.
I have a Rails 3 app in which I'm using I18n.available_locales to display a list of available languages for user accounts. In my config/locales directory I only have en and nl yml files, however, I18n.available_locales returns a variety of other locale keys which I'm assuming are present due to translations being present in the gems that I'm using. Is there a common/standard way to get the method to only return the translations present in the app itself?
I would suggest, you use this gem : rails-i18n , it provides basic translations for every languages, and then, restrict available locales with
config.i18n.available_locales = ['es-CO', :de]
Of course, rails-i18n is not mandatory here, you could simply define available_locales in your config/application.rb file
And as said in the comments, you should definitely accept some answers to improve your accept_rate
Hoping some learned Rails developers here can recommend an existing Ruby on Rails plugin or gem that allows you to continue using the Simple I18n backend whilst allowing you to optionally specify translations in the database.
Here's why:
I have one Rails app used for many websites. For the example I'll just use 2 websites:
Website 1: Leprechauns R Us
Website 2: Unicorns R Us
Most translations are the same for both websites, but occassionally I want to override a translation. For example, in my en-US.yml file I have the following translation:
view_all: View all
And for most websites this translation is fine, including for website 1 (Leprechauns) where I'm happy to use "View all".
However, for website 2, I'd like to use "View all Unicorns" as the view_all translation and I'd like to specify this in the database. For maintenance reasons I don't want to specify this override in a YAML file.
Many thanks,
Eliot
In the end I opted to take advantage of Rails' I18n::Backend::Simple's ability to process both .yml files and .rb files as locale dictionaries.
Artifacts created:
DB migration to create a translations table with columns: locale, key, text
Translation model to map to the translations table
Class method to_locale_hash on Translation model that returns a locale keyed hash as required by I18n::Backend::Simple.load_rb
A single-line file located at config/translations.rb with the line 'Translation.to_locale_hash'
For the source code see the Spree extension (sorry not in a Rails plugin structure, it will be easy to move over to a plugin should you require it) here:
http://github.com/eliotsykes/spree-i18n-db/tree/master