Skip to content

Localization

BenJule edited this page May 31, 2026 · 2 revisions

Localization and Translation

BambuStudio uses GNU gettext for internationalization (i18n). Translation files live in bbl/i18n/ and resources/i18n/.


File Structure

bbl/i18n/
├── BambuStudio.pot          # Template (source strings, auto-generated)
├── de/
│   └── BambuStudio.po       # German translation
├── zh_CN/
│   └── BambuStudio.po       # Simplified Chinese
├── fr/
│   └── BambuStudio.po       # French
└── ...                      # Other languages

Compiled .mo files are generated at build time from the .po files and embedded in the application bundle.


Tools

Tool Purpose Install
xgettext Extract translatable strings from source sudo apt install gettext
msgmerge Merge new strings into existing .po files included with gettext
msgfmt Compile .po to binary .mo included with gettext
Poedit GUI editor for .po files Recommended for translators
Weblate Web-based translation platform Optional

Adding or Updating a Translation

Step 1 — Get the latest template

The .pot file contains all current translatable strings. Regenerate it from source:

# From the repository root
xgettext --keyword=_L --keyword=_u8L \
         --language=C++ \
         --from-code=UTF-8 \
         --output=bbl/i18n/BambuStudio.pot \
         $(find src -name '*.cpp' -o -name '*.hpp' | sort)

Or use the upstream script if available:

bash scripts/generate_pot.sh

Step 2 — Update an existing .po file

# Merge new strings from the template into the existing translation
msgmerge --update --backup=none \
         bbl/i18n/de/BambuStudio.po \
         bbl/i18n/BambuStudio.pot

Step 3 — Edit translations

Open the .po file in Poedit or any text editor:

#: src/slic3r/GUI/MainFrame.cpp:123
msgid "Print Settings"
msgstr "Druckeinstellungen"   # German translation

Rules:

  • msgid — never change (this is the source string)
  • msgstr — your translation
  • Lines starting with # are comments — do not change
  • Preserve %s, %d, %1$s format placeholders exactly

Step 4 — Add a new language

# Create the directory
mkdir -p bbl/i18n/es

# Create an initial .po from the template
msginit --input=bbl/i18n/BambuStudio.pot \
        --locale=es \
        --output=bbl/i18n/es/BambuStudio.po

Then translate the msgstr entries in the new file.

Step 5 — Submit

  1. Commit your .po file(s): git add bbl/i18n/ && git commit -S -m "i18n(de): update German translation"
  2. Open a PR following the Contributing guide

Verifying a Translation

Compile the .po to a .mo file and test:

msgfmt bbl/i18n/de/BambuStudio.po -o /tmp/BambuStudio.mo

# Check for errors
msgfmt --check bbl/i18n/de/BambuStudio.po

To test in the running application:

# Set locale before launching
LANG=de_DE.UTF-8 ./build/src/bambu-studio

Translation Statistics

Check completion percentage:

msgfmt --statistics bbl/i18n/de/BambuStudio.po
# Example output: 1234 translated messages, 56 fuzzy translations, 12 untranslated messages.

Fuzzy translations are machine-suggested or outdated — they must be reviewed and confirmed by a human before release.


String Extraction Conventions (for developers)

When adding translatable strings in C++ source, use the appropriate macro:

// Standard translation
auto label = _L("Print Settings");

// Translation with UTF-8 guarantee
auto label = _u8L("Print Settings");

// Format strings — use wxString::Format or fmt::format
auto msg = wxString::Format(_L("Slicing %d objects"), count);

Do not use _() (wxWidgets macro) — always use _L() or _u8L().

Never construct translatable strings dynamically from fragments:

// ❌ Wrong — cannot be extracted
auto msg = _L("File") + " " + _L("not found");

// ✅ Correct — single string the translator can give full context to
auto msg = _L("File not found");

Clone this wiki locally