use*_*384 8 django localization internationalization url-pattern django-1.4
我开始在Django 1.4中使用新的i18n_patterns.基本上,我希望在我的所有模板标题上为每种支持的语言提供语言链接.我已将我的标题实现为一个单独的模板,该模板包含在其他模板中.
有没有办法保持我的标题通用并解决这个问题,而不传递模板上下文中的当前视图名称或当前网址?我想这是一个问题,我如何以通用方式从模板内部检索当前视图或网址.
顺便说一句,我发现我之前用set_lang视图改变活动语言的方法将使用url_patterns打破,因为在更改语言后,它会在重定向到引用视图时将其更改回来.
任何帮助找出在模板中设置语言链接的通用方法,以通用的方式与url_patterns一起使用将不胜感激!
基本上,有两种不同的方法来设置语言.您可以使用i18n_patterns语言代码自动神奇地为您的网址添加前缀,或者您可以使用该django.views.i18n.set_language视图更改用户会话中的语言代码值(如果您的项目没有会话支持,则使用Cookie).
值得注意的是算法LocaleMiddleware用于确定语言:
首先,它在请求的URL中查找语言前缀.只有在root URLconf中使用i18n_patterns函数时才会执行此操作.有关语言前缀以及如何国际化URL模式的详细信息,请参阅国际化:URL模式.
如果失败了,它会在当前用户的会话中查找django_language键.
如果失败,它会查找cookie.使用的cookie名称由LANGUAGE_COOKIE_NAME设置设置.(默认名称为django_language.)
如果做不到这一点,它会查看Accept-Language HTTP标头.此标头由您的浏览器发送,并按优先级顺序告诉服务器您喜欢哪种语言.Django尝试标题中的每种语言,直到找到具有可用翻译的语言.
如果不这样做,它会使用全局LANGUAGE_CODE设置.
您可能遇到的问题是set_language,除非您专门传递nextPOST数据中的参数,否则您不能使用已经使用语言前缀提供服务的URL重定向.这是因为set_language默认情况下将重定向到引用者,引用者将包含先前的语言前缀,然后LocaleMiddleware将以旧语言查看和提供内容(因为它在检查django_language会话变量之前在URL中查找语言前缀).
一个例子,为清楚起见:
您的用户位于/ en/news/article/1000,并点击将发布'language = es'的链接set_language.
set_language 看到'language = es',检查'es'是否可用,然后将'django_language'会话变量(或cookie)设置为'es'
由于您尚未设置'next',它会重定向到reqeuest.META ['HTTP_REFERRER']的值,即/ en/news/article/1000
LocaleMiddleware(来源)在网址中看到'en'前缀,并激活'en'语言并设置request.LANGUAGE_CODE为'en'
我看到两种可能的解决方案
编写您自己的set_language视图(请参阅此处的原始源代码),该视图将检查引用者(使用django.utils.translation.get_language_from_path)中的语言前缀,并在重定向回到它之前将其更改为新选择语言的前缀.
使用javascript在客户端执行相同的操作,并设置nextPOST参数.真的,这有点傻; 使用javascript动态地在用户首选的语言代码中添加所有url可能会更简单,并且set_language完全忘记了.
似乎这个新set_language视图应该是Django的默认行为.有一张票,其中包括一个提议的实施,但没有真正描述问题,随后被关闭.我建议打开一张新票,更好地描述您的用例,现有set_language实施引起的问题以及您提出的解决方案.
对于这么长时间的延误,我深表歉意。谢谢大家的答案。
首先评论 Chris 的两个解决方案选项:自定义 set_language 和 javascript 都不能达到目的,因为 url 模式的全部优点是 SEO 友好。
此外,简单地替换 URL 中的前缀语言不能被视为基于 urlpattern 的 url 的完整解决方案,因为整个 URL 也可能是可翻译的。例如:/en/profile/英语和/fr/profil/法语。为了解决这样的问题,我们需要捕获 viewfunc 和参数,以便针对不同的语言反转它。
对我来说幸运的是,我的项目目前不使用可翻译的 URL,我采用了以下方法。
添加django.core.context_processors.request到TEMPLATE_CONTEXT_PROCESSORS以便该请求在模板渲染上下文中可用。
RequestContext渲染视图时在视图中使用。对于我来说,无论主题如何,情况总是如此。
编写一个非常简单的代码templatetag,它需要上下文并接受一个语言代码参数来返回给定语言的当前 URL。它基本上确保当前 URL 具有有效的语言代码前缀,并简单地返回与当前 URL 相同且替换了语言代码的另一个字符串。
前任:
from django import template
register = template.Library()
@register.simple_tag(takes_context=True)
def get_current_url_for_lang(context, lang_code):
request=context.get('request',False)
if not request:
return None
request=context['request']
curr_url=request.path
if len(curr_url) < 4 or curr_url[0] != '/' or curr_url[3] != '/':
return curr_url
if context.get('LANGUAGES',False):
codes = []
for code,name in context['LANGUAGES']:
codes.append(code)
curr_langcode = curr_url[1:3]
if lang_code not in codes or curr_langcode not in codes:
return curr_url
changed_url = '/'+lang_code+curr_url[3:]
return changed_url
Run Code Online (Sandbox Code Playgroud)
此外,如果不喜欢将完整的请求注入上下文,那么编写自己的 context_processor 会非常简单,它只需推送 asrequest.path并current_url_path在您的templatetag.
一如既往地欢迎您的评论!
| 归档时间: |
|
| 查看次数: |
2746 次 |
| 最近记录: |