I don't use vue-gettext since Django provides the JavaScriptCatalog
view but I still faced the same issues with makemessages
not picking up translation string in templates.
Using Django 4, Vue 3, and gettext 0.21 I made my own makemessages
management command that overrides the Django's built-in one
from django.core.management.commands import makemessages
class Command(makemessages.Command):
"""
Overrides the default `makemessages` to add my own configuration & extend the command to recognize `interpolate` keyword in JS source files
"""
def handle(self, *args, **kwargs):
# Disable writing of the string's source file location in the generate po file
kwargs['no_location'] = True
# Ignore node_modules by default
kwargs['ignore_patterns'] = ['node_modules/*']
if kwargs['domain'] == 'djangojs':
# Set the default extensions
kwargs['extensions'] = kwargs['extensions'] or []
kwargs['extensions'].append('.js')
kwargs['extensions'].append('.vue')
self.xgettext_options.append('--keyword=interpolate')
# Set language to C so xgettext can pick up translations in Vue templates
self.xgettext_options.append('--language=C')
return super().handle(*args, **kwargs)
With default JavaScriptCatalog setup I have a js module that I import whenever I want to translate something
// Exports Django's `JavaScriptCatalog` functions dynamically
const djangoTranslationFns = [
'gettext',
'ngettext',
'get_format',
'gettext_noop',
'pgettext',
'npgettext',
'pluralidx',
];
const exports = {};
if (Object.keys(window).includes(djangoTranslationFns[0])) {
// If one of the functions are defined then it's safe to asumme they all are
djangoTranslationFns.forEach((fn) => { exports[fn] = window[fn]; });
// Override the interpolate function so it uses `gettext` by default
exports.interpolate = (fmt, obj, named) => window.interpolate(window.gettext(fmt), obj, named);
}
export default exports;
Then in the template
<script setup>
import i18n from '@/i18n';
</script>
<template>
<h1>{{ i18n.gettext("Welcome") }}</h1>
</template>