Skip to main content

OpenSynaptic Multi-Language (i18n) Support

This document explains how to use OpenSynaptic's built-in multi-language support to provide localized messages in different languages.

Overview

OpenSynaptic includes a lightweight multi-language system that supports:

  • Message translation at runtime
  • Dynamic language switching without restarting
  • Extensible design for adding new languages
  • Zero dependencies - uses only Python standard library

Currently supported languages:

  • 🇬🇧 English (en) - default
  • 🇨🇳 Chinese Simplified (zh) - complete translation

Quick Start

1. Switch Language Globally

from opensynaptic.utils import set_language, Language

# Switch to Chinese for all subsequent messages
set_language(Language.ZH)

# Switch back to English
set_language(Language.EN)

2. Use Language Code Strings

from opensynaptic.utils import set_language_by_code

# Use language code
set_language_by_code('zh') # Chinese
set_language_by_code('en') # English

# Invalid codes default to English
set_language_by_code('invalid') # Falls back to English

3. Get Current Language

from opensynaptic.utils import get_current_language

current = get_current_language()
print(f"Current language: {current}") # Output: 'en' or 'zh'

4. Translate Individual Messages

from opensynaptic.utils import translate, MESSAGES, LogMsg

# Translate a message template with context
message_template = MESSAGES[LogMsg.READY]
translated = translate(message_template, root='/path/to/root')
print(translated) # Output in current language

Usage Examples

Example 1: CLI with Language Support

import argparse
from opensynaptic.utils import set_language_by_code, os_log, LogMsg

def main():
parser = argparse.ArgumentParser()
parser.add_argument('--lang', choices=['en', 'zh'], default='en',
help='Display language')
args = parser.parse_args()

# Set language before any logging
set_language_by_code(args.lang)

# Now all logs will be in the selected language
os_log.log_with_const('info', LogMsg.CLI_READY, mode='cli')

if __name__ == '__main__':
main()

Example 2: Config-Based Language Selection

import json
from opensynaptic.utils import set_language_by_code, read_json

# Load language from config
config = read_json('Config.json')
language = config.get('language', 'en')

# Apply language setting
set_language_by_code(language)

Example 3: Translate Messages in Logs

from opensynaptic.utils import os_log, LogMsg, Language, set_language

# English logs
set_language(Language.EN)
os_log.log_with_const('info', LogMsg.DRIVER_MOUNT,
module='UDP', source='auto-discovery')

# Chinese logs
set_language(Language.ZH)
os_log.log_with_const('info', LogMsg.DRIVER_MOUNT,
module='UDP', source='自动发现')

Architecture

File Structure

src/opensynaptic/utils/
├── i18n.py # Main i18n module
├── constants.py # Message templates (LogMsg enum + MESSAGES dict)
├── logger.py # Logger with i18n support
└── __init__.py # Exports i18n functions

How It Works

  1. Message Templates: All user-facing messages are stored as templates in MESSAGES dict with placeholders ({variable})
  2. Translation Dictionaries: Each language has a translation dict (e.g., MESSAGES_EN, MESSAGES_ZH)
  3. Translator Class: Manages language state and message lookup
  4. Global Functions: set_language(), translate(), etc. operate on a global translator instance

Message Template Format

from opensynaptic.utils import MESSAGES, LogMsg

# Access a message template
template = MESSAGES[LogMsg.READY]
# Example: 'OpenSynaptic base is ready | Root: {root}'

# Use with translate()
translated = translate(template, root='/path')

Adding New Languages

Step 1: Create Translation Dictionary

In src/opensynaptic/utils/i18n.py, add a new language:

MESSAGES_FR = {
'OpenSynaptic base is ready | Root: {root}': 'OpenSynaptic est prêt | Root: {root}',
# ... translate all other messages
}

Step 2: Register Language

Add to the Translator.translations dict:

class Translator:
def __init__(self, language: Language = Language.EN):
# ...
self.translations: Dict[Language, Dict[str, str]] = {
Language.EN: MESSAGES_EN,
Language.ZH: MESSAGES_ZH,
Language.FR: MESSAGES_FR, # Add this
}

Step 3: Add Language Enum

class Language(Enum):
EN = 'en'
ZH = 'zh'
FR = 'fr' # Add this

Configuration in Config.json

You can optionally store language preference in your config:

{
"language": "en",
"OpenSynaptic_Setting": {
"Server_Core": true
}
}

Then load it at startup:

from opensynaptic.utils import read_json, set_language_by_code

config = read_json('Config.json')
lang = config.get('language', 'en')
set_language_by_code(lang)

API Reference

Functions

set_language(language: Language) -> None

Set the global language for message translation.

from opensynaptic.utils import set_language, Language
set_language(Language.ZH)

set_language_by_code(code: str) -> None

Set language using a language code string. Defaults to English if code is invalid.

from opensynaptic.utils import set_language_by_code
set_language_by_code('zh') # or 'ZH' (case-insensitive)

get_current_language() -> str

Get the current language code ('en', 'zh', etc.).

from opensynaptic.utils import get_current_language
lang = get_current_language() # Returns: 'en' or 'zh'

translate(message: str, **kwargs) -> str

Translate and format a message using the current language.

from opensynaptic.utils import translate, MESSAGES, LogMsg

template = MESSAGES[LogMsg.READY]
translated = translate(template, root='/path')

Classes

Language(Enum)

Language enumeration for type-safe language selection.

Language.EN    # English
Language.ZH # Chinese Simplified

Testing

Run the demo script to verify multi-language functionality:

python scripts/demo_i18n.py

This demo shows:

  • Basic translation
  • Logger integration
  • Language code switching
  • Batch message translation

Future Enhancements

Potential improvements to the i18n system:

  • Pluralization support ({count} message vs {count} messages)
  • Date/time localization
  • Automatic language detection (OS locale)
  • Language-specific formatting rules
  • RTL language support (Arabic, Hebrew, etc.)
  • Integration with standard gettext for community translations

Contributing Translations

To contribute translations for a new language:

  1. Create issue describing the language
  2. Fork repository
  3. Add MESSAGES_[LANG] dict with full translations
  4. Update Language enum and Translator.translations
  5. Submit pull request

Thank you for helping OpenSynaptic reach more users worldwide!