I have a json file with a long list of geographic locations
[
{
"id": 1,
"name": "Afghanistan",
"iso3": "AFG",
"iso2": "AF",
"phone_code": "93",
"capital": "Kabul",
"currency": "AFN",
"currency_symbol": "؋",
"tld": ".af",
"native": "افغانستان",
"region": "Asia",
"subregion": "Southern Asia",
"timezones": [
{
"zoneName": "Asia\/Kabul",
"gmtOffset": 16200,
"gmtOffsetName": "UTC+04:30",
"abbreviation": "AFT",
"tzName": "Afghanistan Time"
}
],
"latitude": "33.00000000",
"longitude": "65.00000000",
"emoji": "🇦🇫",
"emojiU": "U+1F1E6 U+1F1EB",
"states": [
{
"id": 3901,
"name": "Badakhshan",
"state_code": "BDS",
"cities": [
{
"id": 52,
"name": "Ashkāsham",
"latitude": "36.68333000",
"longitude": "71.53333000"
},
.......
/* very long list */
This file is loaded in Django forms when country/state/city dropdown lists are needed.
The problem is that I want to translate at least the country names to other languages.
Even if I was allowed to use {% trans "Country_name" %} in my JSon file it wouldn't be very practical. Is there a faster way to do so? For example making this in forms.py doesn't work:
from django.utils.translation import gettext_lazy as _
# ...
def get_country():
filepath = 'myproj/static/data/countries_states_cities.json'
all_data = readJson(filepath)
all_countries = [('----', _("--- Select a Country ---"))]
for x in all_data:
y = (x['name'], _(x['name']))
all_countries.append(y)
return all_countries
"--- Select a Country ---" will be translated but x['name'] will not, because it seems that
django-admin makemessages -l fr
doesn't execute loops and doesn't not lookup into arrays.
In short I have the same problem that I would have if I had to translate data coming from a database.
For the database django_modeltranslation would be a solution. But how could I translate data coming from json files without have to manually edit the json file, wihch is extremely tedious and error prone?
You can customize the makemessages
command to preprocess .json
files.
# mysite/myapp/management/commands/makemessages.py
import os
import subprocess
from django.core.management.commands import makemessages
def templatize(path):
return subprocess.check_output(["sed", "-E", f's/"name": "(.*)"/"name": _("\\1")/g', path]).decode()
class BuildFile(makemessages.BuildFile):
def preprocess(self):
if not self.is_templatized:
return
file_ext = os.path.splitext(self.translatable.file)[1]
if file_ext == '.json':
content = templatize(self.path)
with open(self.work_path, 'w', encoding='utf-8') as fp:
fp.write(content)
return
super().preprocess()
class Command(makemessages.Command):
build_file_class = BuildFile
Usage:
python manage.py makemessages -l fr -e html,txt,py,json