解决了它,最后我不得不使用自定义模板加载器在请求时即时更改模板目录。我在华盛顿时代遵循了一个非常有用的教程:http: //opensource.washingtontimes.com/blog/2010/feb/17/loading-templates-based-request-headers-django/
我并不觉得创建一个本地线程来存储请求(在我的例子中是一个上下文值)的想法真的很有趣,但似乎这是将数据实际传递给模板加载器的唯一方法。
我的代码:
<项目名称>/settings/defaults.py
我们首先加载我们的模板加载器,这样我们就可以在 django 加载任何东西之前处理数据。如果我们的代码出现问题,它将回退到默认的 django 加载器。
TEMPLATE_LOADERS = (
'projectname.templateloaders.arabic.load_template_source',
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
#'django.template.loaders.eggs.Loader',
)
<项目名称>/middleware/templaterequest.py
# -*- coding: utf-8 -*-
try:
from threading import local
except ImportError:
from django.utils._threading_local import local
from apps.locales.models import Locale
from apps.markets.models import Market
# for more info:
# http://opensource.washingtontimes.com/blog/2010/feb/17/loading-templates-based-request-headers-django/
_thread_locals = local()
def get_current_request():
return getattr(_thread_locals, 'arabic', None)
class RequestMiddleware(object):
"""
This middleware will store the market.rtl value at each request that is made.
Basically here you can do anything that you can get from the request.
In this case we get the locale and the market settings and extract the RTL
value, which we store in a local thread in memory an will be retrieved
later by the template loader when calling for get_current_request()
"""
def process_request(self, request):
site = request.META['HTTP_HOST']
locale = Locale.objects.get(site=site)
market = Market.objects.get(locale=locale)
_thread_locals.arabic = market.rtl
<项目名称>/templateloaders/arabic.py
# -*- coding: utf-8 -*-
from django.conf import settings
from django.template.loader import BaseLoader, TemplateDoesNotExist
from django.utils._os import safe_join
from tipx.middleware.templaterequest import get_current_request
def get_template_sources(template_name, template_dirs=None):
"""
This class will modify the template directory in case the market has
RTL activated in the market settings. If RTL if False it will pass and
let the standard django template loaders to work.
Explanation of how it behaves (it's weird...) the request comes trough and
hits first our code, tries to determine if the market is arabic or not.
It it's arabic it changes the template directory to /rtl/, but for example
third party templates are not there (except for the overrides), so it will
continue processing through the template loaders until it finds the right
template. This guarantees that no matter how twisted our template locations
are, it will always load the right templates in the right moment even
when the templates have includes from RTL to english.
"""
arabic = get_current_request()
if arabic:
# Loop through the template dirs
for directory in settings.TEMPLATE_DIRS:
new_directory = directory + '/rtl/'
yield safe_join(new_directory, template_name)
def load_template_source(template_name, template_dirs=None):
for filepath in get_template_sources(template_name, template_dirs):
try:
file = open(filepath)
try:
return (file.read().decode(settings.FILE_CHARSET), filepath)
finally:
file.close()
except IOError:
pass
raise TemplateDoesNotExist(template_name)
load_template_source.is_usable = True
最后一件事是拥有我们的 RTL 模板文件夹。如果您的任何模板包含,您将需要附加您的阿拉伯语版本的文件夹名称,例如:
原文包括:
{% include 'whatever/template.html' %}
RTL 包括:
{% include 'rtl/whatever/template' %}
如果有人发现这个答案不完整,请告诉我!:)