Rails: translation file not working - ruby-on-rails

I have to translate the majority of an application I am working on to Dutch. I created a du.yml file and am formatting it in the same way my en.yml file is formatted (to be sure):
en:
Hello: "Hello World"
When outputting the en.yml the application populates the text properly. However when I load the du.yml it gives me the translation not found span wrap around the desired translated material.
The steps I have taken to set this up are as follows -
added to application_controller.rb:
before_filter :set_locale
def set_locale
I18n.locale = params[:lang] if params[:lang].present?
end
This allows me to pass a param in the query-string to determine what language to use.
I then did as shown up top and added values to be translated on both the en.yml and du.yml files
I then call the values from the respective files with (for example) <%= t :hello %>. When I set english as the param (?lang=en), everything works great. However, when I put ?lang=du, I get what I mentioned before - the dreaded span tag of missing translation.
Any ideas on what I may have done wrong? Thanks!
Oh yeah..and both files are in the same directory (config/locales)

Learned that, although rails development allows you to make changes on the fly, file additions require a server re-load. Thanks to house9 for the clarification.

Related

Activeadmin custom filter label is not registering I18n locale

I have a few custom filters in my activeadmin dashboard tabs, and I have set the filter label to read its corresponding translation from 3 different translation files. This is the only translation in my app that isn't working/changing when the user toggles to a different language. When I remove the translation altogether and reload the page, the error tells me that activeadmin is indeed looking to the wrong translation file in its "translation missing" error. Does activeadmin do some sort of caching of custom filter labels? Is there a way to force lookup of locale for these labels?
I've confirmed that my set_locale is working consistently in application_controller. I've tried re-checking/force checking locale redundantly from the activadmin ruby file, but I have not done this successfully. I've tried reading the translation with varying methods from the rails docs: https://guides.rubyonrails.org/i18n.html#looking-up-translations
I also printed out I18n.locale at the top of the active admin file for the resource, and it prints out the previous language code (before the user toggle). I tried forcing the locale by passing it as the 2nd arg to the label translation as well.
def set_locale
I18n.locale = params[:locale] || I18n.default_locale
end
filter :space,
label: I18n.t('.activeadmin.labels.space_names'),
collection: proc { Space.order(:name) }
When the url includes es and all other translations are rendering in Spanish, the custom filter language is still English. When I remove the translation, the error is: TRANSLATION MISSING: EN.ACTIVEADMIN.LABELS.SPACE_NAMES
Why are these the only translations looking to the EN file?
Oh, the custom label has to be passed as a proc:
label: proc{I18n.t('.activeadmin.labels.space_names')}

Rails 4.1 locale and 'version' based on url (.com, .cz, .de, etc)

Hope somebody can point me at the right direction with this...
Basically, i have the locales setup and it works fine. However, i need to depending on how the user gets to the site (example_company.com, example_company.cz or example_company.de..) have slightly different content(views and layout).
I've managed to boil it down to a constant or env variable that if i was to run multiple instances of the site(1 for each country), i could set on the server so that i get the behaviour i need with 1 code base.
My question is, how are people dealing with this in general? is there any way i can serve all countries on the same instance and set some flag based on .com or .cz or whatever, that dictates which 'version' they get without effecting the url itself?
I already have the locales in the url and would prefer not to mix the two as i will have to support multiple languages for each version. For example, french and czech would still support english.. But if i go to the french one, i will only show 2 locales (french and english)...
Hope i managed to explain properly.. if not let me know and i will try again.
If you use Rails' built-in i18n support, you can easily select locales by TLD.
From the official Rails i18n guide:
One option you have is to set the locale from the domain name where your application runs. For example, we want www.example.com to load the English (or default) locale, and www.example.es to load the Spanish locale. Thus the top-level domain name is used for locale setting. This has several advantages:
The locale is an obvious part of the URL.
People intuitively grasp in which language the content will be displayed.
It is very trivial to implement in Rails.
Search engines seem to like that content in different languages lives at different, inter-linked domains.
You can implement it like this in your ApplicationController:
before_action :set_locale
def set_locale
I18n.locale = extract_locale_from_tld || I18n.default_locale
end
# Get locale from top-level domain or return nil if such locale is not available
# You have to put something like:
# 127.0.0.1 application.com
# 127.0.0.1 application.it
# 127.0.0.1 application.pl
# in your /etc/hosts file to try this out locally
def extract_locale_from_tld
parsed_locale = request.host.split('.').last
I18n.available_locales.map(&:to_s).include?(parsed_locale) ? parsed_locale : nil
end
Be sure to read the i18n guide in full. It covers how to use the built-in i18n support. A big advantage is you don't need separate views for each locale.

RAILS I18n: How to use # in translation key?

Here is in our yml file:
Or make up unique one like login#a.com : 'test'
But here is the error on view page for I18n.t("Or make up unique one like login#a.com"):
translation missing: zh-CN.Or make up unique one like login#a.com
What causes the missing translation of t()?
UPDATE:
Just verified that the problem was caused by # sign. Now the question becomes how to use # in translation key.
I highly recommend the Rails i18n guide for beginners.
It will help you understand how to structure your files, how to setup routes to support a locale param, how to set the locale, and other useful tips.
The t helper is not intended to take a string of text to translate. It takes a yaml key and outputs the translated text from a locale file.
You want to structure your yaml file as such:
config/locales/en.yml
en:
some_key: hello world
config/locales/cn.yml
cn:
some_key: hello in Chinese
Then using it in your views
<%= t :some_key %>
Based on the I18n.locale setting, the t helper will look up :some_key in the corresponding locale file and output the translated text.

What is the simplest way to make a group of methods available to several Rails applications

tl;dr
What's a simple way I can create a view helpers module I can use in many apps?
What file, located where, loaded how?
I'm on Rails 2.3.11.
I have a bunch of view helper methods. Here's an example of one of them:
# Render form input fields to add or edit a ZIP code.
def render_zip_code_fields( model_instance )
# Bla bla bla ...
end
I have about 20 or so that I've developed over the years and often use in various applications. I'd like to wrap them all up in one file that I can just drop into and app and then be able to call them in my views.
Why not just copy-and-paste them into application_helper.rb? That just doesn't feel right to me. It seems like it should be a separate file.
In fact I tried creating in /lib...
# /lib/my_view_helpers.rb
module MyViewHelpers
# ...
end
And then in application_helper.rb I put...
include MyViewHelpers
But I got a lot of "uninitialized constant MyViewHelpers errors. Maybe a syntax error? I don't think I need to require my_view_helpers.rb first because it's in /lib. Everything in there gets loaded automatically, right?
So what's the right way to do this optimizing for simplicity?
Sorry this is so long. I get verbose when I'm tired.
As of Rails 3, /lib is no longer on the default load path. You will need to put the following line in the Application class in config/application.rb.
config.autoload_paths += ["#{config.root}/lib"]
An alternative would be to drop the file in app/helpers since it is a helper, after all.

Internationalizing whole text with markup in Rails 3

What's the best practice for internationalizing, say, a Terms of Service document in Rails 3? I can think of two options:
Creating a partial for each locale and choosing which one to load according to the current user's locale.
<li><%= I18n.t :tos_paragraph_1 %></li><li><%= I18n.t :tos_paragraph_2 %></li>
None of these seems like a good solution. Any ideas?
There are a few solutions, but if I were doing this for a production project, I would probably do something like the following:
Create files for your translated Terms of Services in config/locales/terms/, naming them terms.en.html, replacing en with the locale for each translation and html with the format of the file (e.g. you could use Haml, Markdown, etc.).
Create the following helper methods (put them in app/helpers/application_helper.rb to use them everywhere, but you can put them in whatever helper file you need/want):
def localized_document_for(document, locale)
raise ArgumentError.new('nil is not a valid document') if document.nil?
raise I18n::InvalidLocale.new('nil is not a valid locale') if locale.nil?
localized_document = path_for_localized_document(document, locale)
raise MissingTranslationData unless File.exists?(localized_document)
# If you're using Markdown, etc. replace with code to parse/format your document
File.open(localized_document).readlines.join
end
def path_for_localized_document(document, locale)
"#{Rails.root}/config/locales/#{document}/#{document}.#{locale.to_s}.html"
end
Now, in your views, you can use localized_document_for('terms', I18n.locale) any time you need to get the contents of the Terms of Service in the user's language. Now the code you're using to fetch the document is DRY (you can easily fetch other documents by creating another directory in config/locales and changing the value of the document argument), and your translated documents are stored in their own directory and can easily be edited (and don't depend on YAML, which brings no value to storing a single document in a file).
Note that if you wanted to do it the "Rails 3 Way," you could use the I18n::Backend::Chain (see https://github.com/svenfuchs/i18n/blob/master/lib/i18n/backend/chain.rb), and pass in I18n::Backend::Simple.new along with a custom backend that reads the files as necessary, but for a one-off deal I believe the helpers work sufficiently.
Creating a partial for each language is definitly undry.
The Rails way is the second option you suggest with a .yml for each language.
The doc provides great examples to let you organize the yml according to each page. Thus you have shortcuts for all your variables.
See http://guides.rubyonrails.org/i18n.html

Resources