Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for django-jinja. #167

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 10 additions & 7 deletions .travis.yml
Expand Up @@ -6,17 +6,20 @@ python:
- "3.3"
- "3.4"
env:
- DJANGO_VERSION=1.4
- DJANGO_VERSION=1.6
- DJANGO_VERSION=1.7
- DJANGO_VERSION=1.4 JINJA_WITH="jingo==0.7.1"
- DJANGO_VERSION=1.6 JINJA_WITH="jingo==0.7.1"
- DJANGO_VERSION=1.7 JINJA_WITH="jingo==0.7.1"
- DJANGO_VERSION=1.8 JINJA_WITH="django-jinja==1.4.1"
install:
- pip install -q "Django>=${DJANGO_VERSION},<${DJANGO_VERSION}.99" -r travis.txt
- pip install -q "Django>=${DJANGO_VERSION},<${DJANGO_VERSION}.99" "${JINJA_WITH}" -r travis.txt
script: ./run.sh test
matrix:
exclude:
- python: "2.6"
env: DJANGO_VERSION=1.7
env: DJANGO_VERSION=1.7 JINJA_WITH="jingo==0.7.1"
- python: "2.6"
env: DJANGO_VERSION=1.8 JINJA_WITH="django-jinja==1.4.1"
- python: "3.3"
env: DJANGO_VERSION=1.4
env: DJANGO_VERSION=1.4 JINJA_WITH="jingo==0.7.1"
- python: "3.4"
env: DJANGO_VERSION=1.4
env: DJANGO_VERSION=1.4 JINJA_WITH="jingo==0.7.1"
16 changes: 9 additions & 7 deletions docs/usage/templates.rst
Expand Up @@ -8,10 +8,11 @@ Using Waffle in templates
Waffle makes it easy to test :ref:`flags <types-flag>`, :ref:`switches
<types-switch>`, and :ref:`samples <types-sample>` in templates to flip
features on the front-end. It includes support for both Django's
built-in templates and for Jinja2_ via jingo_.
built-in templates and for Jinja2_ via jingo_ (for Django < 1.8) or
django_jinja_ (for Django >= 1.8).

.. warning::

Before using samples in templates, see the warning in the
:ref:`Sample chapter <types-sample>`.

Expand Down Expand Up @@ -68,10 +69,10 @@ Samples
Jinja Templates
===============

When used with jingo_, Waffle provides a ``waffle`` object in the Jinja
template context that can be used with normal ``if`` statements. Because
these are normal ``if`` statements, you can use ``else`` or ``if not``
as normal.
When used with jingo_ or django_jinja_, Waffle provides a ``waffle``
object in the Jinja template context that can be used with normal
``if`` statements. Because these are normal ``if`` statements, you
can use ``else`` or ``if not`` as normal.


Flags
Expand All @@ -88,7 +89,7 @@ Switches
--------

::

{% if waffle.switch('switch_name') %}
switch_name is active!
{% endif %}
Expand All @@ -106,3 +107,4 @@ Samples

.. _Jinja2: http://jinja.pocoo.org/
.. _jingo: http://github.com/jbalogh/jingo
.. _django_jinja: http://niwinz.github.io/django-jinja/
81 changes: 65 additions & 16 deletions test_settings.py
Expand Up @@ -45,22 +45,6 @@

ROOT_URLCONF = 'test_app.urls'

TEMPLATE_LOADERS = (
'jingo.Loader',
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)

JINGO_EXCLUDE_APPS = (
'django',
'waffle',
)

TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.request',
)

WAFFLE_FLAG_DEFAULT = False
WAFFLE_SWITCH_DEFAULT = False
WAFFLE_SAMPLE_DEFAULT = False
Expand All @@ -73,3 +57,68 @@
SOUTH_MIGRATION_MODULES = {
'waffle': 'waffle.south_migrations'
}

if django.VERSION < (1,8):
# Old style TEMPLATE_* settings.
# Use jingo.

TEMPLATE_LOADERS = (
'jingo.Loader',
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)

TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.request',
)

JINGO_EXCLUDE_APPS = (
'django',
'waffle',
)

else:
# New style TEMPLATES setting.
# Use django-jinja

INSTALLED_APPS += ('django_jinja', )

TEMPLATES = [
# Configure the Jinja2 template engine
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might want to make this more specific. Something like:

Configure the Jinja2 template engine so that it looks at the templates we have in
`templates/jingo/`.

{
'BACKEND': 'django_jinja.backend.Jinja2',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
"match_regex": r"jingo.*",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: This uses " but should use '.

'match_extension': '',
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need the debug and messages context processors. I'm not sure it makes much of a difference, but I think I would leave them out to match the jingo configuration.

],
'extensions': [
'jinja2.ext.i18n',
'jinja2.ext.autoescape',
'jinja2.ext.with_',
'jinja2.ext.do'
]
}
},
# Configure the Django template engine
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
24 changes: 24 additions & 0 deletions tox.ini
Expand Up @@ -15,6 +15,10 @@ envlist = py2.6-django1.4,
py3.2-django1.7,
py3.3-django1.7,
py3.4-django1.7,
py2.7-django1.8,
py3.2-django1.8,
py3.3-django1.8,
py3.4-django1.8,

[testenv]
commands=./run.sh test
Expand Down Expand Up @@ -98,3 +102,23 @@ deps = Django>=1.7,<1.8
basepython = python3.4
deps = Django>=1.7,<1.8
-rtravis.txt

[testenv:py2.7-django1.8]
basepython = python2.7
deps = Django>=1.8,<1.9
-rtravis.txt

[testenv:py3.2-django1.8]
basepython = python3.2
deps = Django>=1.8,<1.9
-rtravis.txt

[testenv:py3.3-django1.8]
basepython = python3.3
deps = Django>=1.8,<1.9
-rtravis.txt

[testenv:py3.4-django1.8]
basepython = python3.4
deps = Django>=1.8,<1.9
-rtravis.txt
1 change: 0 additions & 1 deletion travis.txt
Expand Up @@ -2,6 +2,5 @@
# versions.
mock==1.0.1
Jinja2>=2.7.1
jingo==0.7
South==0.8.3
django-discover-runner==1.0
24 changes: 1 addition & 23 deletions waffle/helpers.py
@@ -1,23 +1 @@
import jingo
import jinja2

from waffle import flag_is_active, sample_is_active, switch_is_active
from waffle.views import _generate_waffle_js


@jinja2.contextfunction
def flag_helper(context, flag_name):
return flag_is_active(context['request'], flag_name)


@jinja2.contextfunction
def inline_wafflejs_helper(context):
return _generate_waffle_js(context['request'])


jingo.env.globals['waffle'] = {
'flag': flag_helper,
'switch': switch_is_active,
'sample': sample_is_active,
'wafflejs': inline_wafflejs_helper
}
from waffle.templatetags import jinja_waffle_tags
39 changes: 39 additions & 0 deletions waffle/templatetags/jinja_waffle_tags.py
@@ -0,0 +1,39 @@
import jinja2

from waffle import flag_is_active, sample_is_active, switch_is_active
from waffle.views import _generate_waffle_js


@jinja2.contextfunction
def flag_helper(context, flag_name):
return flag_is_active(context['request'], flag_name)


@jinja2.contextfunction
def inline_wafflejs_helper(context):
return _generate_waffle_js(context['request'])


helpers = {
'flag': flag_helper,
'switch': switch_is_active,
'sample': sample_is_active,
'wafflejs': inline_wafflejs_helper
}

try:
import jingo

jingo.env.globals['waffle'] = helpers
except ImportError:
# jingo isn't being used. Move on.
pass


try:
from django_jinja.library import global_function

global_function('waffle', helpers)
except ImportError:
# django-jinja isn't being used. Move on.
pass
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't think of a situation where both jingo and django-jinja would be available, but I think I'd change this to cascade. Something like this:

try:
    from django_jinja.library import global_function
    global_function('waffle', helpers)
except ImportError:
    try:
        import jingo
        jingo.env.globals['waffle'] = helpers
    except ImportError:
        pass

@jsocol Does that sound ok?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the case here (running tests in travis), both jingo and django-jinja will be in the virtualenv. Unless I change things so they aren't. And even for sumo, we'd have to make sure the virtualenv gets destroyed once we change off of jingo. I don't think our deploys do that every time.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mmm... We should fix the test harness so we have separate "jingo" and "django-jinja" environments with different things installed. Otherwise we're mixing things and it's not clear what confidence of correctness our tests can give us.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SUMO problem should get solved in SUMO-land. There's a bug for this problem.

14 changes: 1 addition & 13 deletions waffle/tests/test_templates.py
Expand Up @@ -48,19 +48,7 @@ def test_no_request_context(self):
assert 'switch off' in content
assert 'sample' in content

@override_settings(TEMPLATE_LOADERS=(
'jingo.Loader',
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
))
@mock.patch.object(template.loader, 'template_source_loaders', None)
def test_jingo_tags(self):
"""
We're manually changing default TEMPLATE_LOADERS to enable jingo

template_source_loaders needs to be patched to None, otherwise
TEMPLATE_LOADERS won't be overriden.
"""
def test_jinja_tags(self):
request = get()
response = process_request(request, views.flag_in_jingo)
self.assertContains(response, 'flag off')
Expand Down