Rosetta¶
Rosetta is a Django application that eases the translation process of your Django projects.
Because it doesn’t export any models, Rosetta doesn’t create any tables in your project’s database. Rosetta can be installed and uninstalled by simply adding and removing a single entry in your project’s INSTALLED_APPS and a single line in your main urls.py
file.
Features¶
- Database independent
- Reads and writes your project’s gettext catalogs (po and mo files)
- Installed and uninstalled in under a minute
- Uses Django’s admin interface CSS
Contents:¶
Installation¶
Requirements¶
- As of version 0.9.0, Rosetta supports Django 1.11 and up.
Install Rosetta¶
pip install django-rosetta
Add
'rosetta'
to the INSTALLED_APPS in your project’ssettings.py
Add an URL entry to your project’s
urls.py
, for example:from django.conf import settings from django.conf.urls import include, re_path if 'rosetta' in settings.INSTALLED_APPS: urlpatterns += [ re_path(r'^rosetta/', include('rosetta.urls')) ]
Note: you can use whatever you wish as the URL prefix.
To uninstall Rosetta, simply comment out or remove the 'rosetta'
line in your INSTALLED_APPS
Testing¶
pip install tox && tox
Security¶
Because Rosetta requires write access to some of the files in your Django project, access to the application is restricted to the administrator user only (as defined in your project’s Admin interface)
If you wish to grant editing access to other users:
- Create a ‘translators’ group in your admin interface
- Add the user you wish to grant translating rights to this group
Settings¶
Rosetta can be configured via the following parameters, to be defined in your project settings file:
ROSETTA_MESSAGES_PER_PAGE
: Number of messages to display per page. Defaults to10
.ROSETTA_ENABLE_TRANSLATION_SUGGESTIONS
: Enable AJAX translation suggestions. Defaults toFalse
.YANDEX_TRANSLATE_KEY
: Translation suggestions from Yandex Yandex.Translate API. To use this service you must first obtain an AppID key, then specify the key here. Defaults toNone
.AZURE_CLIENT_SECRET
: Translation suggestions using the Microsoft Azure Translator API. To use this service, you must first register for the service, and setAZURE_CLIENT_SECRET
to either of the keys listed for your subscription. Defaults toNone
.DEEPL_AUTH_KEY
: Translation suggestions using the DeepL Translation API. To use this service, you must first register for DeepL API, and setDEEPL_AUTH_KEY
to either of the keys listed for your subscription. Defaults toNone
.DEEPL_LANGUAGES
: A dictionary to convert Django language codes to DeepL API Language codes. For example, for Simplified Chinese you could specify:{"zh_Hans": "ZH"}
. Check the languages supported by DeepL at DeepL API docs. Even if this is not set, Rosetta will try to get the language looking at the first 2 letters of django language code, but it would be useful if you want to specify EN-GB or EN-US for example.GOOGLE_APPLICATION_CREDENTIALS_PATH
andGOOGLE_PROJECT_ID
: Translation suggestions using Google Translation API. To use this service, you must first register the project. You do not have to register ENV variable. GOOGLE_APPLICATION_CREDENTIALS_PATH is path to JSON credentials file. Defaults toNone
. You also have to install google-cloud-translate package pip install google-cloud-translate==3.0.2ROSETTA_MESSAGES_SOURCE_LANGUAGE_CODE
andROSETTA_MESSAGES_SOURCE_LANGUAGE_NAME
: Change these if the source language in your PO files isn’t English. Default to'en'
and'English'
respectively.ROSETTA_WSGI_AUTO_RELOAD
andROSETTA_UWSGI_AUTO_RELOAD
: When running WSGI daemon mode, usingmod_wsgi
2.0c5 or later, this setting controls whether the contents of the gettext catalog files should be automatically reloaded by the WSGI processes each time they are modified. For performance reasons, this setting should be disabled in production environments. Default toFalse
.ROSETTA_EXCLUDED_APPLICATIONS
: Exclude applications defined in this list from being translated. Defaults to()
.ROSETTA_REQUIRES_AUTH
: Require authentication for all Rosetta views. Defaults toTrue
.ROSETTA_POFILE_WRAP_WIDTH
: Sets the line-length of the edited PO file. Set this to0
to mimicmakemessage
’s--no-wrap
option. Defaults to78
.ROSETTA_STORAGE_CLASS
: See the note below on Storages. Defaults torosetta.storage.CacheRosettaStorage
ROSETTA_ACCESS_CONTROL_FUNCTION
: An alternative function (string or a callable) that determines if a given user can access the translation views. This function receives auser
as its argument, and returns a boolean specifying whether the passed user is allowed to use Rosetta or not.ROSETTA_LANGUAGE_GROUPS
: Set toTrue
to enable language-specific groups, which can be used to give different translators access to different languages. Instead of creating a globaltranslators
group, create individual per-language groups, e.g.translators-de
,translators-fr
, and assign users to these.ROSETTA_CACHE_NAME
: When usingrosetta.storage.CacheRosettaStorage
, you can store the Rosetta data in a specific cache. This is particularly useful when yourdefault
cache is adjango.core.cache.backends.dummy.DummyCache
(which happens on pre-production environments). If unset, it will default torosetta
if a cache with this name exists, ordefault
if not.ROSETTA_POFILENAMES
: Defines which po file names are exposed in the web interface. Defaults to('django.po', 'djangojs.po')
ROSETTA_EXCLUDED_PATHS
: Exclude paths defined in this list from being searched (usually ends with “locale”). Defaults to()
ROSETTA_AUTO_COMPILE
: Determines whether the MO file is automatically compiled when the PO file is saved. Defaults toTrue
.ROSETTA_ENABLE_REFLANG
: Enables a selector for picking a reference language other than English. Defaults toFalse
.ROSETTA_SHOW_AT_ADMIN_PANEL
: Adds a handy link to Rosetta at the bottom of the Django admin apps index. Defaults toFalse
.ROSETTA_LOGIN_URL
: Use this if you want to override the login URL for rosetta. Defaults tosettings.LOGIN_URL
.ROSETTA_LANGUAGES
: List of languages that Rosetta will offer to translate. This is useful when you wish to translate a language that is not yet defined insettings.LANGUAGES
. Defaults tosettings.LANGUAGES
.ROSETTA_SHOW_OCCURRENCES
: Determines whether occurrences (where the original text appears) should be shown next to the translations for context. Defaults toTrue
.
Storages¶
To prevent re-reading and parsing the PO file catalogs over and over again, Rosetta stores them in a volatile location. This can be either the HTTP session or the Django cache.
Django 1.4 has introduced a signed cookie session backend, which stores the whole content of the session in an encrypted cookie. Unfortunately this doesn’t work with large PO files, as the limit of 4096 chars that can be stored in a cookie is easily exceeded.
In this case the Cache-based backend should be used (by setting ROSETTA_STORAGE_CLASS = 'rosetta.storage.CacheRosettaStorage'
). Please make sure that a proper CACHES
backend is configured in your Django settings if your Django app is being served in a multi-process environment, or the different server processes, serving subsequent requests, won’t find the storage data left by previous requests.
Alternatively you can switch back to using the Session based storage by setting ROSETTA_STORAGE_CLASS = 'rosetta.storage.SessionRosettaStorage'
in your settings. This is perfectly safe on Django 1.3. On Django 1.4 or higher make sure you have DON’T use the signed_cookies SESSION_BACKEND
with this Rosetta storage backend or funky things might happen.
TL;DR: if you run Django with gunicorn, mod-wsgi or other multi-process environment, the Django-default CACHES
LocMemCache
backend won’t suffice: use memcache instead, or you will run into issues.
Usage¶
Generate a batch of files to translate¶
See Django’s documentation on Internationalization to set up your project to use i18n and create the gettext
catalog files.
Translate away!¶
Start your Django development server and point your browser to the URL prefix you have chosen during the installation process. You will get to the file selection window.
Select a file and translate each untranslated message. Whenever a new batch of messages is processed, Rosetta updates the corresponding django.po file and regenerates the corresponding mo
file.
This means your project’s labels will be translated right away, unfortunately you’ll still have to restart the web server for the changes to take effect. (NEW: if your web server supports it, you can force auto-reloading of the translated catalog whenever a change was saved. See the note regarding the ROSETTA_WSGI_AUTO_RELOAD
variable in conf/settings.py
.
If the webserver doesn’t have write access on the catalog files (as shown in the screen shot below) an archive of the catalog files can be downloaded.
Translating Rosetta itself¶
By default Rosetta hides its own catalog files in the file selection interface (shown above.) If you would like to translate Rosetta to your own language:
- Create a subdirectory for your locale inside Rosetta’s
locale
directory, e.g.rosetta/locale/XX/LC_MESSAGES
- Instruct Django to create the initial catalog, by running
django-admin.py makemessages -l XX
inside Rosetta’s directory (refer to Django’s documentation on i18n for details) - Instruct Rosetta to look for its own catalogs, by appending ?rosetta to the language selection page’s URL, e.g.
http://127.0.0.1:8000/rosetta/pick/?rosetta
- Translate as usual
- Send a pull request if you feel like sharing
Version History¶
Version 0.9.8¶
- Test against Django 4.0
Version 0.9.7¶
- Arabic translation. (#257, thanks @Bashar)
- Translations via the DeepL API (#258, thanks @halitcelik)
- Fixed unicode handling in gettext headers (#259, thanks @NotSqrt)
- Remove six as a dependency
- Move context and comment hints into the right-most column (#260 thanks @jieter)
- Add extra styles block to the base template (#261 thanks @Frohus and @adamjforster)
Version 0.9.6¶
- Remove ‘providing_args’ kwarg from signals instanciation (#250, thanks @mondeja)
- Removed support and tests for Django <= 2.1
- Test against Python 3.9 (#251, thanks @mondeja)
- Upgraded Turkish translation (#253, thanks @realsuayip)
- Added support for Google Translation API (#222, thanks @martinsvoboda)
- Test against Django 3.2
Version 0.9.5¶
- Fixed DeprecationWarning: invalid escape sequence (#234, Thanks @jayvdb)
- Fixed typo in documentation (#232, thanks @timgates42)
- Added Kyrgyz translation (#239,thanks @Soyuzbek)
- Ignore translator context hints checking unmatched variables (#238, #239, thanks @jeancochrane and @mondeja)
- Uncheck fuzzy on translation keyup instead of change (#235 @mondeja)
- Allow passing a function itself to the setting ROSETTA_ACCESS_CONTROL (#227, thanks @alvra)
- Dropped support for Django 1.11 and Python 2
- Test against Django 3.1a
- Do not show Rosetta link in admin panel if user has no access to translations (#240, thanks @mondeja)
- Django 3.1: force #changelist to display:block (#248 thanks @realsuayip and @mondeja)
Version 0.9.4¶
- Added ROSETTA_SHOW_OCCURRENCES: Option to hide file name & path (#77, PR #221, thanks @sarathak)
- Unfuzzy fuzzy entries when the translation is changed (#16, PR #220, thanks @sarathak)
- Updated spanish translation (#230, thank you @mondeja)
- Test against Django 3.0 and Python 3.8
Version 0.9.3¶
- Added a tooltip to explain fuzzy entries (#206)
- New ROSETTA_LANGUAGES setting allows for translating languages which are not yet in LANGUAGES (#219)
- Fix for duplicate PO files listed on case insensitive filesystems (#47, #52, #218, thanks @malkstar)
Version 0.9.2¶
- Cleanup of imports, and use relative imports. Hopefully fixes #209.
- Travis: cleanup and test with Python 3.7
Version 0.9.1¶
- Removed old compatibility code for Django < 1.11 (#205, thanks @claudep)
- Allow overriding rosetta login url (#210, thanks @izimobil)
- Test against Django 2.2
- Optional line number in the occurrences column (#215, thanks @pauloxnet)
- Add search in msgctxt (#213, thanks @yakky)
- Strip code tag from Yandex response. (#212, thanks @izimobil)
- Test friendly settings and better tests (#211, thanks @izimobil)
- The reference language didn’t work in widows (#189, thanks @pedfercue)
Version 0.9.0¶
- Fix ROSETTA_REQUIRES_AUTH = False wasn’t respected (#203, @BarnabasSzabolcs)
- Django-rosetta now requires Django 1.11 or newer. Rosetta 0.8.3 is the last version to support Django 1.8 through 1.10. (#204, thanks @claudep)
Version 0.8.3¶
- Replace the (no longer working) Microsoft translation API with the new Azure Translator API (Fixes #200 and #201, thank you @svdvonde)
Version 0.8.2¶
- Avoid UnicodeEncodeError when quering strings (#197, thanks @YAtOff)
- Test against Django 2.1
Version 0.8.1¶
- PR #194, thanks again @jbaldivieso!
- Allow searching for plural strings, both in the original and translation. (Fixes #186)
- HTML-encoding ampersands in the template (minor regression introduced with 0.8.0)
- Stop showing “None” in the search input if there was no search query submitted
Version 0.8.0¶
- PR #194, huge thanks to @jbaldivieso:
- Better, cleaner RESTful URLs
- Massive rewrite of Rosetta’s view functions as CBVs
- Better management of cached content
- Check for PEP8 validity during tests
Version 0.7.14¶
- Updated installation docs (PR #190, thanks @AuHau)
- Test against Django 2.0
Version 0.7.13¶
- Search in comments, too (PR #174, thanks @torchingloom)
- Added ROSETTA_SHOW_AT_ADMIN_PANEL setting to display add a link to Rosetta from the admin app index page. (PR #176, thanks @scream4ik)
- Test against Django 1.11
- Template cleanup (Issue #181, thanks @Ecno92)
Version 0.7.12¶
- Fix IndexError in fix_nls when translation is just a carriage return (PR #168, thanks @nealtodd)
- Remove float formatting of integer percent translated (PR #171, thanks @nealtodd)
- Fixed a comment (PR #170, thanks @dnaranjo89)
- Test against Django 1.10
- Dropped support for goslate and the Google translate API
Version 0.7.11¶
- Make MO file compilation optional (PR #166, Issue #155, thanks @nealtodd)
- Fix an invalid page get parameter by falling back to page 1 (PR #165, thanks @nealtodd)
- Adds reference language selector (PR #60, thanks @hsoft)
Version 0.7.10¶
- Re-released 0.7.9 to include a missing image (Issue #162, thanks @legios89)
Version 0.7.9¶
- Use language code without country specification for Yandex dest lang (PR #152, thanks @nealtodd)
- Support discovering locale directories like zh_Hans(xx_Xxxx) (Fixes #133 via PR #153 and #133, thanks @glasslion and @dohsimpson)
- Ship Django’s original search icon as a static asset (Fixes #157, thanks @facconi)
- Added a warning about translation via the Google Translate service being deprecated in the next version
Version 0.7.8¶
- Adds missing includes in MANIFEST.in
- Support for running tests via setuptools
- Updated microsofttranslator dependency version
Version 0.7.7¶
- Supported Django versions are now 1.7, 1.8 and 1.9
- Added proper documentation
- Fixed typo in documentation (PR #130, thanks @dfrdmn)
- Fixes the Fuzzy toggle link by adding an actual toggle checkbox (Issue #132, thanks @EmilStenstrom)
- Better handling of Custom User Models while checking wether the current User is authorized to translate (Issue #131, thanks @EmilStenstrom)
- Include the testproject in the sdist tarball to allow Debian to run tests during installation (Issue #137, thanks @fladi)
- Display an explicit error message to the enduser when saving the POfile fails for some reason (Issue #135, thanks @pgcd)
- Added support for PEP 3101 string formatting (PR #140, thanks @adamjforster)
- Added support for composite locales, e.g. ‘bs-Cyrl-BA’ (Issue #142, thanks @felarov)
- Fixed a misplaced CSRF token (PR #145, thanks @pajod)
Version 0.7.6¶
- Added support for the Free Google Translate API (PR #117, thanks @cuchac)
- Probable fix for apps defined by their AppConfig causing havoc in Django 1.7 and later (Issues #113 and #125)
- Test configuration improved to test against Django 1.8 beta 1 and Django 1.7.5
- Require polib >= 1.0.6 (PR #127, thanks @NotSqrt)
- Test against Django 1.8 final
Version 0.7.5¶
- Fixed external JavaScript import to be url scheme independent (PR #101, thanks @tsouvarev)
- Fixed a test
- Added support for excluding certain locale paths from the list of PO catalogs (PR #102, thanks @elpaso)
- Added support for translator groups (PR #103, thanks @barklund)
- Removed Microsoft Translator as a shipped lib, relying on an external version instead
- Improved the app loading mechanism to cope with Django 1.7’s new AppConfig (thanks @artscoop)
- Fixed a couple inconsistencies in the German translation. (thanks @benebun)
- Use content_type instead of mimetype in HttpResponse. (Issue #115, thanks @vesteinn)
- Don’t assume that request.user has settable properties, this was a silly idea anyway (Issue #114, thanks @stevejalim)
- Preserve HTML code when receiving translations from the Yandex translation service (Issue #116, thanks @marcbelmont)
- Use TOX for testing
- Test against Django 1.8a
Version 0.7.4¶
- New ROSETTA_POFILENAMES setting. (PR #44, thanks @wrboyce)
- Updated Czech translation (#97, #99 thanks @cuchac)
- Fixed gettext standard compliance of all shipped translations
- No longer ship polib, rely on the Cheeseshop instead
Version 0.7.3¶
- Fix for test settings leaking onto global settings: LANGUAGES was overridden and not set back (Issue #81 - Thanks @zsoldosp)
- Test against Django 1.6.1
- Missing context variable in catalog list (Issue #87 - Thanks @kunitoki)
- Added support for Yandex translation API (Issue #89 - Thanks @BlackWizard) See supported languages and limitations here: https://github.com/mbi/django-rosetta/pull/89
- Added support for the Azure translation API, replacing the BING API. (Issue #86, thanks @davidkuchar and @maikelwever)
- Removed support for the signed_cookies SESSION_ENGINE + SessionRosettaStorage in Django 1.6, because serialization of POFiles would fail
- Simplified the group membership test (Issue #90 - Thanks @dotsbb)
- Better serving of admin static files. (Issue #61, thanks @tback)
- Dropped Django 1.3 support
Version 0.7.2¶
- Fix for when settings imports unicode_literals for some reason (Issue #67)
- Fixed mess with app_id between pages (Issue #68, thanks @tsouvarev)
- Added Farsi translation. Thanks, @amiraliakbari
- Improved the permission system, allowing for more advanced permission mechanisms. Thanks, @codeinthehole and @tangentlabs
- Fixed the ordering of apps in the language selection screen. (Issue #73, thanks @tsouvarev, @kanu and everyone else involved in tracking this one down)
- Support for complex locale names. (Issue #71, Thanks @strycore)
- Configurable cache name (Issue #75, Thanks @Karmak23)
Version 0.7.1¶
- Fix: value missing in context
Version 0.7.0¶
- Support for Django 1.5 and HEAD, support for Python 3.
- Upgraded bundled polib to version 1.0.3 - http://pypi.python.org/pypi/polib/1.0.3
- Support timezones on the last modified PO header. Thanks @jmoiron (Issue #43)
- Actually move to the next block when submitting a lot of translations (Issue #13)
- Add msgctxt to the entry hash to differentiate entries with context. Thanks @metalpriest (Issue #39)
- Better discovery of locale files on Django 1.4+ Thanks @tijs (Issues #63, #64)
- List apps in alphabetical order
Version 0.6.8¶
- Switched to a pluggable storage backend model to increase compatibility with Django 1.4. Cache and Session-based storages are provided.
Version 0.6.7¶
- Added a testproject to run tests
- Updated french translation. Thanks, @BertrandBordage
- Merged @sleepyjames’ PR that fixes an error when pofile save path contains ‘.po’ in the path
- Merged @rory’s PR to correcty handle plural strings that have a leading/trailing newline (Issue #34)
Version 0.6.6¶
- Django 1.4 support (Issue #30, #33)
- Better handling of translation callbacks on Bing’s translation API and support of composite locales (Issue #26)
Version 0.6.5¶
- Updated polib to 0.7.0
- Added ROSETTA_POFILE_WRAP_WIDTH setting to track the line-length of the updated Po file. (Issue #24)
- Renamed the
messages``context variable to ``rosetta_messages
prevent conflicts withdjango.contrib.messages
(Issue #23)
Version 0.6.4¶
- Added ROSETTA_REQUIRES_AUTH option to grant access to non authenticated users (False by default)
Version 0.6.3¶
- Support for the Bing transation API service to replace Google’s service which is no longer free.