<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>globetrotter</title><link>https://luupsystems.github.io/globetrotter/</link><description>Recent content on globetrotter</description><generator>Hugo</generator><language>en-us</language><atom:link href="https://luupsystems.github.io/globetrotter/index.xml" rel="self" type="application/rss+xml"/><item><title>Introduction</title><link>https://luupsystems.github.io/globetrotter/docs/introduction/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://luupsystems.github.io/globetrotter/docs/introduction/</guid><description>&lt;h1 id="introduction"&gt;Introduction&lt;a class="anchor" href="#introduction"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Globetrotter is a code generator for applications that share translations across languages or
frameworks. It reads TOML catalogs, validates the translations as one set, and writes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;one JSON file for each spoken language, intended for runtime loading;&lt;/li&gt;
&lt;li&gt;TypeScript definitions for the translation structure;&lt;/li&gt;
&lt;li&gt;Rust types for translation keys and their declared arguments.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The translation text and the type information come from the same source files. A key cannot change
in one output without changing in all of them.&lt;/p&gt;</description></item><item><title>Installation</title><link>https://luupsystems.github.io/globetrotter/docs/installation/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://luupsystems.github.io/globetrotter/docs/installation/</guid><description>&lt;h1 id="installation"&gt;Installation&lt;a class="anchor" href="#installation"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Globetrotter is distributed as the &lt;code&gt;globetrotter&lt;/code&gt; command-line binary.&lt;/p&gt;
&lt;h2 id="homebrew"&gt;Homebrew&lt;a class="anchor" href="#homebrew"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;brew install --cask LuupSystems/tap/globetrotter&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The tap installs a prebuilt release. Upgrade it with the normal Homebrew workflow:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;brew upgrade --cask globetrotter&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="from-cratesio"&gt;From crates.io&lt;a class="anchor" href="#from-cratesio"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The binary is published by the &lt;code&gt;globetrotter-cli&lt;/code&gt; crate:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cargo install --locked globetrotter-cli&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;--locked&lt;/code&gt; uses the dependency versions recorded for the published release.&lt;/p&gt;
&lt;h2 id="prebuilt-releases"&gt;Prebuilt releases&lt;a class="anchor" href="#prebuilt-releases"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Release archives for supported platforms are attached to the
&lt;a href="https://github.com/LuupSystems/globetrotter/releases"&gt;GitHub releases&lt;/a&gt;. Extract the archive and put
the &lt;code&gt;globetrotter&lt;/code&gt; executable on your &lt;code&gt;PATH&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Quick start</title><link>https://luupsystems.github.io/globetrotter/docs/quick-start/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://luupsystems.github.io/globetrotter/docs/quick-start/</guid><description>&lt;h1 id="quick-start"&gt;Quick start&lt;a class="anchor" href="#quick-start"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This example generates runtime translations for English, German, and French, plus TypeScript and
Rust bindings. Every file shown here belongs to the runnable fixture under &lt;code&gt;docs/examples/quickstart&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="1-write-the-catalog"&gt;1. Write the catalog&lt;a class="anchor" href="#1-write-the-catalog"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Create &lt;code&gt;translations.toml&lt;/code&gt;:&lt;/p&gt;
&lt;div class="gt-file"&gt;
 &lt;div class="gt-file__cap"&gt;
 &lt;span class="gt-file__name"&gt;translations.toml&lt;/span&gt;
 &lt;/div&gt;
 &lt;div class="gt-file__body"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;greeting&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;en&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Welcome back, {{name}}!&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Willkommen zurück, {{name}}!&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fr&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Bon retour, {{name}} !&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;en&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;You have {{count}} items in your cart.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Du hast {{count}} Artikel in deinem Warenkorb.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fr&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Vous avez {{count}} articles dans votre panier.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;number&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;navigation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sign_out&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;en&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Sign out&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Abmelden&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fr&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Se déconnecter&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The table path is the translation key. Language fields hold the text, and &lt;code&gt;arguments&lt;/code&gt; declares the
placeholders accepted by the Handlebars template.&lt;/p&gt;</description></item><item><title>Configuration</title><link>https://luupsystems.github.io/globetrotter/docs/configuration/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://luupsystems.github.io/globetrotter/docs/configuration/</guid><description>&lt;h1 id="configuration"&gt;Configuration&lt;a class="anchor" href="#configuration"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Globetrotter uses a versioned YAML file. By default it looks for &lt;code&gt;globetrotter.yaml&lt;/code&gt; in the current
directory; pass &lt;code&gt;--config&lt;/code&gt; (&lt;code&gt;-c&lt;/code&gt;) to name a file or a directory to search.&lt;/p&gt;
&lt;div class="gt-file"&gt;
 &lt;div class="gt-file__cap"&gt;
 &lt;span class="gt-file__name"&gt;globetrotter.yaml&lt;/span&gt;
 &lt;/div&gt;
 &lt;div class="gt-file__body"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;configs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;languages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;en, de, fr]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;handlebars&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;strict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;check_templates&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;./translations.toml&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;app&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;outputs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;json&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;./generated/translations_{{language}}.json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;typescript&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;./generated/translations.ts&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rust&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;./generated/translations.rs&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Paths and glob patterns are resolved relative to the config file, not the shell&amp;rsquo;s working
directory. That makes a checked-in config safe to invoke from a repository root, a nested build
script, or CI.&lt;/p&gt;</description></item><item><title>Translation files</title><link>https://luupsystems.github.io/globetrotter/docs/translations/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://luupsystems.github.io/globetrotter/docs/translations/</guid><description>&lt;h1 id="translation-files"&gt;Translation files&lt;a class="anchor" href="#translation-files"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Translation sources are TOML. Each table path is a translation key; its fields are spoken-language
codes and, optionally, an argument declaration.&lt;/p&gt;
&lt;div class="gt-file"&gt;
 &lt;div class="gt-file__cap"&gt;
 &lt;span class="gt-file__name"&gt;translations.toml&lt;/span&gt;
 &lt;/div&gt;
 &lt;div class="gt-file__body"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;greeting&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;en&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Welcome back, {{name}}!&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Willkommen zurück, {{name}}!&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fr&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Bon retour, {{name}} !&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;string&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;en&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;You have {{count}} items in your cart.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Du hast {{count}} Artikel in deinem Warenkorb.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fr&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Vous avez {{count}} articles dans votre panier.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;number&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;navigation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sign_out&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;en&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Sign out&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Abmelden&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fr&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Se déconnecter&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="keys"&gt;Keys&lt;a class="anchor" href="#keys"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Nested TOML tables become dotted keys. This table:&lt;/p&gt;</description></item><item><title>Generated outputs</title><link>https://luupsystems.github.io/globetrotter/docs/outputs/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://luupsystems.github.io/globetrotter/docs/outputs/</guid><description>&lt;h1 id="generated-outputs"&gt;Generated outputs&lt;a class="anchor" href="#generated-outputs"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;One run can write runtime JSON and compile-time bindings. All examples on this page are generated
from the checked-in &lt;a href="https://luupsystems.github.io/globetrotter/docs/quick-start/"&gt;quick-start catalog&lt;/a&gt; before the documentation
site is built.&lt;/p&gt;
&lt;h2 id="runtime-json"&gt;Runtime JSON&lt;a class="anchor" href="#runtime-json"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Globetrotter writes one versioned JSON document per language. Its &lt;code&gt;translations&lt;/code&gt; object maps fully
qualified keys to literal text or templates:&lt;/p&gt;
&lt;div class="gt-file gt-file--out"&gt;
 &lt;div class="gt-file__cap"&gt;
 &lt;span class="gt-file__name"&gt;translations_en.json&lt;/span&gt;&lt;span class="gt-file__tag"&gt;generated&lt;/span&gt;
 &lt;/div&gt;
 &lt;div class="gt-file__body"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;template_engine&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;handlebars&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;language&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;en&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;translations&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;app.account.greeting&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;template&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Welcome back, {{name}}!&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;app.cart.summary&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;template&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;You have {{count}} items in your cart.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;app.navigation.sign_out&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;literal&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Sign out&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The key set is shared across language files, so an application can choose a file at runtime without
changing the lookup contract. Values without arguments remain literals; values with Handlebars
placeholders remain templates for the application to render.&lt;/p&gt;</description></item><item><title>Linting</title><link>https://luupsystems.github.io/globetrotter/docs/linting/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://luupsystems.github.io/globetrotter/docs/linting/</guid><description>&lt;h1 id="linting"&gt;Linting&lt;a class="anchor" href="#linting"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;globetrotter lint&lt;/code&gt; validates translation sources without writing generated files:&lt;/p&gt;
&lt;div class="gt-term"&gt;&lt;pre class="gt-term__body"&gt;&lt;span class="term-fg32 term-fg1"&gt;$&lt;/span&gt; globetrotter lint
&amp;nbsp;
&amp;nbsp;
 INFO globetrotter::lint: no issues found in 0ms&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The deterministic checks report:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a missing required language;&lt;/li&gt;
&lt;li&gt;empty text or leading/trailing whitespace;&lt;/li&gt;
&lt;li&gt;a template that does not compile with the configured engine;&lt;/li&gt;
&lt;li&gt;a value substituted in some languages but not in others; a name that only selects a wording,
such as &lt;code&gt;{{#if my_condition}}&lt;/code&gt;, may be absent from a language without that distinction;&lt;/li&gt;
&lt;li&gt;a condition whose branches are identical, so it has no effect;&lt;/li&gt;
&lt;li&gt;placeholders that are undeclared, or arguments that are never used;&lt;/li&gt;
&lt;li&gt;identical translations within one key;&lt;/li&gt;
&lt;li&gt;duplicate text shared by different keys.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The template checks use the configured &lt;code&gt;engine&lt;/code&gt; (or &lt;code&gt;--engine&lt;/code&gt;) and are never run with a guessed
one: without an engine, or with one that has no template analysis yet, they are skipped and a note
says so. Handlebars is the only engine with template analysis today.&lt;/p&gt;</description></item><item><title>CLI reference</title><link>https://luupsystems.github.io/globetrotter/docs/cli/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://luupsystems.github.io/globetrotter/docs/cli/</guid><description>&lt;h1 id="cli-reference"&gt;CLI reference&lt;a class="anchor" href="#cli-reference"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Running &lt;code&gt;globetrotter&lt;/code&gt; without a subcommand generates every configured output. The &lt;code&gt;format&lt;/code&gt; and
&lt;code&gt;lint&lt;/code&gt; subcommands operate on the same discovered inputs.&lt;/p&gt;
&lt;div class="gt-term"&gt;&lt;pre class="gt-term__body"&gt;&lt;span class="term-fg32 term-fg1"&gt;$&lt;/span&gt; globetrotter --help
&amp;nbsp;
Polyglot, type-safe internationalization
&amp;nbsp;
&lt;span class="term-fg1 term-fg4"&gt;Usage:&lt;/span&gt; &lt;span class="term-fg1"&gt;globetrotter&lt;/span&gt; [OPTIONS] [COMMAND]
&amp;nbsp;
&lt;span class="term-fg1 term-fg4"&gt;Commands:&lt;/span&gt;
 &lt;span class="term-fg1"&gt;format&lt;/span&gt; Formats translation files in place
 &lt;span class="term-fg1"&gt;lint&lt;/span&gt; Lints translation files and reports any issues
 &lt;span class="term-fg1"&gt;help&lt;/span&gt; Print this message or the help of the given subcommand(s)
&amp;nbsp;
&lt;span class="term-fg1 term-fg4"&gt;Options:&lt;/span&gt;
 &lt;span class="term-fg1"&gt;--log&lt;/span&gt; &amp;lt;LOG_LEVEL&amp;gt;
 Log level. When using a more sophisticated logging setup using RUST_LOG environment variable, this option is overwritten.
&amp;nbsp;
 [env: LOG_LEVEL=]
&amp;nbsp;
 &lt;span class="term-fg1"&gt;--log-format&lt;/span&gt; &amp;lt;LOG_FORMAT&amp;gt;
 log format (json, pretty, or pretty-compact)
&amp;nbsp;
 [env: LOG_FORMAT=]
&amp;nbsp;
 &lt;span class="term-fg1"&gt;--color&lt;/span&gt; &amp;lt;COLOR_CHOICE&amp;gt;
 enable or disable color
&amp;nbsp;
 [env: GLOBETROTTER_COLOR=]
&amp;nbsp;
 &lt;span class="term-fg1"&gt;-c&lt;/span&gt;, &lt;span class="term-fg1"&gt;--config&lt;/span&gt; &amp;lt;CONFIG_PATHS&amp;gt;
 Paths to globetrotter config files or directories to search for one
&amp;nbsp;
 &lt;span class="term-fg1"&gt;-i&lt;/span&gt;, &lt;span class="term-fg1"&gt;--translation&lt;/span&gt; &amp;lt;TRANSLATIONS&amp;gt;
 Paths to translation files to process
&amp;nbsp;
 &lt;span class="term-fg1"&gt;--engine&lt;/span&gt; &amp;lt;TEMPLATE_ENGINE&amp;gt;
 Template engine to use for rendering translations
&amp;nbsp;
 &lt;span class="term-fg1"&gt;--strict&lt;/span&gt;[=&amp;lt;STRICT&amp;gt;]
 Treat warnings as errors
&amp;nbsp;
 [possible values: true, false]
&amp;nbsp;
 &lt;span class="term-fg1"&gt;--check&lt;/span&gt;[=&amp;lt;CHECK_TEMPLATES&amp;gt;]
 Whether to validate that all templates render successfully
&amp;nbsp;
 [possible values: true, false]
&amp;nbsp;
 &lt;span class="term-fg1"&gt;--absolute&lt;/span&gt;[=&amp;lt;PRINT_ABSOLUTE_PATHS&amp;gt;]
 Print absolute paths instead of paths relative to the common base directory
&amp;nbsp;
 [possible values: true, false]
&amp;nbsp;
 &lt;span class="term-fg1"&gt;--dry-run&lt;/span&gt;[=&amp;lt;DRY_RUN&amp;gt;]
 Run without writing any output files
&amp;nbsp;
 [possible values: true, false]
&amp;nbsp;
 &lt;span class="term-fg1"&gt;--max-keys&lt;/span&gt; &amp;lt;N&amp;gt;
 Process only the first `N` translation keys of each config.
&amp;nbsp;
 A debugging aid for large corpora: try a change — or the LLM judge — against a small subset of real translations before paying for a full run. Applies to linting and generation alike; the truncation is warned about, never silent.
&amp;nbsp;
 &lt;span class="term-fg1"&gt;--cache-dir&lt;/span&gt; &amp;lt;DIR&amp;gt;
 Directory for cached data (e.g. LLM judge verdicts).
&amp;nbsp;
 Defaults to a `globetrotter` folder in the OS user cache directory (e.g. `~&amp;#47;.cache&amp;#47;globetrotter` on Linux).
&amp;nbsp;
 [env: GLOBETROTTER_CACHE_DIR=]
&amp;nbsp;
 &lt;span class="term-fg1"&gt;-h&lt;/span&gt;, &lt;span class="term-fg1"&gt;--help&lt;/span&gt;
 Print help (see a summary with &amp;#39;-h&amp;#39;)
&amp;nbsp;
 &lt;span class="term-fg1"&gt;-V&lt;/span&gt;, &lt;span class="term-fg1"&gt;--version&lt;/span&gt;
 Print version&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id="generation"&gt;Generation&lt;a class="anchor" href="#generation"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;globetrotter &lt;span class="o"&gt;[&lt;/span&gt;OPTIONS&lt;span class="o"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Common options:&lt;/p&gt;</description></item><item><title>Continuous integration</title><link>https://luupsystems.github.io/globetrotter/docs/ci/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://luupsystems.github.io/globetrotter/docs/ci/</guid><description>&lt;h1 id="continuous-integration"&gt;Continuous integration&lt;a class="anchor" href="#continuous-integration"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;A translation pipeline normally has three independent gates:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;source files are formatted;&lt;/li&gt;
&lt;li&gt;source files pass lint;&lt;/li&gt;
&lt;li&gt;committed generated files match the current catalogs and generator.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Keep those checks separate enough that a failure says what changed.&lt;/p&gt;
&lt;h2 id="verify-committed-output"&gt;Verify committed output&lt;a class="anchor" href="#verify-committed-output"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When generated files are committed, regenerate them and fail on a diff:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;globetrotter format --check
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;globetrotter lint
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;globetrotter
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git diff --exit-code -- generated/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Replace &lt;code&gt;generated/&lt;/code&gt; with the output paths from your config. Running generation before &lt;code&gt;git diff&lt;/code&gt;
tests the same config developers use locally; it does not rely on a second list of expected keys.&lt;/p&gt;</description></item><item><title>FAQ</title><link>https://luupsystems.github.io/globetrotter/docs/faq/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://luupsystems.github.io/globetrotter/docs/faq/</guid><description>&lt;h1 id="faq"&gt;FAQ&lt;a class="anchor" href="#faq"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;h2 id="does-globetrotter-render-translations-at-runtime"&gt;Does Globetrotter render translations at runtime?&lt;a class="anchor" href="#does-globetrotter-render-translations-at-runtime"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;No. It generates JSON data and language bindings. Your application loads the appropriate JSON file
and renders templates with its own Handlebars-compatible runtime or another integration.&lt;/p&gt;
&lt;h2 id="why-are-languages-fields-in-the-same-toml-table"&gt;Why are languages fields in the same TOML table?&lt;a class="anchor" href="#why-are-languages-fields-in-the-same-toml-table"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Keeping a key&amp;rsquo;s translations together makes missing languages and placeholder differences visible
to both reviewers and the linter. Output is still split by language for runtime loading.&lt;/p&gt;
&lt;h2 id="must-generated-files-be-committed"&gt;Must generated files be committed?&lt;a class="anchor" href="#must-generated-files-be-committed"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;No. Commit them when consumers need to build without the generator; otherwise generate them as part
of the build. In either case, establish one owner for the files and never edit them manually.&lt;/p&gt;</description></item></channel></rss>