Translating forms
ASCII designer has a custom translation system for forms. You can also add own content e.g. for dynamic texts.
Builtin translation covers:
Widget and label texts (Key
<Class>.<widget_id>)List column headers (Key
<Class>.<widget_id>.<column_id>)Menu entries (Key
<Class>.<menuitem_id>)Form title (Key
<Class>.f_title)
Translations are stored as JSON files. The content is a simple key-value store.
Translation files can be stored either within some python package (recommended), or accessed via path.
Whichever folder you use, name the files:
default.jsonfor fallback translations (usually English)<code>.jsone.g.de.json,en.json, … for individual languagesIf required, add country-specific versions as
de_DE.json,de_CH.json.
Loading translations from a package
Assume that the translations files are stored in my_app package, in a
subfolder locale. I.e. the actual translation package is my_app.locale.
Remember that in Python 3.3+, the __init__.py is not required anymore.
File structure:
my_app/
__init__.py
my_app.py
...etc...
locale/
default.json
de.json
es.json
...etc...
To use translations, add the following code where you init your app:
from ascii_designer import AutoFrame, load_translations_json
# in Setup code
translations = load_translations_json("my_app.locale")
AutoFrame.f_translations = translations
Remarks
Language will be picked up from the OS. To force a language, use e.g.
load_translations_json("my_app.locale", language="es").
The importlib.resource loader will be used, meaning you can put package and
translations in a zip file if needed. load_translations_json will not fail
even if no translation file is found.
translations is a Translations instance. For the most part, it’s
just a dict matching the JSON’s content.
Keys are formed as <ClassName>.<widget_id>. Additionally, List column
headers are stored as <ClassName>.<widget_id>.<column_id>. It is recommended
to use the recording feature to generate the file (see below).
By setting the class attribute AutoFrame.f_translations, Translations are
shared among all AutoFrame subclasses. You can also set translations just for
an individual form or even instance, by setting their respective f_translations
class or instance attribute.
Loading translations from a file
Works nearly the same. Pass to load_translations_json:
a
pathlib.Path, ora string containing at least one slash
/or backslash\.
Instead of the importlib.resource loader, normal file loading is used.
Generating or updating translation files
Translations has a special flag recording that you can set.
The dictionary will then record all translation keys that are queried.
Extend your startup code as follows:
from ascii_designer import AutoFrame, load_translations_json, save_translations_json
# in Setup code
translations = load_translations_json("my_app.locale", language="")
AutoFrame.f_translations = translations
translations.recording = True
# Show your app here
# After mainloop exits (last window closed):
save_translations_json(AutoFrame.f_translations, "default.json")
Note that the default language is forced when loading.
Run the app, and open all forms that need to be translated at least once. After exiting the app, the new translation file is saved.
Existing entries of the translation file are kept untouched. New entries are appended at the end.
Now, copy or move the file to your translations directory. Make a copy for each
language to translate into, e.g de.json, … Then edit the translations with
any tool of choice.
To see if there are any translations missing in the GUI
Set Translations.mark_missing flag. All GUI strings missing in the
translation file will be prepended with $.
Adding custom translations
Just add them to the JSON dictionary under whatever key(s) you like.
In a Form method, retrieve them by:
custom_text = self.f_translations.get("my_key", "Default text here")
Always use get. That way the key can be “captured” by the recording
and mark_missing features.