MoritzS / jinja2-django-tags

jinja2 extensions that add django tags
MIT License
41 stars 10 forks source link

{% trans 'key' %} raises AttributeError #10

Open M1ha-Shvn opened 6 years ago

M1ha-Shvn commented 6 years ago

Hi. I use gunicorn server served by supervisor (in venv). When I reboot supervisor code is updated. But when I cleanly install django-jinja on the server via pip and release project version with django-jinja included libs, I get an error: ("expected token 'name', got 'string'",) in jinja2 templates on statements like: {% trans 'panel.emails.password_reset.link_valid_interval' %} After some time, the error is gone (some sort of caching?) and never occures again. The error can at the same time appear on one template and don't appear on another one. I've tried deleting pycache directory in all project directories, but it didn't resolve the issue. image

M1ha-Shvn commented 6 years ago

Looks like jdj extensions are not used at all. My setup:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            # insert your TEMPLATE_DIRS here
        ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.contrib.auth.context_processors.auth',
                'django.template.context_processors.debug',
                'django.template.context_processors.i18n',
                'django.template.context_processors.media',
                'django.template.context_processors.static',
                'django.template.context_processors.tz',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    }, {
        'BACKEND': 'django_jinja.backend.Jinja2',
        'DIRS': [
            # insert your TEMPLATE_DIRS here
        ],
        'APP_DIRS': True,
        'OPTIONS': {
            "extensions": DEFAULT_EXTENSIONS + [
                'jdj_tags.extensions.DjangoCompat',
                'jdj_tags.extensions.DjangoI18n',
                'jdj_tags.extensions.DjangoL10n'
            ],
            "auto_reload": DEBUG,
            "app_dirname": "jinja2",
            "match_extension": ".jinja2",
            "translation_engine": "django.utils.translation",
            "context_processors": {
                "django.template.context_processors.i18n",
            },
            "constants": {
                "PROJECT_NAME": PROJECT_NAME,
                "BLOG_URL": BLOG_URL,
                "CQ_USER_UNSUBSCRIBE_URL": UNSUBSCRIBE_URL,
                "ADMIN_UNSUBSCRIBE_URL": ADMIN_UNSUBSCRIBE_URL,
                "PANEL_URL": PANEL_URL,
                "SUPPORT_EMAIL": SUPPORT_EMAIL,
                "CDN_URL": CDN_URL,
                "PAY_NOW_URL": PAY_NOW_URL,
                "ACT_URL": ACT_URL,
                "DEV_URL": DEV_URL,
                "LANDING_URL": LANDING_URL,
                "FILES_CDN_URL": FILES_CDN_URL,
                "HELP_URL": HELP_URL,
                "API_URL": API_URL,
                "API_JS_OBJECT": API_JS_OBJECT,

                "IOS_APP_URL": IOS_APP_URL,
                "ANDROID_APP_URL": ANDROID_APP_URL,
                "WINDOWS_APP_URL": WINDOWS_APP_URL,
                "CHROME_APP_URL": CHROME_APP_URL
            },
            "globals": {
                "get_current_language_code": 'django.utils.translation.get_language',
                "get_current_locale": 'locale_settings.utils.get_current_locale',
                "get_current_region": 'locale_settings.utils.get_current_region'
            },
            "filters": {
                "localize": "django.utils.formats.localize"
            }
        }
    }
]
M1ha-Shvn commented 6 years ago

I've investigated the issue. The real problem is that jdj_tags.extensions.DjangoI18n has the same priority attribute (100 by default from superclass) with basic jinja2.ext.InternationalizationExtension and serve same tags (jinja2 extension - tags = set(['trans']), jdj extension - tags = set(['trans', 'blocktrans'])). So the order, they are iterated in jinja2.environment.Evironment.iter_extensions is not obvious. And this method is used by jinja2.parser.Parser, when it gets extensions for parsing tags and forms self.extensions dictionary. So standard library sometimes replaces jdj library in dictionary, sometimes - not. You should set priority > 100 to you extensions which have tags intersecting with standard jinja2 tags, as it should always replace standard extensions

MoritzS commented 6 years ago

I can't find anything about the priority attribute in the official docs, so I guess it's private API? Also, does it make sense to have both jdj_tags.extensions.DjangoI18n and jinja2.ext.InternationalizationExtension loaded at the same time?

M1ha-Shvn commented 6 years ago

I'm not sure about private API, I've found it in library sources while debugging. The comment assures, this attribute is created for extensions like yours. As you can see in my config, I haven't included InternationalizationExtension directly. I suppose, it has come from django_jinja.builtins.DEFAULT_EXTENSIONS which recommends using your library for additional tags. So it's not obvious, that I can't use both DEFAULT_EXTENSIONS and you library extensions at the same time.