首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >django-动态更改模板(BIDI支持)

django-动态更改模板(BIDI支持)
EN

Stack Overflow用户
提问于 2014-07-23 15:25:02
回答 1查看 225关注 0票数 1

我正在尝试将对阿拉伯语言的支持添加到我正在工作的站点中,因此目前我的模板如下

代码语言:javascript
复制
/templates
    /accounts/
    /includes/
    /rtl
        /accounts/
        /includes/
        ...
    ...

django-allauth无论如何都会尝试从/templates/accounts加载模板(在视图中是硬编码的),但是我想在必要时基于上下文变量加载RTL (从右到左)版本,所以我想出了四种解决方案,但它们对我来说似乎都不够好(我不是说我不会这么做,我是说如果有更好的方法,我就找不到更好的方法了)。

  1. 在我的重写中设置一个条件以加载LTR或RTL版本(这将需要/templates/accounts中的条件版本、带有其他模板的LTR版本和/templates/rtl/accounts中的条件版本)。
  2. 创建一个具有模板名称的参数并动态加载模板的模板标记,这看起来像是浪费资源。
  3. 用大量的逻辑在主模板中创建一个混乱,以便在需要时在LTR和RTL之间切换(这将需要大量的逻辑,这是不好的)
  4. 在我的项目中添加逻辑到视图中。--我真的不想做这个,因为它会使将来的维护变得很糟糕。

我没有使用标准的django i18n,所以我不能使用BIDI设置。

有人有更好的方法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-07-28 14:56:09

解决了这个问题,最后我不得不使用一个自定义的模板加载程序来在请求的时候动态地更改模板目录。我在华盛顿时报上学习了一个非常有用的教程:http://opensource.washingtontimes.com/blog/2010/feb/17/loading-templates-based-request-headers-django/

我并不认为创建一个本地线程来存储请求(在我的例子中是一个上下文值)的想法,但这似乎是将数据真正传递给模板加载器的唯一方法。

我的代码:

<项目名称>/设置/defaults.py

我们首先加载模板加载程序,这样我们就可以在django加载任何内容之前处理数据。如果代码出现故障,它将返回到默认的django加载器。

代码语言:javascript
复制
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 <项目名称

代码语言:javascript
复制
# -*- 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

< projectname >/templateloader/arabic.py

代码语言:javascript
复制
# -*- 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模板文件夹。如果您的模板中包含了任何内容,则需要附加阿拉伯文本的文件夹名称,例如:

原文包括:

代码语言:javascript
复制
{% include 'whatever/template.html' %}

RTL包括:

代码语言:javascript
复制
{% include 'rtl/whatever/template' %}

如果有人发现这个答案不完整,就告诉我!:)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24914611

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档