Note that there are some explanatory texts on larger screens.

plurals
  1. PODjango internationalization problems with fr-ca, es-us
    primarykey
    data
    text
    <p>Working on internationalizing, <em>mainly the urls right now</em>, a site and everything seems to be working with the exception of Canadian French (fr-ca) and US Spanish (es-us).</p> <p>I'm using Django 1.4 </p> <p><code>settings.py</code> has <code>django.middleware.locale.LocaleMiddleware</code> as an installed middleware</p> <p>my list of language are: </p> <pre><code>ugettext = lambda s: s LANGUAGES = ( ('en', ugettext('English')), ('en-gb', ugettext('English United Kingdom')), ('es', ugettext('Spanish')), ('es-us', ugettext('Spanish United States')), ('fr', ugettext('French')), ('fr-ca', ugettext('French Canada')), ) </code></pre> <p>urls.py: </p> <pre><code>from django.conf.urls.defaults import patterns, include from django.conf.urls.i18n import i18n_patterns urlpatterns = patterns('myapp', (r'^example/?$', 'main.views.example'), (r'^$', 'main.views.index'), (r'', include('myapp.main.urls')), ) urlpatterns += i18n_patterns('myapp.main.views', (r'^example/?$', 'example'), (r'^example_1/?$', 'example1'), (r'^example_2/?$', 'example2'), (r'^$', 'index'), ) </code></pre> <p>I've run</p> <pre><code># django-admin.py makemessages -l en # django-admin.py makemessages -l en-GB # django-admin.py makemessages -l fr # django-admin.py makemessages -l fr_CA # django-admin.py makemessages -l es # django-admin.py makemessages -l es_US # # django-admin.py compilemessages </code></pre> <p>This is what I get: </p> <pre><code>| Accept-Language Header | Response Language | Expected Language | |--------------------------------------|--------------------|--------------------| | fr-ca;q=0.9, fr;q=0.8 | fr | fr-ca | | fr-ca;q=0.9 | fr | fr-ca | | | | | | es-us;q=0.9, es-mx;q=0.8, es;q=0.7 | es | es-us | | es-us;q=0.9 | es | es-us | | | | | | en-gb;q=0.8, en-us;q=0.7, en;q=0.6 | en-gb | en-gb | | en-us;q=0.9 | en | en | | | | | | fr-ca;q=0.8, en-gb;q=0.7 | fr | fr-ca | | fr-ca;q=0.7, en-gb;q=0.8 | en-gb | en-gb | |--------------------------------------|--------------------|--------------------| </code></pre> <p>If I place the locale codes in the URL, then I get the correct locale response:</p> <pre><code>http://localhost:8000/fr-ca/ I get fr-ca text back http://localhost:8000/fr/ I get fr text back http://localhost:8000/en/ I get en text back http://localhost:8000/en-gb/ I get en-gb text back http://localhost:8000/es-us/ I get es-us text back http://localhost:8000/es/ I get es text back http://localhost:8000/ I get en text back _(Default in settings.py)_ </code></pre> <p>en-gb works as expected, and in the last request is returned instead of the higher precedence fr-ca. </p> <p>Am I just missing something, or do fr-ca/es-us just not work with Django? </p> <hr> <p>(** I also sent in the default <code>django_language</code> cookie, and everything works as expected, so it looks like I'm only experiencing the issue when using the <code>Accept-Language</code> header. **)</p> <hr> <p><strong>UPDATE</strong> - <em>The short and sweet answer was already provided by @ilvar</em> </p> <p>Awright, I finally dug down into Django source <em>(Since it's awesomely open source, and all)</em> </p> <p>The file <code>[django/utils/translation/trans_real.py][1]</code> is where I found, verified, the answer. </p> <p>Here's a snippet of the function <code>get_language_from_request</code>, line 350: </p> <pre><code>... for path in all_locale_paths(): if os.path.exists(os.path.join(path, dirname, 'LC_MESSAGES', 'django.mo')): _accepted[normalized] = lang return lang ... </code></pre> <p>The <code>path</code> is set to the <code>conf/locale</code> directory of the Django install <em>(in site-packages)</em> and <code>dirname</code> is the locale name from the request, in my case <code>fr-ca</code>. So, if the Django install doesn't contain the locale from the request, which it doesn't have <code>fr-ca</code>, it will revert to one that is, <code>fr</code>. </p> <p>Just above the snippet the language is checked for within the URL first, if you're using i18n routes, and then within the language cookie. If it exists in either then that language code is returned immediately, so it doesn't matter if the language doesn't exist within the Django install. </p> <p>Handling it differently for 2/3 scenarios is what threw me off, but makes some sense since the browser could send anything, but if you've set a cookie|url then at that point it's your issue. </p> <p>Thanks @ilvar for the answer, even though I questioned it ;)<br> <strong>All I did was just copy the <code>fr</code> to <code>fr_CA</code>, within Django's locales, and voila...</strong></p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload