hwuethrich
Gettext_sigils - a sigil for using gettext with less boilerplate and better readability
Hi!
I’m happy to share my first Elixir library. But first some …
Background
As an Elixir company from a country with 4 official languages (
), trust me when I say: we are using Gettext a lot in our Phoenix projects.
I really love the features of Gettext, but it always bothered me that it adds a lot of noise in the code, especially when using domains/contexts, interpolations or pluralization (besides, I still can’t remember which Gettext macro to use when using domains and/or contexts
).
That’s why until now, we always added a ~t sigil to all our (phoenix) projects that simply delegates to gettext. We also had an m modifier that is using the current module name (eg. live view/component) as context.
Over the last few days, I extracted this (and more!) as a library called …
gettext_sigils
It provides a new sigil ~t (which felt oddly familiar) for using Gettext translations with less boilerplate and better readability:
# before
gettext("Hello, %{name}", name: user.name)
# after
~t"Hello, #{user.name}"
When using GettextSigils (eg. in your MyAppWeb.html_helpers/0 for Phoenix projects), you can also provide how modifiers are mapped do domains and/or contexts:
# replace this
use Gettext, backend: MyApp.Gettext
# with this
use GettextSigils,
backend: MyApp.Gettext
sigils: [
modifiers: [
m: [context: inspect(__MODULE__)],
e: [domain: "errors"]
]
]
# then use it instead of gettext
~t"This is a global message"
~t"This is scoped to the current module/view/component"m
~t"This is a scoped error message"em
If this sounds interesting, there are a few other features, all described in the README.
As this is a very new project, contributions, bug reports and feedback in general are very welcome. I’m currently working on adding pluralization (which is a bit tricky when all you have is a sigil) where I would love some feedback (PR).
Thanks! Danke! Merci! Grazie! Grazia! ![]()
Most Liked
josevalim
Love the idea!
ErikNaslund
Thanks a bunch for this! I’ve also always been bothered by the verbosity of having gettext() calls all over my .heex templates, but I’ve never done anything about it.
I just migrated one of my projects to using GettextSigils, and one quirky regex replace and some small amount of manual editing later I was all done and it was working like a charm ![]()
<.socialproof name={~t"Papa John"} title={~t"City Planner"}>
# ...is just so much nicer than....
<.socialproof name={gettext("Papa John")} title={gettext("City Planner")}>
Great “quality of life” improvement, so thanks again! ![]()
P.S.
A serendipitous side effect is that my syntax highlighting scheme highlights sigil strings differently than normal binary strings, so it became a lot easier to spot “language strings” vs other strings (like CSS classes etc) in the templates as well.
hwuethrich
I just released v0.2.1 of the library with the following features:
igniter install task
installiing the library now automatically replaces use Gettext with use GettextSigils in the project. this allows installing and configuring the library with:
mix igniter.install gettext_sigils
usage rules & skill
I added usage rules to teach LLMs to use ~t instead of fixed strings for newly generated code. also comes with a skill that will:
-
replace fixed strings with
~tin any user-facing part of the application (HEEx templates) -
suggest using ex_cldr when showing dates, time, numbers, etc.
-
at the end of a task, asks to translate the new Gettext message for all languages used in the project (optional)
-
this works for newly generated code and existing parts of the project!
While this might be a bit controversial (my wife is actually working as a translator
), this has been a real time-saver and localizing an existing app is now easier than ever! At least it should mark the generated translations as “fuzzy”. See skill source and LLM guide.
Popular in News & Updates
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance











