Django i18n默认语言没有路径前缀 [英] Django i18n default language without path prefixes
问题描述
一个约束是我不想更改已经存在的网址。该网站已经活动了一段时间,并且有外部链接,我不想打破或重定向。网址计划的工作方式如下:英文内容是网站的根,而其他语言在域名中使用前缀:
英文urls:
/
/ articles /
/ suggestions /
西班牙语urls:
/ es /
/ es /我已经将翻译的页面与Django配合使用了。 1.4的i18n模块,但真的,真的想把所有的英文网址放在/ en /下。我尝试了一些不同的黑客,包括为英文版定义非国际化网址: def build(callback):
return callback('',
url(_(r'^ $'),home.index,name =home),
url(_(r'^ articles / $ '),content.article_list,name ='article_list'),
url(_(r'^ suggestions / $'),suggest.suggestions,name ='suggestions'),
)
urlpatterns = build(patterns)
urlpatterns + = build(i18n_patterns)
这样可以正确解析网址,但反向解析的{%url%}标签不起作用。
完成非前缀英语网址的最佳方式是什么?
解决方案 更新:阅读下面的回答,Django 1.10本身支持
我遇到这个问题,解决了这个问题:
-
创建了一个替代的 i18n_patterns
,它不在站点主要语言前面(在 settings.LANGUAGE_CODE
)。
-
创建了一个替代中间件,仅使用URL前缀语言来激活当前
我没有看到使用这种技术的任何副作用。
代码:
#编码:utf-8
CauêThenório - cauelt(at)gmail.com
此代码段使Django不为默认语言(settings.LANGUAGE_CODE)创建URL语言前缀(即/ en /)
它还提供了一个激活langu的中间件年龄仅基于网址。
此中间件忽略用户会话数据,cookie和Accept-LanguageHTTP头。
您的网址将如下所示:
在您的默认语言(例如英语)中:
/ contact
/ news
/ articles
在另一种语言(例如葡萄牙语)中:
/ pt / contato
/ pt / noticias
/ pt / artigos
要使用它,请使用'simple_i18n_patterns'代替'i18n_patterns'
在您的urls.py:
from this_sinppet import simple_i18n_patterns as i18n_patterns
使用SimpleLocaleMiddleware代替Django的LocaleMiddleware
在您的settings.py中:
MIDDLEWARE_CLASSES =(
...
'this_snippet。 SimpleLocaleMiddleware'
...
)
适用于Django> = 1.4
import re
from django.conf import settings
from django.conf.urls import patterns
from django.core.urlresolvers import LocaleRegexURLResolver
from django.middleware.locale import LocaleMiddleware
from django.utils.translation import get_language,get_language_from_path
from django.utils import translation
class SimpleLocaleMiddleware(LocaleMiddleware):
def process_request (self,request):
如果self.is_language_prefix_patterns_used():
lang_code =(get_language_from_path(request.path_info)或
settings.LANGUAGE_CODE)
translation.activate(lang_code)
request.LANGUAGE_CODE = translation.get_language()
class NoPrefixLocaleRegexURLResolver(LocaleRegexURLResolver):
@property
def regex(self):
language_code = get_language()
如果language_code不在self._regex_dict:
regex_compiled =(re.compile('',re.UNICODE )
if language_code == settings.LANGUAGE_CODE
else re.compile('^%s /'%languag e_code,re.UNICODE))
self._regex_dict [language_code] = regex_compiled
return self._regex_dict [language_code]
def simple_i18n_patterns(prefix ,* args):
将此语言代码前缀添加到此
函数中的每个URL模式中,当该语言不是主要语言时。
这只能在根URLconf中使用,而不是包含在URLconf中。
pattern_list = patterns(prefix,* args)
如果没有设置.USE_I18N:
return pattern_list
return [NoPrefixLocaleRegexURLResolver(pattern_list) ]
上面的代码可在:
https://gist.github.com/cauethenorio/4948177
I have an existing multi-lingual Django app that I'm porting to Django 1.4. I18n support is currently based on some ugly hacks, I'd like to make it use Django's built-in i18n modules.
One constraint is that I don't want to change the urls that are already in place. This site has been active for a while and there are external links to it that I dont' want to break or redirect. The urls scheme works like this: English content is at the root of the site, while other languages use prefixes in the domain name:
English urls:
/
/articles/
/suggestions/
Spanish urls:
/es/
/es/articulos/
/es/sugerencias/
I've got the translated pages working with Django 1.4's i18n modules, but it really, really, really wants to put all the English urls under /en/. I've tried a few different hacks, including defining non-internationalized urls for the English version:
def build(callback):
return callback('',
url(_(r'^$'), home.index, name="home"),
url(_(r'^articles/$'), content.article_list, name='article_list'),
url(_(r'^suggestions/$'), suggestions.suggestions, name='suggestions'),
)
urlpatterns = build(patterns)
urlpatterns += build(i18n_patterns)
This makes the urls resolve properly, but the {% url %} tag to do reverse resolution doesn't work.
What's the best way to accomplish non-prefixed English-language urls?
解决方案 UPDATE: Read answer bellow, Django 1.10 supports it natively
I faced this problem and solved this way:
Created an alternative i18n_patterns
that do not prefix the site main language (defined in settings.LANGUAGE_CODE
).
Created an alternative middleware that only uses the URL prefixes language to activate the current language.
I didn't see any side-effect using this technique.
The code:
# coding: utf-8
"""
Cauê Thenório - cauelt(at)gmail.com
This snippet makes Django do not create URL languages prefix (i.e. /en/)
for the default language (settings.LANGUAGE_CODE).
It also provides a middleware that activates the language based only on the URL.
This middleware ignores user session data, cookie and 'Accept-Language' HTTP header.
Your urls will be like:
In your default language (english in example):
/contact
/news
/articles
In another languages (portuguese in example):
/pt/contato
/pt/noticias
/pt/artigos
To use it, use the 'simple_i18n_patterns' instead the 'i18n_patterns'
in your urls.py:
from this_sinppet import simple_i18n_patterns as i18n_patterns
And use the 'SimpleLocaleMiddleware' instead the Django's 'LocaleMiddleware'
in your settings.py:
MIDDLEWARE_CLASSES = (
...
'this_snippet.SimpleLocaleMiddleware'
...
)
Works on Django >=1.4
"""
import re
from django.conf import settings
from django.conf.urls import patterns
from django.core.urlresolvers import LocaleRegexURLResolver
from django.middleware.locale import LocaleMiddleware
from django.utils.translation import get_language, get_language_from_path
from django.utils import translation
class SimpleLocaleMiddleware(LocaleMiddleware):
def process_request(self, request):
if self.is_language_prefix_patterns_used():
lang_code = (get_language_from_path(request.path_info) or
settings.LANGUAGE_CODE)
translation.activate(lang_code)
request.LANGUAGE_CODE = translation.get_language()
class NoPrefixLocaleRegexURLResolver(LocaleRegexURLResolver):
@property
def regex(self):
language_code = get_language()
if language_code not in self._regex_dict:
regex_compiled = (re.compile('', re.UNICODE)
if language_code == settings.LANGUAGE_CODE
else re.compile('^%s/' % language_code, re.UNICODE))
self._regex_dict[language_code] = regex_compiled
return self._regex_dict[language_code]
def simple_i18n_patterns(prefix, *args):
"""
Adds the language code prefix to every URL pattern within this
function, when the language not is the main language.
This may only be used in the root URLconf, not in an included URLconf.
"""
pattern_list = patterns(prefix, *args)
if not settings.USE_I18N:
return pattern_list
return [NoPrefixLocaleRegexURLResolver(pattern_list)]
The code above is available on:
https://gist.github.com/cauethenorio/4948177
这篇关于Django i18n默认语言没有路径前缀的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!