Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Translation Markup Language
Search
Ian McDaniel
February 20, 2016
Programming
94
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Translation Markup Language
Translation Markup Language and Universal Translation Memory
Ian McDaniel
February 20, 2016
Other Decks in Programming
See All in Programming
パスワード再設定メールのURLについて知っておこう
uyuki234
0
160
作って学ぶSpring BootのAuto Configuration / JJUG Night Seminar 2026-10-19
rshindo
0
150
Vue Fes Japan の “作る側”に関わってみて
naokihaba
0
160
Everything will be SERVERLESS — 信じて運用した10年の経験値 / Everything Will be Serverless — Lessons Learned from 10 Years of Operational Experience
seike460
PRO
1
1.1k
contenteditable と日本語入力に向き合う
colorful12
0
200
AmebaブログはKMPから卒業します
kmars0605
0
200
Agentic Software Factoryに、すごく賢いIF文を。 / super smart IF statement into the Agentic Software Factory.
rkaga
8
2.2k
3回つくってわかった、 定期実行ジョブ基盤の本質情報
takai
0
500
sbt 2.0: takeoff
eed3si9n
0
160
Domain-Driven Transformation
hschwentner
2
2.3k
SalesForceを内製化!? ~ HR事業を支える顧客管理基盤のインフラを大公開 ~
oku053
0
180
phperだってパンチカードでコーディングしたい
o0h
PRO
0
340
Featured
See All Featured
AI: The stuff that nobody shows you
jnunemaker
PRO
10
1.2k
The Limits of Empathy - UXLibs8
cassininazir
2
720
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
3.1k
My Coaching Mixtape
mlcsv
0
360
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
エンジニアに許された特別な時間の終わり
watany
109
250k
Building an army of robots
kneath
307
47k
Large-scale JavaScript Application Architecture
addyosmani
516
110k
It's Worth the Effort
3n
188
29k
How to Ace a Technical Interview
jacobian
280
24k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.7k
Art, The Web, and Tiny UX
lynnandtonic
304
22k
Transcript
Translation Markup Language Universal Translation Memory and
Michael Berkovich
Localization is
1990 (pre internet) 2016
1990 (pre internet) 2016
{ It’s
There are many standards, but little guidance. “
No universality in the current standards
Lots of translation
Repeat when new content is added or changed File management
is a
File Management • • • • •
Some companies build their own
How can we make it
What would an ideal solution look like? • Consistency •
Adaptability • Contextualization • Agility
What are the Proxy Servers Javascript based solutions SDK based
solutions
• • • • Proxy Server Solutions • • •
Good Bad
• • • • • • • • Javascript Solutions
Good Bad
• • • • • • • • • •
• • SDK Solutions
あ A SDK Flow
Caching Translations Static Cache • • • Dynamic Cache •
• •
Translation Tools
TRANSLATION MARKUP LANGUAGE
<?php tre('Hello World') ?> <%= tr('Hello World') %> TML.translate('Hello World')
TMLLocalizedString('Hello World') TML Basics
Descriptions tr('Eats shoots and leaves', 'a panda') tr('Eats shoots and
leaves', 'a violent restaurant patron')
Data Tokens tr('Hello {name}', {name: 'John'})
Data Tokens tr('Hello {user}', {user: [user_object, :name]}) Passing an object
Decoration Tokens tr('Hello [bold: World]', {bold: '<strong>{$0}</strong>'})
Decoration Tokens tr('Hello <bold>World</bold>', {bold: '<strong>{$0}</strong>'}) tr('Hello <strong>World</strong>') With HTML
Syntax or
Decoration Tokens tr('Hello <link>World</link>', {link: {‘href’:‘www.google.com’}}) link: ‘<a href=”{$href}”>{$0}</a>’ With
Predefined Default Decorators
Decoration Tokens TMLLocalizedString('Hello <bold>World</bold>', @{ @”bold”: @{ @"font": [UIFont fontWithName:@"ChalkboardSE-Bold"
size:14] } }) Using iOS Native Decoration Methods
Nested Tokens Nesting Tokens tr('Hello [bold: {name}]', {name: 'John', bold:
'<strong>{$0}</strong>'})
Nested Tokens tr('Hello [bold: {user}]', {user: [current_user, :name]}) tr('Hello [bold:
{user}]', {user: current_user}) or Passing Objects
<%= tml_source('common/navigation') do %> <ul> <li><%= tr('Home') %></li> <li><%= tr('Features')
%></li> <li><%= tr('Languages') %></li> <li><%= tr('Pricing') %></li> <li><%= tr('Docs') %></li> </ul> <% end %> Sources are arbitrary groups of related strings Sources & String Grouping
<%= trh(source: 'common/navigation') do %> <ul> <li>Home</li> <li>Features</li> <li>Languages</li> <li>Pricing</li>
<li>Docs</li> </ul> <% end %> Translation Blocks Entire blocks can be translated without markup.
<%= trh(source: 'common/navigation') do %> <nav> <ul> <li>You have <a
href=’/messages’>unread messages</a></li> <li><a href=’/logout’>Logout</a></li> </ul> </nav> <% end %> Blocks
Pluralization
CLDR Pluralization Rules (Common Locale Data Repository)
labels: messages: one: You have 1 message other: You have
{count} messages <%= t('labels.messages', {count: 5}) %> :rule => lambda { |n| n == 1 ? :one : :other } Pluralization in Rails using YAML English
Pluralization in Rails using YAML Russian labels: messages: one: У
вас есть 1 сообщение few: У вас есть {count} сообщения other: У вас есть {count} сообщений <%= t('labels.messages', {count: 5}) %> :rule => lambda { |n| n % 10 == 1 && n % 100 != 11 ? :one : [2, 3, 4].include?(n % 10) && ![12, 13, 14].include?(n % 100) ? :few : n % 10 == 0 || [5, 6, 7, 8, 9].include?(n % 10) || [11, 12, 13, 14].include?(n % 100) ? :many : :other }
Pluralization in Rails using TML English <%= tr('You have {count
|| message}', {count: 5}) %>
Pluralization in Rails using TML Russian Translation 'У вас есть
{count || сообщение, сообщения, сообщений}' У вас есть сообщений
Data Token Full Definition {count:number::ord || one: message, other: messages}
Simplification through Configuration {count:number || one: message, other: messages} {count
|| message, messages} {count || message}
Pluralization with TML translations: [ {label: “You have one message”,
context: {count: {number: ‘one’}}, {label: “You have {count} message”, context: {count: {number: ‘other’}}, ] <%= tr('You have {count} messages', {count: 5}) %> Expanded Translations
Pluralization with TML <%= tr('You have {count} messages', {count: 5})
%> translations: [ {label: “У вас есть {count} сообщение”, context: {count: {number: ‘one’}}, {label: “У вас есть {count} сообщения”, context: {count: {number: ‘few’}}, {label: “У вас есть {count} сообщений”, context: {count: {number: ‘other’}}, ] translations: [ {label: “תחא העדוה ךל שי”, context: {count: {number: ‘one’}}, {label: “העדוה יתש ךל שי”, context: {count: {number: ‘two’}}, {label: “תועדוה {count} ךל שי”, context: {count: {number: ‘other’}}, ] Expanded Translations
Numeric Rules Definition one: (&& (= 1 (mod @n 10))
(!= 11 (mod @n 100))) few: (&& (in '2..4' (mod @n 10)) (not (in '12..14' (mod @n 100)))) other: (|| (= 0 (mod @n 10)) (in '5..9' (mod @n 10)) (in '11..14' (mod @n 100))) one: (= @n 1) other: (true)
Genders
Contextualization by Gender tr('{user} uploaded {count || photo}', {user: user,
count: 3}) user = {name: ‘Michael’, gender: ‘male’}
Contextualization by Gender загрузил фотографии '{user || загрузил, загрузила} {count
|| фотографию, фотографии, фотографий}' Russian Translation user count
Contextualization by Gender <%= tr('{user} uploaded {count || photo}', {user:
user, count: 3}) %> '{user || загрузил, загрузила} {count || фотографию, фотографии, фотографий}' Simplified
Contextualization by Gender <%= tr('{user} uploaded {count || photo}', {user:
user, count: 3}) %> translations: [ {label: “{user} загрузил {count} фотографию”, context: {count: {number: ‘one’}, user: {gender: ‘male’}}, {label: “{user} загрузил {count} фотографии”, context: {count: {number: ‘few’}, user: {gender: ‘male’}}, {label: “{user} загрузил {count} фотографий”, context: {count: {number: ‘other’}, user: {gender: ‘male’}}, {label: “{user} загрузила {count} фотографию”, context: {count: {number: ‘one’}, user: {gender: ‘female’}}, {label: “{user} загрузила {count} фотографии”, context: {count: {number: ‘few’}, user: {gender: ‘female’}}, {label: “{user} загрузила {count} фотографий”, context: {count: {number: ‘other’}, user: {gender: ‘female’}} ] By Context
Language Cases
Possessive Case “{actor} liked {target::pos} post”
Dative Case Михаилу нравистся пост Анны “{actor::dat} нравится пост {target::gen}”
Ordinals ‘This is your {count::ord} reminder'
{date} = ‘{month_name} {days}, {years}’ Dates English Date Format tr('{user}
was born on {date}', {user: user, date: user.birthday.tr(:verbose)}) %B = {month_name} %d = {days} %Y = {years} verbose = ‘%B %d, %Y’ #July 4, 2002
Dates Russian Date Format родился Июля “{user || родился, родилась}
{date::gen}” ‘%d %B, %Y’ #4 Июль, 2002 {date} = ‘{days} {month_name}, {years}’
tr('[link: {user}] completed [bold: {count || mile}] on {user |
his, her} last run.',{ user: [user, :name], count: 3, link: {href: ‘/profile’} }) Mixing it all together
Mixing it all together Russian Translation пробежал мили в своем
последнем забеге '[link: {user}] {user | пробежал, пробежала} [bold: {count || милю, мили, миль}] в своем последнем забеге.'
DEMO
Framework Support
UNIVERSAL TRANSLATION MEMORY
• • • What is UTM?
Translation Rankings • • • +45 +2 -2 -17 -55
-58 -99
+45 +22 +1 -99 Translator Rankings
Hello World Hola Mundo 안녕하세요 Привет Мир Hallo Welt םלוע
םולש 你好,世界 UTM Graph
SUMMARY & CONCLUSION
Resources SDKs Documentation Blog Sample App Live Sample App Facebook
Twitter Feedback
We’re Hiring!
Michael Berkovich
Thank you