Skip to content

Translating

Marius Stanciu edited this page Oct 29, 2026 · 1 revision

FlatCAM Evo has a translation in several languages. You can help by checking a text, correcting a translation, or adding a new language. You do not need to write code: a translation is a text file with the English text and your translation next to it.

Where to find it

  • Preferences: Preferences > General > App Preferences > Languages. Choose a language and click Apply Language. The program restarts.
  • Translation files: the locale folder of the repository.

Quick start

  1. Choose the language you want to help with, for example de (German).
  2. Open locale/de/LC_MESSAGES/strings.po with Poedit (free) or a text editor.
  3. Translate the entries that are not translated or are marked fuzzy (Poedit: "needs work").
  4. Run the check: python scripts/i18n_tool.py check de. It must report 0 placeholder errors.
  5. Run the compile: python scripts/i18n_tool.py compile de. It makes strings.mo, which the program reads.
  6. Send the change as a pull request, or attach the .po file to an issue.

Parameters

The files

File What it is Do you edit it?
locale/<lang>/LC_MESSAGES/strings.po The translation: each English text (msgid) and its translation (msgstr). Yes
locale/<lang>/LC_MESSAGES/strings.mo The compiled file that the program reads. No: made from the .po file
locale_template/strings.pot All English texts of the program (the template). No: made from the code
locale_template/glossary_terms.txt The key CNC and PCB terms with a short explanation. Only to add a term

The language codes are the folder names: de, es, fr, it, pt_BR, ro, ru, tr, zh.

The tool commands

Run these from the program folder. You need Python 3 only (no packages).

Command What it does
python scripts/i18n_tool.py stats The status of every language: translated, untranslated, fuzzy, errors, and whether the .mo file is up to date.
python scripts/i18n_tool.py check <lang> Placeholder errors, warnings, untranslated and fuzzy texts.
python scripts/i18n_tool.py compile <lang> Makes strings.mo from strings.po.
python scripts/i18n_tool.py glossary <lang> Shows how your language translates the key terms. --out glossary.csv writes a spreadsheet.
python scripts/i18n_tool.py init <code> Makes a new .po file with every text untranslated.

Advanced

Rules: what must stay as it is

Some parts of a text are filled in by the program. If they are changed, the program shows a wrong message or fails.

  • Placeholders stay the same, with the same number of each: %s, %d, %.4f, %(name)s, {name}. Only %(name)s and {name} may change their order. Keep %s and %d in the English order.
  • A percent sign in a text that has placeholders is written %% (for example 100%%). A single % makes the program fail.
  • HTML tags stay as they are: <b>, </b>, <br>, <span ...>, <font ...>. Translate the text between them.
  • Line breaks at the start or at the end of a text stay. Line breaks inside a text may move.
  • Argument names in angle brackets (for example <command_name> in the Tcl help) are best kept in English, like the command names next to them.
  • Names of formats, programs, and commands are usually kept: Gerber, Excellon, G-code, GRBL, Marlin, Tcl, and the Tcl command names (isolate, drillcncjob).
  • Units and numbers are written as the program writes them (mm, in, 0.1).
  • A text that the program builds with a % operator is not translated. Write _("Line %s") % n, not _("Line %s" % n).

Terms

Use the key terms the same way in the whole file. glossary_terms.txt explains each term. A common trap: Tool and Tools Table mean the cutting tool (end mill, drill bit, laser), not a software tool.

Checking your work

  • check must report 0 placeholder errors. An error is a translation that makes the program fail when it fills in the values: a lost or extra %s, a single %, or a changed {name}.
  • The warnings do not stop the program, but most of them are mistakes that the user sees: a lost or extra HTML tag, a placeholder written differently (% s), a %s added to a text that has none, a translated argument name, or a missing line break.
  • A text marked fuzzy is not used by the program. Users see English. Check the translation against the new English text, then remove the mark.

Approval of machine-made translations

Some translations were corrected or added with machine help. Each one was checked by a second model. These entries need the approval of a native speaker.

  • The file docs/translation_review/ lists each such entry with the old and the new text and the reason. It is a readable table, and a spreadsheet with an Approved column.
  • In the .po file these entries have a comment # auto-review <date>: <type>. Delete the comment when you have checked the entry.

Adding a new language

  1. Run python scripts/i18n_tool.py init <code>. Use a code like pl, pt_PT, or ja.
  2. Translate the file. Start with the menus and the tools you use.
  3. Run check <code> and compile <code>.
  4. Add the language and its name, written in that language, to languages_dict in appTranslation.py. Or send the .po file and the maintainer will add it.

How the program finds a translation

  • appTranslation.py lists the languages (languages_dict) and finds the locale folder (locale_dir()). It applies the language with gettext at start-up.
  • A language is shown in the menu only if it has a folder in locale and an entry in languages_dict.
  • The name of the language is saved in the settings. If the saved name is not available, English is used.

For maintainers: update the texts

python scripts/i18n_tool.py extract           # makes locale_template/strings.pot from the code
python scripts/i18n_tool.py merge de es fr it pt_BR ro ru tr zh
python scripts/i18n_tool.py compile
python scripts/i18n_tool.py stats
  • extract also lists the _() calls whose argument is not a text in quotes. Some are expected, for example _(self.label_text) in appGUI/preferences/OptionUI.py and _(label) in appDatabase.py. These translate a text held in a variable, and no language can translate them through the template.
  • merge keeps each translation whose English text did not change. It adds the new texts without a translation. A text that is no longer in the code is kept as an obsolete entry (#~), so a translation comes back when its text does.
  • Translations are under the license of the project (MIT, see LICENSE).

See also

Clone this wiki locally