1

私が取り組んでいるサイトにアラビア語のサポートを追加しようとしているので、現在私のテンプレートは次のようになっています

/templates
    /accounts/
    /includes/
    /rtl
        /accounts/
        /includes/
        ...
    ...

django-allauth は/templates/accounts何からでもテンプレートをロードしようとします (ビューにハードコードされています) が、必要に応じてコンテキスト変数に基づいて RTL (Right To Left) バージョンをロードしたいので、4 つの解決策を考えましたが、どれもそれらは私にとって十分に良いようです(私はそれらをやらないと言っているのではありません。もしあれば、より良い方法を見つけることができないと言っています

  1. オーバーライドで条件を設定して、LTR または RTL バージョンをロードします (これには/templates/accounts/templates/rtl/accounts.

  2. テンプレート名のパラメーターを持つテンプレート タグを作成し、テンプレートを動的にロードします。これはリソースの無駄のように見えます

  3. 必要に応じて LTR と RTL を切り替えるため、大量のロジックでメイン テンプレートを混乱させます (テンプレートに大量のロジックが必要になるため、これは適切ではありません)。

  4. allauth をプロジェクトにフォークし、ロジックをビューに追加します。将来メンテナンスが大変になるので、本当にやりたくないです。

標準の django i18n を使用していないため、BIDI 設定を使用できません。

誰にもこれに対するより良いアプローチがありますか?

4

1 に答える 1

1

解決しましたが、最終的には、カスタム テンプレート ローダーを使用して、リクエストの瞬間にその場でテンプレート ディレクトリを変更する必要がありました。私はワシントン・タイムズの人々からの非常に有用なチュートリアルに従いました: 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' %}

誰かがこの答えが不完全だと思ったら教えてください! :)

于 2014-07-28T14:56:09.807 に答える