Rails i18n library powerful กว่าที่มอง ไม่ต้องใช้แค่ translation i18n useful ที่ไหนก็ตามที่อยาก decouple text ที่แสดง จากที่แสดงมัน
ระหว่างอยู่ที่ Avvo ใช้ i18n ทำ cool stuff เยอะ จะ share สิ่งที่เรียนรู้และช่วยได้ พร้อม crazy abuse ของ library ที่ผลลัพธ์ออกมาเก๋บมาก
Automatic HTML Escaping
มี lines แบบนี้ใน views ไหม?
<%= raw(t('form.required_field_header')) %> ไม่ต้อง raw เพราะถ้า translation key ลงท้าย _html ได้ escaping ฟรี:
<%= t('form.required_field_header_html') %> เรียบง่าย และ consistent กับ t() calls อื่นๆ
Accessing Locales สะดวกกว่า
ตอนสร้าง locale files จะมี keys บางส่วน grouped under parent เดียวกัน:
en: bugs: index: new_label: "File a new bug" edit_label: "edit" delete_label: "delete" Reference หลายๆ ตัวด้วย full key ได้:
<%= t('bugs.index.edit_label') %> | <%= t('bugs.index.delete_label') %> ค่อนข้าง annoying และ repetitive แต t() รับ scope ช่วย reference keys สะดวกกว่า:
<% bugs_scope = 'bugs.index' -%> <%= t('edit_label', scope: bugs_scope) %> | <%= t('delete_label', scope: bugs_scope) %> ถ้าตั้งชื่อ partials ดี ไม่ต้องระบุ scope:
<%= t('.edit_label') %> | <%= t('.delete_label') %> นั่นคือ .edit_label reference bugs.index.edit_label เพราะอยู่ใน bugs/index.html.erb
ActiveRecord Backends
บางครั้ง static translations ใน yaml ไมพอ ถ้าใช้ ActiveRecord i18n backend แทน:
require 'i18n/backend/active_record' I18n.backend = I18n::Backend::ActiveRecord.new ค้นหา translations ในตาราง translations ใน database ได้ ไม่ต้อง define translations ทั้งหมดล่วงหน้า เพิ่ม translations ใหม่ on the fly ได้
Setup translations table ต้อง migration เฉพาะ README บน i18n-active_record repo มี info ครบ
Sharing Partials ระหว่าง Object Types
ที่ Avvo มี lawyer directory, attorney reviews, legal advice แตไม่กี่ปีก่อน ไมได้แค่ lawyers บน site มี doctors และ dentists ด้วย!
UI มาก part เหมือนกันระหว่าง professions แตต่างพอ (lawyers เรียก "practice areas" doctors เรียก "specialties") ยาก share views/partials เดียวกันโดยไม่ ugly code
คิดว่า lean บน i18n system ได้ English lawyerese คือ dialect ของ English และ doctorese เหมือนกัน ไมอยาก block ตัวเองจาก languages อื่นภายหลัง สร้าง locales ใหม่ 2 ตัว: en_jd และ en_md
Setup ง่ายเป็น custom i18n backend:
class AvvoI18nStore < I18n::Backend::Simple def translate(locale, key, options = {}) begin default = options.delete(:default) super(locale, key, options) rescue I18n::MissingTranslationData => e # fall back to "en" ถ้าไม่เจอใน "en_jd" ฯลฯ fallback_locale = locale.to_s.split("_").first super(fallback_locale, key, options.merge(:default => default)) end end end I18n.backend = AvvoI18nStore.new Define translations ง่ายเท่าเดิม:
en_jd: practice_area: "practice area" en_md: practice_area: "specialty" ใช้ได้ดีสำหรับ translate partials ทั้งหมด (ดู filename):
<!-- Lawyer badge HTML --> <!-- Doctor badge HTML --> และ fallback ไป en locale สำหรับ shared translations:
en: leaderboard: title: "Leaderboard" ตอนอยู่ section "Doctors" เปลี่ยน default locale เป็น :en_md และ vice versa:
I18n.locale = :en_md ทุกอย่าง just worked!
ไม่แน่ใจว่าจะ recommend มัน ค่อนข้าง nuts คิดว่า professions ต่างๆ มี languages ต่างกัน แตทำงานเก๋บมากตอนทำ และมัน reveal ว่า simple tools อย่าง i18n มี power มากแค่ไหน
Where Do You Pick Up This Stuff?
สัปดาห์ก่อนพูดถึง deep dives ลง technologies เพื่อจาก beginner สู่ expert นี่อีกตัวอย่าง: ส่วนใหญ่ i18n ที่เรียนรู้มาจากอ่าน Rails guides และ API docs
ให้ก้าวเพิ่ม เรียนรู้ tools ที่พึ่งพา ให้ดี จะพบ conveniences และ tricks ที่ไม่แค่ทำให้ productive แตอาจ unlock categories ใหม่ของ solutions ที่ไม่เคยคิดถึง