Cheatsheet
doti18n is a Python library for accessing localization data (YAML, JSON, XML, TOML) using dot-notation, with built-in type safety, pluralization, macrosing, and ICU Message Format (ICUMF) support.
Installation#
Basic Setup & Access#
Python Usage:
from doti18n import LocaleData
i18n = LocaleData("locales")
# Access as raw string
print(i18n["en"].greeting) # Output: Hello World!
File Structure Examples#
locales/en.yaml:
# key-value
hello: "Hello World!"
# list
fruits:
- "Apple"
- "Banana"
- "Orange"
# nested list
items:
- name: "Item 1"
- name: "Item 2"
# nested dict
errors:
connection: "Connection error occurred."
timeout: "Request timed out."
# pluralization
notifications:
one: "You have {count} new notification."
other: "You have {count} new notifications."
locales/en.json:
{
// key-value
"hello": "Hello World!",
// list
"fruits": [
"Apple",
"Banana",
"Orange"
],
// nested list
"items": [
{"name": "Item 1"},
{"name": "Item 2"}
],
// nested dict
"errors": {
"connection": "Connection error occurred.",
"timeout": "Request timed out."
},
// pluralization
"notifications": {
"one": "You have {count} new notification.",
"other": "You have {count} new notifications."
}
}
Note
Standard JSON does not support comments. The comments above are for illustration only.
locales/en.xml:
<locale>
<!-- key-value -->
<hello>Hello World!</hello>
<!-- list -->
<fruits list="true">
<fruit>Apple</fruit>
<fruit>Banana</fruit>
<fruit>Orange</fruit>
</fruits>
<!-- nested list -->
<items list="true">
<item>
<name>Item 1</name>
</item>
<item>
<name>Item 2</name>
</item>
</items>
<!-- nested dict -->
<errors>
<connection>Connection error occurred.</connection>
<timeout>Request timed out.</timeout>
</errors>
<!-- pluralization -->
<notifications>
<one>You have {count} new notification.</one>
<other>You have {count} new notifications.</other>
</notifications>
</locale>
locales/en.toml:
# key-value
hello = "Hello World!"
# list
fruits = [
"Apple",
"Banana",
"Orange"
]
# nested list
[[items]]
name = "Item 1"
[[items]]
name = "Item 2"
# nested dict
[errors]
connection = "Connection error occurred."
timeout = "Request timed out."
# pluralization
[notifications]
one = "You have {count} new notification."
other = "You have {count} new notifications."
Multilocale#
For more information, see Supported Formats.
locales/locales.json:
locales/locales.xml:
Macros#
Macros are resolved once at load-time. Use the __macros__ or __doti18n__ key and the @ prefix.
For more information, see Macros.
locales/en.xml:
Python Usage:
Formatting Styles#
Call the key as a function () to apply formatting. doti18n supports Python formatting natively.
For more information, see Formatting.
Escaping
Double the characters to escape them: {{, }}.
Pluralization#
For more information, see Pluralization.
Python Usage:
ICU Message Format (ICUMF)#
Powered by CLDR rules. Pass variables as keyword arguments. Use # inside sub-numeric formatters to represent the count.
For more information, see ICU Message Format.
Plural#
Python Usage:
Select (Switch-case)#
Python Usage:
Selectordinal#
Python Usage:
Forcing / Disabling ICUMF
- Force: Prepend
icu:to a string in your file (e.g.,"icu:My {custom} format"). - Disable: Pass
Loader(icumf=False)when initializingLocaleData.
Configuration Modes#
Control how doti18n handles missing keys during initialization.
For more information, see Configuration.
# Non-Strict Mode (Default) - Recommended for Production
i18n = LocaleData("locales", strict=False)
val = i18n["en"].missing_key
# Returns NoneWrapper (behaves like None), logs a WARNING. Does NOT crash.
# Strict Mode - Recommended for Development/Testing
i18n = LocaleData("locales", strict=True)
val = i18n["en"].missing_key
# Raises KeyError!
CLI Tools#
1. Type Stubs (.pyi)#
Generates type definitions for IDE autocompletion and static analysis (mypy).
For more information, see Stub Generation.
Place section types in the root of your locale file to specify explicit types for variables. The generator will import these types (if needed) into the stub file.
locales/en.yaml:
locales/en.json:
locales/en.xml:
Virtual Environment
Always run the stub generator inside your project's venv. It writes directly to the installed package directory.
doti18n stub locales/ # Generate stubs (default source: 'en')
doti18n stub locales/ --lang fr # Use 'fr' as the source of truth
doti18n stub --clean # Remove generated stubs
2. Linter#
Checks for missing keys, type mismatches, and list length differences between locales.
For more information, see Linting Translations.
doti18n lint locales/ # Lint against 'en' (default)
doti18n lint locales/ --source fr # Lint against 'fr'
doti18n lint locales/ --icumf # Enable ICU syntax validation
3. Studio#
A web-based translation editor. Multiple users can edit translations simultaneously with real-time sync.
For more information, see Studio.
pip install doti18n[studio] # Install studio dependencies
doti18n studio add-user admin mypassword # Create a user
doti18n studio run locales/ # Start the editor on http://127.0.0.1:5000
Advanced Customization#
- Custom Formatters: Inherit from
BaseFormatter. - Custom Loaders: Inherit from
BaseLoader. - Custom Tag Handling (HTML to Markdown, etc.): Pass
tag_formatter=MarkdownFormatter()to theICUMFconfiguration. Or call keys withformatter=MarkdownFormatter()to apply Markdown formatting at runtime.
Execution Order
Custom loaders and formatters must be defined/imported before initializing LocaleData(or Loader/ICUMF).