Question

I am deploying a single Django project for managing a certain kind of an event. There are two deployments with a single database, the sites are in Slovak. They are for events called „Akadémia Trojstenu“ and „Klub Trojstenu“. The simple part is I can just use the sites framework, set the display name for each site accordingly and use that in my templates where I need to refer to the name of the event.

This looks all right up until you realize the Slovak language uses grammatical cases. That means, in some places I need to write „Program Akadémie Trojstenu“ / „Program Klubu Trojstenu“ or „Staré Akadémie“ / „Staré Kluby“ for example.

For example, consider the following piece of template code:

<link rel="alternate" type="application/atom+xml" title="Novinky pre {{ site.name }}" href="{% url "news_feed" %}" />

site.name contains „Akadémia Trojstenu“, but in this case I need it to output „Novinky pre Akadémiu Trojstenu“, i.e. the content of the variable in the fourth grammatical case.

The only way forward I see at this moment is to special-case all such occurrences in the templates, look at the current site's domain and output the correct grammatical case of the name. This solution is obviously heavily anti-DRY, hideous and will eat small children.

Does anyone have a better suggestion? Is there some kind of standard solution? I imagine there are lots of languages using grammar cases and there's certainly someone who encountered this problem before me.

Was it helpful?

Solution

As @jpic says, you could do it with contextual markers. It would actually be simpler with the site name embedded in the template, as then it would be picked up by django's makemessages.

<link rel="alternate" type="application/atom+xml" 
      title="Novinky pre {% trans 'Akadémia Trojstenu' context '4th' %}" 
      href="{% url "news_feed" %}" />

Since that is probably not simple with multiple sites, you could instead make an extra .po file and manually enter all the site names and their translations and context names.

This is sort of error-prone, as you're manually synchronizing a translation file and some database values, but at least it's all in one place and outside the templates.

msgctxt "1st"
msgid "Akadémia Trojstenu"
msgstr "Akadémia Trojstenu"

msgctxt "2nd"
msgid "Akadémia Trojstenu"
msgstr "????? Trojstenu"

msgctxt "3rd"
msgid "Akadémia Trojstenu"
msgstr "Akadémie Trojstenu"

msgctxt "4th"
msgid "Akadémia Trojstenu"
msgstr "Akadémiu Trojstenu"

...

msgctxt "3rd"
msgid "Klub Trojstenu"
msgstr "Klubu Trojstenu"

...

Stick the extra .po in another directory and register the directory in the LOCALE_PATHS setting. Remember you did this, so you know where to look when someone adds a new site or changes the name of one and starts wondering why the translations are broken.

With this done, you should be able to use the site name like this:

<link rel="alternate" type="application/atom+xml" 
      title="Novinky pre {% trans site.name context '4th' %}" 
      href="{% url "news_feed" %}" />

Of course, if the problem is limited to just the site name, you might instead stick a few more fields on your Site model to hold the other cases (subclass it). Since site objects never really change, I don't think this sort of denormalization would cause any trouble.

OTHER TIPS

Just use variables in your translation strings:

output = _('Today is %(month)s %(day)s.') % {'month': m, 'day': d}

That also works in templates:

{% blocktrans with site.name as site_name %}Novinky pre {{ site_name }}.{% endblocktrans %}

Finnaly, you may find useful to use translation contexts.

There you won't have to "eat small children" (unless you're really hungry).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top