Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Gettext for Elixir - getting serious at compile...
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Andrea Leopardi
October 03, 2015
Programming
2
540
Gettext for Elixir - getting serious at compile time
Andrea Leopardi
October 03, 2015
Tweet
Share
More Decks by Andrea Leopardi
See All by Andrea Leopardi
The Umbrella and the Range
whatyouhide
0
33
gen_statem - OTP's Unsung Hero
whatyouhide
2
300
The World is a Network (and We Are Just Nodes)
whatyouhide
1
240
BEAM: The Perfect Fit for Networks
whatyouhide
1
230
Update from the Elixir team - 2022
whatyouhide
0
440
Testing Asynchronous OTP
whatyouhide
1
550
Elixir Sightseeing Tour
whatyouhide
0
460
Mint - Disrupting HTTP clients
whatyouhide
0
280
BEAM Architecture Handbook
whatyouhide
7
2.9k
Other Decks in Programming
See All in Programming
AgentCoreとHuman in the Loop
har1101
5
240
Implementation Patterns
denyspoltorak
0
290
Apache Iceberg V3 and migration to V3
tomtanaka
0
160
Fluid Templating in TYPO3 14
s2b
0
130
izumin5210のプロポーザルのネタ探し #tskaigi_msup
izumin5210
1
130
Honoを使ったリモートMCPサーバでAIツールとの連携を加速させる!
tosuri13
1
180
例外処理とどう使い分ける?Result型を使ったエラー設計 #burikaigi
kajitack
16
6.1k
CSC307 Lecture 02
javiergs
PRO
1
780
Patterns of Patterns
denyspoltorak
0
1.4k
OSSとなったswift-buildで Xcodeのビルドを差し替えられるため 自分でXcodeを直せる時代になっている ダイアモンド問題編
yimajo
3
620
HTTPプロトコル正しく理解していますか? 〜かわいい猫と共に学ぼう。ฅ^•ω•^ฅ ニャ〜
hekuchan
2
690
コントリビューターによるDenoのすゝめ / Deno Recommendations by a Contributor
petamoriken
0
200
Featured
See All Featured
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
110
BBQ
matthewcrist
89
10k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.6k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.6k
Design in an AI World
tapps
0
140
WENDY [Excerpt]
tessaabrams
9
36k
Product Roadmaps are Hard
iamctodd
PRO
55
12k
Typedesign – Prime Four
hannesfritz
42
2.9k
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
290
Raft: Consensus for Rubyists
vanstee
141
7.3k
Heart Work Chapter 1 - Part 1
lfama
PRO
5
35k
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
160
Transcript
gettext for elixir getting serious at compile time
None
processes otp supervision trees
vs compile time runtime
gettext is deadly simple at runtime
free } agent supervisor let it crash
andrea @whatyouhide leopardi
None
gettext
i18n b4g l10n internationalization localization boring
<%= translate "greetings.informal" %> # en_US.yml greetings: informal: "hello" context
# en_TX.yml greetings: informal: "howdy" translation
# in en_TX/LC_MESSAGES/default.po #: lib/greetings.ex:24 msgid "hello" msgstr "howdy" <%=
gettext "hello" %>
# in en_TX/LC_MESSAGES/default.po #: lib/greetings.ex:24 msgid "hello" msgstr "howdy" <%=
gettext "hello" %>
# in en_TX/LC_MESSAGES/default.po #: lib/greetings.ex:24 msgid "hello" msgstr "howdy" <%=
gettext "hello" %>
# in en_TX/LC_MESSAGES/default.po #: lib/greetings.ex:24 msgid "hello" msgstr "howdy" <%=
gettext "hello" %>
# in en_TX/LC_MESSAGES/default.po #: lib/greetings.ex:24 msgid "hello" msgstr "howdy" <%=
gettext "hello" %>
developers see plain strings
translators see plain strings
PO files
translator-friendly syntax # Enough with the greetings examples! #: lib/greeter.ex:24
msgid "hello" msgstr "hola"
tools
gettext elixir-lang /
read translations from po files extract translations from source interpolate
translations pluralization
read translations from PO files
defmodule Gettext do @translations Gettext.Compiler.po_files() for {msgid, msgstr} <- @translations
do def gettext_fn(unquote(msgid)) do unquote(msgstr) end end end
defmodule Gettext do @translations Gettext.Compiler.po_files() for {msgid, msgstr} <- @translations
do def gettext_fn(unquote(msgid)) do unquote(msgstr) end end end
defmodule Gettext do @translations Gettext.Compiler.po_files() for {msgid, msgstr} <- @translations
do def gettext_fn(unquote(msgid)) do unquote(msgstr) end end end
defmodule Gettext do @translations Gettext.Compiler.po_files() for {msgid, msgstr} <- @translations
do def gettext_fn(unquote(msgid)) do unquote(msgstr) end end end
defmodule Gettext do @translations Gettext.Compiler.po_files() for {msgid, msgstr} <- @translations
do def gettext_fn(unquote(msgid)) do unquote(msgstr) end end end
defmodule Unicode do @pairs Unicode.read("data.txt") for {lower, upper} <- @pairs
do def lower(unquote(upper)) do unquote(lower) end end end
very fast at runtime
move logic away from runtime
compiler friend is your the
extract translations from source
how they do it
printf(_("Hello"))
printf(_("Hello"))
how we do it
MACROS :D
functions that do stuff at compile time
mix gettext.extract calls mix compile --force
defmacro gettext(msgid) do extract(__CALLER__, msgid) quote do ... end end
defmacro gettext(msgid) do extract(__CALLER__, msgid) quote do ... end end
defmacro gettext(msgid) do extract(__CALLER__, msgid) quote do ... end end
has to be a string
defmacro gettext(msgid) do extract(__CALLER__, msgid) quote do ... end end
pushes to an agent
defmacro gettext(msgid) do extract(__CALLER__, msgid) quote do ... end end
has context
actual implementation
zero runtime cost
compiler friend is your the
interpolate translations
gettext "Hello %{name}!", %{name: "Frodo"} case %{name: "Frodo"} do %{name:
name} -> {:ok, "Hello " <> name} _ -> {:error, :bad_interp} end
gettext "Hello %{name}!", %{name: "Frodo"} case %{name: "Frodo"} do %{name:
name} -> {:ok, "Hello " <> name} _ -> {:error, :bad_interp} end
easy pluralization support
import MyApp.Gettext ngettext "One attendant", "%{count} attendants", 254 msgid "One
attendant" msgid_plural "%{count} attendants" msgstr[0] "Uno spettatore" msgstr[1] "%{count} spettatori"
# Arabic def plural("ar", 0), do: 0 def plural("ar", 1),
do: 1 def plural("ar", 2), do: 2 def plural("ar", n) when rem(n, 100) >= 3 and ... def plural("ar", n) when rem(n, 100) >= 11, ... def plural("ar", _n), do: 5
workflow
define a gettext module defmodule MyApp.Gettext do use Gettext, otp_app:
:my_app end
write source code import MyApp.Gettext gettext "Hello, world"
extract translations mix gettext.extract
extract translations POT files #: lib/greetings.ex:24 msgid "Hello, world!" msgstr
""
merge POT with locales mix gettext.merge priv/gettext --locale en_TX
merge POT with locales #: lib/old_greetings.ex:23 msgid "Hello, world!" msgstr
"Ciao, mondo!"
merge POT with locales #: lib/greetings.ex:24 msgid "Hello, world!" msgstr
"Ciao, mondo!"
merge POT with locales #: lib/greetings.ex:24 #, fuzzy msgid "Hello,
world!" msgstr "Ciao, mondo"
Again
so.
github.com/elixir-lang/gettext
@WHATYOUHIDE