hwuethrich

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 (:switzerland:), 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 :sweat_smile:).

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

Github / hex.pm

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! :heart:

Most Liked

josevalim

josevalim

Creator of Elixir

Love the idea!

12
Post #3
ErikNaslund

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 :slight_smile:

<.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! :slight_smile:

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

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 ~t in 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 :sweat_smile:), 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.

Where Next?

Popular in News & Updates Top

DominikWolek
Last Friday we released Membrane Core 0.11.0 :tada: A pipeline’s lifecycle has changed: pipeline is now spawned with a dedicated supervi...
New
hugobarauna
Welcome to the second day of Livebook Launch Week! :tada: Today we will discuss all the new Machine Learning capabilities in Elixir and ...
New
hugobarauna
Discover Livebook 0.9’s new security features, including Hubs for centralized secret management, notebook stamping, and a sneak peek into...
New
fhunleth
It looks like it’s finally safe to announce that Nerves supports Erlang/OTP 26 and Elixir 1.15! We’ve updated dozens of Nerves and close...
New
sorentwo
Oban.Web is a view of Oban’s inner workings that you host directly within your Phoenix application. Powered by Oban Metrics and Phoenix L...
New
zachdaniel
Hey folks! In order to give the new AshSqlite a trial run and make sure its got some real usage, AshHq’s multi-package search has been re...
New
zachdaniel
Hey folks! I’ll be teasing some interesting bits going into Ash 3.0 while I work on it, and this is post #1! You can follow along with t...
New
zachdaniel
The new Ash Framework site and installer are live. Please try it out and let me know what you think!
New
bartblast
Hey! For those following Hologram’s progress… I’m excited to share that I’ve just published the official roadmap for Hologram. You can ch...
New
bartblast
Hologram v0.8.0 is out! This release brings JavaScript interoperability - the most requested feature since the project’s inception. You c...
New

Other popular topics Top

johnnyicon
Hi all, I’ve just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I’m trying to use Postgres...
New
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
Lily
In templates/appointment/index.html.eex: &lt;%= for appointment &lt;- @appointments do %&gt; &lt;tr&gt; &lt;td&gt;&lt;%= appoi...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 43757 214
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New

Latest on Elixir Forum

We're in Beta

About us Mission Statement