Translations¶
Internationalization (i18n) support for Tinko.
Supported Languages¶
- English (en) - Primary
- Romanian (ro) - Secondary
Marking Strings for Translation¶
In Python¶
from django.utils.translation import gettext as _
from django.utils.translation import gettext_lazy as _lazy
# Immediate translation
name = _("Activity Timer")
# Lazy translation (for class attributes)
class Plugin(PluginBase):
name = _lazy("My Plugin")
description = _lazy("Plugin description")
In Templates¶
{% load i18n %}
<h1>{% trans "Welcome to Tinko" %}</h1>
<p>{% blocktrans %}Hello {{ user }}{% endblocktrans %}</p>
Creating Translation Files¶
1. Make Messages¶
2. Edit Translations¶
File: locale/ro/LC_MESSAGES/django.po
msgid "Activity Timer"
msgstr "Cronometru Activitate"
msgid "Start"
msgstr "Pornire"
msgid "Stop"
msgstr "Oprire"
3. Compile Messages¶
Plugin Translations¶
Plugin Structure¶
plugins/acme/myplugin/
├── locale/
│ ├── en/
│ │ └── LC_MESSAGES/
│ │ └── django.po
│ └── ro/
│ └── LC_MESSAGES/
│ └── django.po
Compile Plugin Translations¶
# Compile all plugin translations
python scripts/compile_translations.py
# Compile specific plugin
python scripts/compile_translations.py --plugin acme/myplugin
# List plugins with translations
python scripts/compile_translations.py --list
Language Selection¶
Django Settings¶
# config/settings.py
LANGUAGE_CODE = 'en-us'
LANGUAGES = [
('en', 'English'),
('ro', 'Romanian'),
]
LOCALE_PATHS = [
BASE_DIR / 'locale',
# Plugin locales discovered automatically
]
URL Language Prefix¶
# urls.py
from django.conf.urls.i18n import i18n_patterns
urlpatterns = i18n_patterns(
path('', include('core.urls')),
prefix_default_language=False,
)
Testing Translations¶
Test Setup¶
# tests/test_translations.py
from django.test import TestCase
from django.utils import translation
class TranslationTests(TestCase):
def test_romanian_translation(self):
with translation.override('ro'):
from django.utils.translation import gettext as _
self.assertEqual(_("Start"), "Pornire")
Check Coverage¶
Best Practices¶
- Use
_lazy()for module-level strings - Use
_()for runtime strings - Include context for ambiguous strings
- Keep translations updated