internationalization (i18n)static.edu.panter.ch/attachments... · 2014-10-18 · i18n bedeutet:...

Post on 07-Aug-2020

3 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Internationalization (I18n)

Ziele

Begriff "Internationalization"

Unterscheidung der anzupassenden Inhalte

Einsatz Ruby on Rails

Programmieraspekte, um Internationalisierung zu ermöglichen

Was muss internationalisiert werden?

Typische Übersetzungen in Webapplikationen

Texte in Templates

Lokalisierte Texte (Zeit, Datum, Währung, Nummernformat)

Fehlermeldungen

Model Klassen Namen und Felder Namen

URLs

Bilder, Logos

CSS

Inhalte von Feldern

Quellen der Übersetzungen

Texte in Templates: Programmierung

Lokalisierte Texte (Zeit, Datum, Währung, Nummernformat): Programmierung

Fehlermeldungen: Programmierung

Model Klassen Namen und Felder Namen: Programmierung

URLs: Programmierung

CSS: Programmierung / Grafiker

Bilder, Logos: Grafiker

Inhalte von Feldern: Datenbank

Übersetzungen und REST

shop.com/product?locale=de - shop.com/product?locale=en

shop.com/de/product - shop.com/en/product

your.shop.ch/product - your.shop.com/product

de.shop.com/product - en.shop.com/product

HTTP Header: Accept-Language: de, en-gb;

Nicht! session[:locale] = :de

Konfigurationsfile in Ruby

Verwendete Lokalisationen und Defaulteinstellung.File muss als UTF-8 gespeichert sein!

Anstelle von UTF-8 kann auch HTMLencoding verwendet werden, aberunübersichtlich:

1. #encoding: utf-82. I18n.default_locale = :en3. 4. LANGUAGES = [5. ["English", 'en'],6. ["Español", 'es'], 7. ["日本語", 'ja']8. ]

1. I18n.default_locale = :en2. 3. LANGUAGES = [4. ["English", 'en'],5. ["Español".html_safe, 'es'], 6. ["日本語".html_safe, 'ja']7. ]

Umsetzung Routing

1. Depot::Application.routes.draw do2. ...3. scope '(:locale)' do resources :orders4. resources :line_items5. resources :carts6. ...7. end8. end

Umsetzung Controller

1. class ApplicationController < ActionController::Base2. before_action :set_i18n_locale_from_params3. 4. # ...5. 6. def set_i18n_locale_from_params7. if params[:locale]8. if I18n.available_locales.map(&:to_s).include?(params[:locale])9. I18n.locale = params[:locale]10. else11. flash.now[:notice] =12. "#{params[:locale]} translation not available"13. logger.error flash.now[:notice]14. end15. end16. end17. 18. end

Übersetzungen im View Layer

1. <%= @page_title || t('.title') %>2. <%= t('.home') %>3. <%= button_to t('.add_html'), line_items_path(product_id: product), ...

Übersetzungen pflegen

/config/locales/en.yml

1. en:2. store:3. index:4. title_html: "Your Catalog"5. add_html: "Add to Cart"6. ...

1. de:2. store:3. index:4. title_html: "Ihr Katalog"5. add_html: "Zum Warenkorb hinzufügen"6. ...

Zahlen, Währungen, Datumsformate etc.

/config/locales/en.yml

1. date:2. formats:3. short_datetime: "%B %d, %Y"4. normal_datetime: "%m/%d/%Y"5. 6. number:7. currency:8. format:9. unit: "$"10. precision: 211. separator: "."12. delimiter: ","13. format: "%u%n"

1. <%= l Date.today , :format => :short_datetime %>

Häufig gebrauchte Übersetzungen und Formatierungen

https://github.com/svenfuchs/rails-i18n/tree/master/rails/locale

de-CH: date: abbr_day_names: - So - Mo ... abbr_month_names: - - Jan - Feb - Mär day_names: - Sonntag - Montag - Dienstag ... formats: default: ! '%d.%m.%Y' long: ! '%e. %B %Y' short: ! '%e. %b' month_names: - - Januar - Februar - März - April ... distance_in_words: about_x_hours: one: etwa eine Stunde other: etwa %{count} Stunden about_x_months: one: etwa ein Monat other: etwa %{count} Monate about_x_years: one: etwa ein Jahr other: etwa %{count} Jahre ...

Keine algorithmische Stringkonstruktionen!

Definition der Texte als ganze, parametrisierte Texte:

Verschiedene Textbausteine, um Plural abzufangen

1. #Richtig2. message: "You have ordered %{count} on %{orderDate}"3. ...4. <%= t('.message', count: myCount, orderDate: myDate) %>5. 6. #Falsch7. part1: "You have ordered"8. part2: "items on "9. ...10. <%= t('.part1') + myCount + t('.part2') + myDate %>

Fehlermeldungen

/config/locales/de.yml

1. activerecord:2. errors:3. messages:4. inclusion: "ist nicht in der Liste vorhanden"5. blank: "ist leer"6. errors:7. template:8. body: "Die Einträge in folgenden Feldern sind fehlerhaft:"9. header:10. one: "Aufgrund eines Fehlers kann %{model} nicht gespeichert werden"11. other: "Aufgrund von %{count} Fehlern kann %{model} nicht gespeichert

werden"12.

Locale-Switcher

1. <%= form_tag store_path, class: 'locale' do %>2. <%= select_tag 'set_locale', 3. options_for_select(LANGUAGES, I18n.locale.to_s),4. onchange: 'this.form.submit()' %>5. <%= submit_tag 'submit' %>6. <%= javascript_tag "$('.locale input').hide()" %>7. <% end %> 8.

1. def index2. if params[:set_locale]3. redirect_to store_url(locale: params[:set_locale])4. else5. @products = Product.order(:title)6. end7. end

Übersetzungen von Inhalten

Inhalte gespeichert in Datenbank

Erst zur Laufzeit bekannt

Spezielle Datenbank Designs, z.B Übersetzungstabellen1. class Post < ActiveRecord::Base2. translates :title, :text3. end

1. class CreatePosts < ActiveRecord::Migration2. def up3. create_table :posts do |t|4. t.timestamps5. end6. Post.create_translation_table! :title => :string, :text => :text7. ...

Konzepte der I18n in Java

Internationalisierungs-APIs funktionieren oft ähnlich

1. Locale deCh = new Locale("de", "CH")

1. # This is the LabelsBundle_de.properties file2. s1 = Computer3. s2 = Platte4. s3 = Monitor5. s4 = Tastatur

1. ResourceBundle labels = ResourceBundle.getBundle("LabelsBundle", currentLocale);2. String value = labels.getString(key);

Ein Beispiel aus der Praxis (JavaScript)

Default Fallbacks falls Übersetzungstext nicht verfügbar:

1. Defaultsprache, z.B. Englisch

2. Technischer Name

1. qx.convertToLocale = function (txtid, lang, args) {2. 3. var englishTexts = qx.localizedStrings['en'];4. var localizedTexts = qx.localizedStrings[lang];5. 6. if (localizedTexts === undefined) {7. localizedTexts = englishTexts;8. if (localizedTexts === undefined) { return msgid; }9. 10. var localizedText = localizedTexts[txtid];11. if (localizedText === undefined ) {12. localizedText = englishTexts[txtid];13. if (localizedText === undefined) {14. localizedText = txtid;15. }16. }17. 18. if (arguments.length > 2) {19. var fmt = localizedText;20. var fmtarg = Array.prototype.splice.call(arguments, 2);21. localizedText = fmt.format(fmtarg);22. }23. 24. return localizedText;25. 26. };

Sprachabhängige Sortierung

Alphabetische Sortierung ist nicht gleich ASCII/UTF-Sortierung!

Beispiel: Sortierung von schwedischen Ortsnamen:

Auf Deutsch: Auf Schwedisch:

1. Åkersberga

2. Alingsås

3. Borås

4. Göteborg

5. Örebro

6. Stockholm

1. Alingsås

2. Borås

3. Göteborg

4. Stockholm

5. Åkersberga

6. Örebro

Collator-Klasse in Java, localeCompare in JavaScript ...

Noch extremer in fernöstlichen Sprachen wie Japanisch

Aufgepasst bei dynamisch erzeugten Katalogen

Ein schlechtes Beispiel, gesehen bei einem grossen internationalen Softwarehersteller...

Zusammenfassung

I18N bedeutet:

Übersetzen aller Texte

Anpassen von Formaten für Zahlen, Währungen, Datum etc.

Allenfalls auch CSS, Grafiken

Alle lokalisierungsspezifischen Angaben in einer Datei pro Locale

Einige Punkte sind bei der Programmierung zu beachten

Encoding / Multi-Byte-Fähigkeit

Stringmanipulation

Sprachspezifisches String-Handling

top related