From 0bb713a5f3201d754849d5a7a35cb0246d519d00 Mon Sep 17 00:00:00 2001 From: Les Orchard Date: Mon, 18 Jul 2011 18:57:18 -0400 Subject: [PATCH] Make jingo.Loader properly fall back to other TEMPLATE_LOADERS - jingo.Loader raises TemplateDoesNotExist when excluded app encountered, which causes fallback to the next loader listed in settings.TEMPLATE_LOADERS - renamed setting DJANGO_TEMPLATE_APPS -> JINGO_EXCLUDE_APPS - tests updated to ensure top-level override of app-level templates works for both Jinja and Django loaders --- docs/index.rst | 12 ++++++----- fake_settings.py | 9 +++++++-- jingo/__init__.py | 10 +++++----- jingo/tests/django_app/__init__.py | 0 .../django_app/test_nonoverride.html | 1 + .../templates/django_app/test_override.html | 1 + jingo/tests/jinja_app/__init__.py | 0 .../templates/jinja_app/test_nonoverride.html | 1 + .../templates/jinja_app/test_override.html | 1 + .../templates/django_app/test_override.html | 1 + .../templates/jinja_app/test_override.html | 1 + jingo/tests/test_loader.py | 20 +++++++++++++++++++ 12 files changed, 45 insertions(+), 12 deletions(-) create mode 100644 jingo/tests/django_app/__init__.py create mode 100644 jingo/tests/django_app/templates/django_app/test_nonoverride.html create mode 100644 jingo/tests/django_app/templates/django_app/test_override.html create mode 100644 jingo/tests/jinja_app/__init__.py create mode 100644 jingo/tests/jinja_app/templates/jinja_app/test_nonoverride.html create mode 100644 jingo/tests/jinja_app/templates/jinja_app/test_override.html create mode 100644 jingo/tests/templates/django_app/test_override.html create mode 100644 jingo/tests/templates/jinja_app/test_override.html diff --git a/docs/index.rst b/docs/index.rst index 399e84f..5400fd4 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -31,7 +31,8 @@ You'll want to use jingo's template loader:: TEMPLATE_LOADERS = ( 'jingo.Loader', - 'django.template.loaders.filesystem.Loader' + 'django.template.loaders.filesystem.Loader', + 'django.template.loaders.app_directories.Loader', ) This will let you use ``django.shortcuts.render`` or @@ -40,11 +41,12 @@ This will let you use ``django.shortcuts.render`` or And finally you may have apps that do not use Jinja2, these must be excluded from the loader:: - DJANGO_TEMPLATE_APPS = ('debug_toolbar',) + JINGO_EXCLUDE_APPS = ('debug_toolbar',) -If a template is in the *app folder*, `debug_toolbar`, Django will handle the -templating, not Jinja. If this fails, Django will then move on to the next -loader. +If a template is in the *app folder*, `debug_toolbar`, the Jinja loader will +raise a TemplateDoesNotExist exception. This causes Django to move onto the +next loader in TEMPLATE_LOADERS to find a template - in this case, +``django.template.loaders.filesystem.Loader`` Template Helpers diff --git a/fake_settings.py b/fake_settings.py index cba5447..f45619f 100644 --- a/fake_settings.py +++ b/fake_settings.py @@ -3,9 +3,14 @@ import os path = lambda *a: os.path.join(ROOT, *a) ROOT = os.path.dirname(os.path.abspath(__file__)) +INSTALLED_APPS = ( + 'jingo.tests.jinja_app', + 'jingo.tests.django_app' +) TEMPLATE_LOADERS = ( 'jingo.Loader', - 'django.template.loaders.filesystem.Loader' + 'django.template.loaders.filesystem.Loader', + 'django.template.loaders.app_directories.Loader', ) TEMPLATE_DIRS = (path('jingo/tests/templates'),) -DJANGO_TEMPLATE_APPS = ('django_app',) +JINGO_EXCLUDE_APPS = ('django_app',) diff --git a/jingo/__init__.py b/jingo/__init__.py index 572f3ae..d7f078d 100644 --- a/jingo/__init__.py +++ b/jingo/__init__.py @@ -5,8 +5,9 @@ import logging from django import http from django.conf import settings +from django.template.base import TemplateDoesNotExist from django.template.context import get_standard_processors -from django.template.loaders.app_directories import Loader as AppLoader +from django.template.loader import BaseLoader from django.utils.importlib import import_module from django.utils.translation import trans_real @@ -165,15 +166,14 @@ class Template(object): return self.template.render(context_dict) -class Loader(AppLoader): +class Loader(BaseLoader): is_usable = True def load_template(self, template_name, template_dirs=None): if hasattr(template_name, 'rsplit'): app = template_name.rsplit('/')[0] - if app in getattr(settings, 'DJANGO_TEMPLATE_APPS', []): - return super(Loader, self).load_template( - template_name, template_dirs) + if app in getattr(settings, 'JINGO_EXCLUDE_APPS', []): + raise TemplateDoesNotExist(template_name) template = env.get_template(template_name) return Template(template), template.filename diff --git a/jingo/tests/django_app/__init__.py b/jingo/tests/django_app/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/jingo/tests/django_app/templates/django_app/test_nonoverride.html b/jingo/tests/django_app/templates/django_app/test_nonoverride.html new file mode 100644 index 0000000..efe5970 --- /dev/null +++ b/jingo/tests/django_app/templates/django_app/test_nonoverride.html @@ -0,0 +1 @@ +{{ 'HELLO WORLD'|truncatewords:"1" }} diff --git a/jingo/tests/django_app/templates/django_app/test_override.html b/jingo/tests/django_app/templates/django_app/test_override.html new file mode 100644 index 0000000..090dc06 --- /dev/null +++ b/jingo/tests/django_app/templates/django_app/test_override.html @@ -0,0 +1 @@ +{{ 'GOODBYE CRUEL WORLD'|truncatewords:"1" }} diff --git a/jingo/tests/jinja_app/__init__.py b/jingo/tests/jinja_app/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/jingo/tests/jinja_app/templates/jinja_app/test_nonoverride.html b/jingo/tests/jinja_app/templates/jinja_app/test_nonoverride.html new file mode 100644 index 0000000..27cd5f2 --- /dev/null +++ b/jingo/tests/jinja_app/templates/jinja_app/test_nonoverride.html @@ -0,0 +1 @@ +{{ 'hello'.upper() }} diff --git a/jingo/tests/jinja_app/templates/jinja_app/test_override.html b/jingo/tests/jinja_app/templates/jinja_app/test_override.html new file mode 100644 index 0000000..e3dace9 --- /dev/null +++ b/jingo/tests/jinja_app/templates/jinja_app/test_override.html @@ -0,0 +1 @@ +{{ 'goodbye'.upper() }} diff --git a/jingo/tests/templates/django_app/test_override.html b/jingo/tests/templates/django_app/test_override.html new file mode 100644 index 0000000..efe5970 --- /dev/null +++ b/jingo/tests/templates/django_app/test_override.html @@ -0,0 +1 @@ +{{ 'HELLO WORLD'|truncatewords:"1" }} diff --git a/jingo/tests/templates/jinja_app/test_override.html b/jingo/tests/templates/jinja_app/test_override.html new file mode 100644 index 0000000..27cd5f2 --- /dev/null +++ b/jingo/tests/templates/jinja_app/test_override.html @@ -0,0 +1 @@ +{{ 'hello'.upper() }} diff --git a/jingo/tests/test_loader.py b/jingo/tests/test_loader.py index a5312a3..4e41a01 100644 --- a/jingo/tests/test_loader.py +++ b/jingo/tests/test_loader.py @@ -11,7 +11,27 @@ def test_render(): eq_(r.content, 'HELLO') +def test_render_no_toplevel_override(): + r = render(Mock(), 'jinja_app/test_nonoverride.html', {}) + eq_(r.content, 'HELLO') + + +def test_render_toplevel_override(): + r = render(Mock(), 'jinja_app/test_override.html', {}) + eq_(r.content, 'HELLO') + + def test_render_django(): r = render(Mock(), 'django_app/test.html', {}) eq_(r.content, 'HELLO ...\n') + +def test_render_django_no_toplevel_override(): + r = render(Mock(), 'django_app/test_nonoverride.html', {}) + eq_(r.content, 'HELLO ...\n') + + +def test_render_django_toplevel_override(): + r = render(Mock(), 'django_app/test_override.html', {}) + eq_(r.content, 'HELLO ...\n') +