Поиск…


Синтаксис

  • I18n.t ( "ключ")
  • I18n.translate («ключ») # эквивалентно I18n.t("key")
  • I18n.t («ключ», число: 4)
  • I18n.t («ключ», param1: «Что-то», param2: «Else»)
  • I18n.t («doesnt_exist», по умолчанию: «key») # указать значение по умолчанию, если отсутствует ключ
  • I18n.locale # =>: ru
  • I18n.locale =: ru
  • I18n.default_locale # =>: ru
  • I18n.default_locale =: ru
  • t (". key") # то же, что и I18n.t("key") , но в область действия / шаблон, из которого она I18n.t("key")

Использовать I18n в представлении

Предполагая, что у вас есть этот файл локали YAML:

# config/locales/en.yml
en:
  header:
    title: "My header title"

и вы хотите отобразить строку заголовка, вы можете сделать это

# in ERB files
<%= t('header.title') %>

# in SLIM files
= t('header.title')

I18n с аргументами

Параметры I18n t можно передать:

# Example config/locales/en.yml
en:
  page:
    users: "%{users_count} users currently online"

# In models, controller, etc...
I18n.t('page.users', users_count: 12)

# In views

# ERB
<%= t('page.users', users_count: 12) %>

#SLIM
= t('page.users', users_count: 12)

# Shortcut in views - DRY!
# Use only the dot notation
# Important: Consider you have the following controller and view page#users

# ERB Example app/views/page/users.html.erb
<%= t('.users', users_count: 12) %>

И получите следующий результат:

"12 users currently online"

плюрализация

Вы можете позволить I18n обрабатывать плюрализацию для вас, просто используйте аргумент count .

Вам необходимо настроить файл локали следующим образом:

# config/locales/en.yml
en:
  online_users:
    one: "1 user is online"
    other: "%{count} users are online"

И затем используйте только что созданный ключ, передав аргумент count аргументу I18n.t :

I18n.t("online_users", count: 1)
#=> "1 user is online"

I18n.t("online_users", count: 4)
#=> "4 users are online"

Установить локаль через запросы

В большинстве случаев вы можете установить локаль I18n . Возможно, вам захочется установить локаль для текущего сеанса, текущего пользователя или на основе параметра URL. Это легко достижимо путем реализации before_action в одном из ваших контроллеров или в ApplicationController чтобы иметь его во всех ваших контроллерах.

class ApplicationController < ActionController::Base
  before_action :set_locale

  protected

  def set_locale
    # Remove inappropriate/unnecessary ones
    I18n.locale = params[:locale] ||    # Request parameter
      session[:locale] ||               # Current session
      (current_user.preferred_locale if user_signed_in?) ||  # Model saved configuration
      extract_locale_from_accept_language_header ||          # Language header - browser config
      I18n.default_locale               # Set in your config files, english by super-default
  end

  # Extract language from request header
  def extract_locale_from_accept_language_header
    if request.env['HTTP_ACCEPT_LANGUAGE']
      lg = request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first.to_sym
      lg.in?([:en, YOUR_AVAILABLE_LANGUAGES]) ? lg : nil
    end
  end

URL на основе

Параметр locale может исходить из URL-адреса, подобного этому

http://yourapplication.com/products?locale=en

Или же

http://yourapplication.com/en/products

Чтобы достичь последнего, вам необходимо изменить routes , добавив scope :

# config/routes.rb
scope "(:locale)", locale: /en|fr/ do
  resources :products
end

Поступая таким образом, посещение http://yourapplication.com/en/products установит ваш локаль в :en . Вместо этого, посетив http://yourapplication.com/fr/products он установит его :fr . Кроме того, вы не получите ошибку маршрутизации при отсутствии параметра :locale , так как посещение http://yourapplication.com/products будет загружать локаль I18n по умолчанию.

Основанный на сеансах или основанный на постоянстве

Это предполагает, что пользователь может щелкнуть по значку кнопки / языка, чтобы изменить язык. Действие может перенаправляться на контроллер, который устанавливает сеанс на текущий язык (и, в случае необходимости, сохраняет изменения в базе данных, если пользователь подключен)

class SetLanguageController < ApplicationController
  skip_before_filter :authenticate_user!
  after_action :set_preferred_locale

  # Generic version to handle a large list of languages
  def change_locale
    I18n.locale = sanitize_language_param
    set_session_and_redirect
  end

Вы должны определить sanitize_language_param со списком доступных языков и, в конечном счете, обработать ошибки, если язык не существует.

Если у вас очень мало языков, возможно, стоит их определить следующим образом:

def fr
  I18n.locale = :fr
  set_session_and_redirect
end

def en
  I18n.locale = :en
  set_session_and_redirect
end

private

  def set_session_and_redirect
    session[:locale] = I18n.locale
    redirect_to :back
  end

  def set_preferred_locale
    if user_signed_in?
      current_user.preferred_locale = I18n.locale.to_s
      current_user.save if current_user.changed?
    end
  end
end

Примечание. Не забудьте добавить некоторые маршруты к действиям change_language

Default Locale

Помните, что вам нужно установить языковой стандарт по умолчанию для вашего приложения. Вы можете сделать это, установив его в config/application.rb :

config.i18n.default_locale = :de

или путем создания инициализатора в папке config/initializers :

# config/initializers/locale.rb
I18n.default_locale = :it

Получить локаль из HTTP-запроса

Иногда бывает полезно установить локализацию вашего приложения на основе IP-адреса запроса. Вы можете легко достичь этого с помощью Geocoder . Среди многих вещей, Geocoder делает Geocoder , он также может указать location request .

Во-первых, добавьте Geocoder в свой Gemfile

# Gemfile
gem 'geocoder'

Geocoder добавляет методы location и safe_location в стандартный объект Rack::Request чтобы вы могли легко найти местоположение любого HTTP-запроса по IP-адресу. Эти методы можно использовать в before_action в ApplicationController :

class ApplicationController < ActionController::Base
  before_action :set_locale_from_request

  def set_locale_from_request
    country_code = request.location.data["country_code"] #=> "US"
    country_sym = country_code.underscore.to_sym #=> :us

    # If request locale is available use it, otherwise use I18n default locale
    if I18n.available_locales.include? country_sym
      I18n.locale = country_sym
    end
end

Помните, что это не будет работать в средах development и test , поскольку такие вещи, как 0.0.0.0 и localhost являются действительными действительными IP-адресами в Интернете.


Ограничения и альтернативы

Geocoder очень мощный и гибкий, но его необходимо настроить для работы с сервисом геокодирования (см. Подробнее ); многие из которых ограничивают использование. Также стоит иметь в виду, что вызов внешней службы по каждому запросу может повлиять на производительность.

Для решения этих проблем также стоит рассмотреть:

1. Автономное решение

Использование драгоценного камня, такого как GeoIP (см. Здесь ), позволяет выполнять поиск по локальному файлу данных. Там может быть компромисс с точки зрения точности, так как эти файлы данных должны быть обновлены.

2. Используйте CloudFlare

Страницы, обслуживаемые CloudFlare, имеют возможность геокодирования прозрачно, причем код страны добавляется в заголовок ( HTTP_CF_IPCOUNTRY ). Более подробную информацию можно найти здесь .

Перевод атрибутов модели ActiveRecord

globalize gem - отличное решение для добавления переводов в ваши модели ActiveRecord . Вы можете установить его, добавив это в свой Gemfile :

gem 'globalize', '~> 5.0.0'

Если вы используете Rails 5 вам также нужно будет добавить activemodel-serializers-xml

gem 'activemodel-serializers-xml'

Моделирование переводов позволяет вам переводить значения атрибутов ваших моделей, например:

class Post < ActiveRecord::Base
  translates :title, :text
end

I18n.locale = :en
post.title # => Globalize rocks!

I18n.locale = :he
post.title # => גלובאלייז2 שולט!

После того, как вы определили свои атрибуты модели, которые нужно перевести, вам нужно создать таблицу переводов через миграцию. globalize предоставляет create_translation_table! и drop_translation_table! ,

Для этой миграции вам нужно использовать up и down , а не change . Кроме того, чтобы успешно выполнить эту миграцию, сначала необходимо определить переведенные атрибуты в своей модели, как показано выше. Правильная миграция для предыдущей модели Post :

class CreatePostsTranslationTable < ActiveRecord::Migration
  def up
    Post.create_translation_table! title: :string, text: :text
  end

  def down
    Post.drop_translation_table!
  end
end

Вы также можете передавать параметры для определенных параметров, например:

class CreatePostsTranslationTable < ActiveRecord::Migration
  def up
    Post.create_translation_table! title: :string,
      text: { type: :text, null: false, default: "Default text" }
  end

  def down
    Post.drop_translation_table!
  end
end

Если у вас уже есть какие-либо существующие данные в ваших столбцах перевода, вы можете легко перенести их в таблицу переводов, регулируя миграцию:

class CreatePostsTranslationTable < ActiveRecord::Migration
  def up
    Post.create_translation_table!({
      title: :string,
      text: :text
    }, {
      migrate_data: true
    })
      
  end

  def down
    Post.drop_translation_table! migrate_data: true
  end
end

Убедитесь, что вы удалили переведенные столбцы из родительской таблицы после того, как все ваши данные безопасно перенесены. Чтобы автоматически удалить переведенные столбцы из родительской таблицы после переноса данных, добавьте параметр remove_source_columns в перенос:

class CreatePostsTranslationTable < ActiveRecord::Migration
  def up
    Post.create_translation_table!({
      title: :string,
      text: :text
    }, {
      migrate_data: true,
      remove_source_columns: true
    })
      
  end

  def down
    Post.drop_translation_table! migrate_data: true
  end
end

Вы также можете добавить новые поля в ранее созданную таблицу переводов:

class Post < ActiveRecord::Base
  # Remember to add your attribute here too.
  translates :title, :text, :author
end

class AddAuthorToPost < ActiveRecord::Migration
  def up
    Post.add_translation_fields! author: :text
  end

  def down
    remove_column :post_translations, :author
  end
end

Использовать I18n с HTML-тегами и символами

# config/locales/en.yml
en:
  stackoverflow:
    header:
      title_html: "Use <strong>I18n</strong> with Tags &amp; Symbols"

Обратите внимание на добавление дополнительного _html после названия title .

И в Представлениях,

# ERB
<h2><%= t(:title_html, scope: [:stackoverflow, :header]) %></h2>


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow