Skip to content

Supported Formats

Supports YAML via PyYAML.
To enable YAML support, ensure the library is installed with the extra dependency:

pip install doti18n[yaml]

Note

You can also install PyYAML separately if doti18n is already installed.

Files must have a .yaml or .yml extension.

Supports JSON via the built-in json module.
Included by default; no additional installation required.

Files must have a .json extension.

Supports XML via the built-in xml module.
Included by default; no additional installation required.

Files must have a .xml extension.

Supports TOML via the built-in tomllib module (available in Python 3.11+).
Included by default; no additional installation required for Python 3.11+.

Files must have a .toml extension.


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."

Note

Standard YAML features (anchors, aliases, complex structures) are fully supported.

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>

XML Parsing Logic

  • Root Element: Ignored. You can name it anything (e.g., <locale>, <data>, <xml>), it serves only as a container.
  • Lists: Tags with identical child names are automatically treated as lists.
  • Explicit Lists: To force a list (e.g., for a single element), add the list="true" attribute to the parent tag. Using list="true" explicitly is recommended for consistency.

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."

Note

Standard TOML features (arrays of tables, inline tables, multi-line strings) are fully supported.


Multilocale Files#

doti18n supports defining multiple locales in a single file.

Warning

Using multilocale files is discouraged as it increases maintenance complexity. Separate files per locale are recommended.

Each document must contain a __locale__ key (this key is removed from the final data). Missing keys will trigger an error (or a log in non-strict mode).

locales/locales.yaml:

__locale__: "en"
hello: "Hello World!"
---
__locale__: "fr"
hello: "Bonjour le monde!"

Warning

Any YAML file containing multiple documents (separated by ---) is treated as a multilocale file.

Each object in the root list must contain a __locale__![img.png](img.png) key (this key is removed from the final data). Missing keys will trigger an error (or a log in non-strict mode).

locales/locales.json:

[
    {
        "__locale__": "en",
        "hello": "Hello World!"
    }, 
    {
        "__locale__": "fr",
        "hello": "Bonjour le monde!"
    }
]

Warning

Any JSON file where the root element is a list is treated as a multilocale file.

The root element must be <locales>, <localizations>, or <translations>. Child tags serve as locale names (see example). Incorrect structure will trigger an error (or a log in non-strict mode).

locales/locales.xml:

<locales>
    <en>
        <hello>Hello World!</hello>
    </en>
    <fr>
        <hello>Bonjour le monde!</hello>
    </fr>
</locales>

Warning

Any XML file with a root element named <locales>, <localizations>, or <translations> is treated as a multilocale file.

Each document in the locales or translations array must contain a __locale__ key. Missing keys will trigger an error (or a log in non-strict mode).

locales/locales.toml:

[[locales]]
__locale__ = "en"
hello = "Hello World!"

[[locales]]
__locale__ = "fr"
hello = "Bonjour le monde!"

Warning

Any TOML file where the root element contains a list named locales or translations is treated as a multilocale file.

Usage Example#

from doti18n import LocaleData

i18n = LocaleData("locales")
print(i18n["en"].hello)  # Output: Hello World!
print(i18n["fr"].hello)  # Output: Bonjour le monde!