Whenever I look at modern internationalization libraries and compare them to GNU gettext, I feel like a key piece of knowledge got lost somewhere. BabelBox continues the trend of apparently not having ever used gettext or understanding how it should work. Here&#x27;s how it works in gettext. Let&#x27;s say you have something that prints a message:<p><pre><code>    print(&quot;Hello, world.&quot;);
</code></pre>
If a string should be translated, you wrap it in a call to gettext:<p><pre><code>    print(gettext(&quot;Hello, world.&quot;));
</code></pre>
In a webapp, you&#x27;d need an extra parameter for the session or locale, but the principle is the same. Note that the parameter was the initial english text. This is the first way i18n libraries go wrong: they make the parameter a key, instead of the english message.<p><pre><code>    print(i18lib(&quot;hello_msg&quot;));
</code></pre>
This makes the code less readable, and forces you to update a second location to add the English version. It also means you can no longer search the code for an english-language string and get to the right line.<p>I guess forcing the developer to update that second location is the reason for doing it that way, but gettext does something better: you run a tool on your source code which automatically detects calls to the gettext function, and produces a file with all the strings, ready to hand off to translators. This is ridiculously much more programmer-friendly.<p>Templating adds a bunch of complexity to this, and languages have weird quirks that sometimes need to be handled with code. But it&#x27;s sad that the basics got forgotten.