NB: the whole approach of serving a Vue project through Django is less than ideal, so this can be seen as deprecated.
The goal of this gist is to be able to use the built-in makemessages command of Django on your Vue frontend. You can then expose a JavaScript catalog and localize your frontend using gettext.
Following assumptions are made:
- The directory for the frontend lives in your Django project
- You are using components (.vue files)
Somewhere in urls.py:
from django.views.i18n import JavaScriptCatalog
urlspatterns += [
path('jsi18n/', JavaScriptCatalog.as_view(), {
'domain': 'djangojs',
'packages': None,
}
]
Since 'djangojs' is the default here, you can just do:
urlspatterns += [path('jsi18n/', JavaScriptCatalog.as_view()]
The catalog and the gettext utility are now available in the JS file served at that URL.
You have to load the catalog synchronously, otherwise your frontend will try to access functions that are undefined.
In index.html (or the root file in which you load your bundled frontend):
<script src="/api/v1/jsi18n"></script>
In index.js(or your main frontend app file):
Vue.prototype._ = window.gettext // choose anything you like, _ is a common option
You can now use _('La vie est belle') in your frontend.
The makemessages command is based on the GNU xgettext tool. Even though it works with JS files, it will not work properly with .vue files (especially in the <template> part. That's why you need to use another tool for that, namely gettext-vue.
Install gettext-vue:
npm install -g xgettext-template gettext-vue
Create a file for overriding the command:
mkdir someapplication/management/commands/makemessages.py
Copy paste the file contents of the makemessages.py file of this gist. The important override is this part:
if self.domain == 'djangojs' and ('.vue' in self.extensions):
args = [
'yarn',
'--silent',
'xgettext-template',
'-L',
'Vue',
'--keyword=_',
'--keyword=gettext',
'--keyword=$gettext',
'--output=-'
]
Make sure you replace the --keyword arguments by whatever function name you use in your templates.
In your .vue components, all of the following will now work:
<template>
<SomeComponent :label="_('Traduisez moi`)"/>
<a>{{ _('Le lien vers le paradis') }}</a>
</template>
<script>
export default {
computed: {
title() {
return this._('Une belle application')
}
}
}
</script>
You can use the standard commands to collect messages. node_modules will be ignored automatically if you use the file provided in this gist.
./manage.py makemessages -d djangojs -e vue
./manage.py compilemessages
The djangojs .po and .mo files will now be available as per your settings.
@pierremonico yeah but somehow it's not recognized. I've ended up with vue-i18n which is more active (and easy to integrate with django)