Sök…


Syntax

  • I18n.t ( "nyckel")
  • I18n.translate ("key") # motsvarande I18n.t("key")
  • I18n.t ("nyckel", räknas: 4)
  • I18n.t ("nyckel", param1: "Något", param2: "Annars")
  • I18n.t ("existerar inte", standard: "nyckel") # ange en standard om nyckeln saknas
  • I18n.locale # =>: sv
  • I18n.locale =: sv
  • I18n.default_locale # =>: sv
  • I18n.default_locale =: sv
  • t (". nyckel") # samma som I18n.t("key") , men scoped till åtgärden / mallen den heter från

Använd I18n i vyer

Förutsatt att du har den här YAML-språkfilen:

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

och du vill visa din titelsträng kan du göra det

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

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

I18n med argument

Du kan skicka parametrar till I18n t metoden:

# 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) %>

Och få följande utgång:

"12 users currently online"

pluralise

Du kan låta I18n hantera pluralisering för dig, använd bara count argument.

Du måste ställa in din språkfil så här:

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

Och sedan använda nyckeln du just har skapat genom att skicka count argument till I18n.t hjälpare:

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

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

Ställ in språk genom förfrågningar

I de flesta fall kanske du vill ställa in I18n språk. Man kanske vill ställa in landskapsområdet för den aktuella sessionen, den aktuella användaren eller baserat på en URL-parameter. Det är lätt att uppnå genom att implementera en before_action i en av dina kontroller, eller i ApplicationController att ha den i alla dina kontroller.

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-baserade

Den locale parametern kan komma från en URL som denna

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

Eller

http://yourapplication.com/en/products

För att uppnå det senare måste du redigera dina routes och lägga till en scope :

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

Genom att göra detta kommer du att besöka http://yourapplication.com/en/products ställa in ditt land till :en . I stället kommer du att besöka http://yourapplication.com/fr/products :fr . Dessutom får du inte ett routingsfel när du saknar parametern :locale , eftersom besöket http://yourapplication.com/products kommer att ladda standardinställningen för I18n .

Session-baserad eller uthållighet-baserad

Detta förutsätter att användaren kan klicka på en knapp / språkflagga för att ändra språk. Åtgärden kan väg till en controller som ställer in sessionen till det aktuella språket (och så småningom kvarstår ändringarna i en databas om användaren är ansluten)

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

Du måste definiera sanitize_language_param med din lista över tillgängliga språk och så småningom hantera fel om språket inte finns.

Om du har mycket få språk kan det vara värt att definiera dem så här istället:

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

Obs! Glöm inte att lägga till några rutter till dina åtgärder för att change_language

Standardinställning

Kom ihåg att du måste ställa in din applikations standardinställning. Du kan göra det genom att antingen ställa in det i config/application.rb :

config.i18n.default_locale = :de

eller genom att skapa en initialisering i mappen config/initializers :

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

Hämta språk från HTTP-förfrågan

Ibland kan det vara användbart att ställa in din applikationsinställning baserad på IP-förfrågan. Du kan enkelt uppnå detta med Geocoder . Bland de många saker Geocoder gör, kan det också tala om location för en request .

Lägg först Geocoder till din Gemfile

# Gemfile
gem 'geocoder'

Geocoder tillägger location och safe_location metoder för standard Rack::Request objekt så att du enkelt kan slå upp platsen för varje HTTP-begäran från IP-adress. Du kan använda dessa metoder i en before_action i din 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

Se upp för att detta inte fungerar i development och test , eftersom saker som 0.0.0.0 och localhost är giltiga Internet-IP-adresser.


Begränsningar och alternativ

Geocoder är mycket kraftfull och flexibel, men måste konfigureras för att fungera med en geokodningstjänst (se mer information ); av vilka många begränsar användningen. Det är också värt att tänka på att att ringa en extern tjänst på varje begäran kan påverka prestandan.

För att hantera dessa kan det också vara värt att överväga:

1. En offline-lösning

Genom att använda en pärla som GeoIP (se här ) gör det möjligt för uppslag att hända mot en lokal datafil. Det kan finnas en avvägning när det gäller noggrannhet, eftersom dessa datafiler måste hållas uppdaterade.

2. Använd CloudFlare

Sidor som visas via CloudFlare har möjlighet att geokodas öppet, med landskoden läggs till i rubriken ( HTTP_CF_IPCOUNTRY ). Mer information finns här .

Översättning av ActiveRecord-modellattribut

globalize pärla är en utmärkt lösning för att lägga till översättningar till dina ActiveRecord modeller. Du kan installera det och lägga till detta i din Gemfile :

gem 'globalize', '~> 5.0.0'

Om du använder Rails 5 måste du också lägga till activemodel-serializers-xml

gem 'activemodel-serializers-xml'

Med modellöversättningar kan du översätta dina modellers attributvärden, till exempel:

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

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

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

När du har definierat dina modellattribut som måste översättas måste du skapa en översättningstabell genom en migrering. globalize ger create_translation_table! och drop_translation_table! .

För denna migrering måste du använda up och down och inte change . För att köra migreringen framgångsrikt måste du först definiera de översatta attributen i din modell, som visas ovan. En korrekt migrering för den föregående Post är denna:

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

  def down
    Post.drop_translation_table!
  end
end

Du kan också välja alternativ för specifika alternativ, som:

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

Om du redan har befintliga data i dina behov av översättningskolumner, kan du enkelt migrera dem till översättningstabellen genom att justera din migrering:

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

Se till att du tappar de översatta kolumnerna från överordnade tabeller efter att alla dina data har migrerats säkert. För att automatiskt ta bort de översatta kolumnerna från överordnade tabeller efter datamigreringen, lägger du till alternativet remove_source_columns till migreringen:

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

Du kan också lägga till nya fält i en tidigare skapad översättningstabell:

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

Använd I18n med HTML-taggar och symboler

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

Notera tillägg av extra _html efter namnet title .

Och i vyer,

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


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow