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
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Andrea Leopardi
October 03, 2015
Programming
550
2
Share
Gettext for Elixir - getting serious at compile time
Andrea Leopardi
October 03, 2015
More Decks by Andrea Leopardi
See All by Andrea Leopardi
Agentic Elixir
whatyouhide
0
400
The Umbrella and the Range
whatyouhide
0
56
gen_statem - OTP's Unsung Hero
whatyouhide
2
330
The World is a Network (and We Are Just Nodes)
whatyouhide
1
250
BEAM: The Perfect Fit for Networks
whatyouhide
1
250
Update from the Elixir team - 2022
whatyouhide
0
450
Testing Asynchronous OTP
whatyouhide
1
570
Elixir Sightseeing Tour
whatyouhide
0
480
Mint - Disrupting HTTP clients
whatyouhide
0
300
Other Decks in Programming
See All in Programming
Liberating Ruby's Parser from Lexer Hacks
ydah
2
2.1k
HTML-Aware ERB: The Path to Reactive Rendering @ RubyKaigi 2026, Hakodate, Japan
marcoroth
0
280
UIの境界線をデザインする | React Tokyo #15 メイントーク
sasagar
2
380
From Formal Specification to Property Based Test
ohbarye
0
330
事業会社でのセキュリティ長期インターンについて
masachikaura
0
270
NakouPAY説明用
annouim0
0
260
エラー処理の温故知新 / history of error handling technic
ryotanakaya
6
1.5k
「Linuxサーバー構築標準教科書」を読んでみた #ツナギメオフライン.7
akase244
0
1.4k
tRPCの概要と少しだけパフォーマンス
misoton665
2
240
SkillがSkillを生む:QA観点出しを自動化した
sontixyou
6
3.5k
Vibe NLP for Applied NLP
inesmontani
PRO
0
470
VueエンジニアがReactを触って感じた_設計の違い
koukimiura
0
180
Featured
See All Featured
Fireside Chat
paigeccino
42
3.9k
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
110
Prompt Engineering for Job Search
mfonobong
0
280
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
2.9k
Paper Plane
katiecoart
PRO
1
49k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
9.9k
Mind Mapping
helmedeiros
PRO
1
160
New Earth Scene 8
popppiees
3
2.1k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
A Tale of Four Properties
chriscoyier
163
24k
KATA
mclloyd
PRO
35
15k
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
0
210
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