Provide a mechanism for Django that switching template based on request context.
Project description
We often want to render different HTML templates for phones, tablets, and desktop browsers. Or for AB testing. django-variatmpl make it easy. By setting request.variant, you can render the template according to that request.variant. This library is heavily inspired by Action Pack Variants.
Quick start
Install django-variantmpl
$ pip install django-variantmpl
Change django.shortcuts.render to variantmpl.shortcuts.render in your views.
And set request.variant property.
# views.py --
# from django.shortcuts import render
from variantmpl.shortcuts import render # <- add
def sample(request):
# Set variant value
request.variant = 'v2'
return render(request, 'index.html')
Prepare variant templates.
$ echo 'sample v1' > templates/index.html
$ echo 'sample v2' > templates/index+v2.html
Confirm views.sample display in your browser.
You can see sample v2.
It is the result of loading the template(index+v2.html) based on request.variant.
Features
render
Use instead of django.shortcuts.render.
# views.py --
from variantmpl.shortcuts import render
def sample(request):
request.variant = 'v2'
# Actually "index+v2.html" is rendered
return render(request, 'index.html')
render_to_response
Use instead of django.shortcuts.render_to_response.
# views.py --
from variantmpl.shortcuts import render_to_response
def sample(request):
# Actually "index+v2.html" is rendered
return render_to_response(request, 'index.html', variant='v2')
You can set variant as a keyword argument.
render_to_string
Use instead of django.template.loader.render_to_string.
# views.py --
from django.http import HttpResponse
from variantmpl.template.loader import render_to_string
def sample(request):
request.variant = 'v2'
# Actually "index+v2.html" is rendered
content = render_to_string('index.html', request=request)
return HttpResponse(content)
TemplateResponse
Use instead of django.template.response.TemplateResponse.
# views.py --
from django.views.generic import TemplateView
from variantmpl.template.response import TemplateResponse
class SampleView(TemplateView):
template_name = 'sample/index.html'
response_class = TemplateResponse # Replace response class
def get(self, request, **kwargs):
request.variant = 'v2'
# Actually "index+v2.html" is rendered
return super().get(request, **kwargs)
sample = SampleView.as_view()
Monkey patching Django’s functions/classes
It is difficult to rewrite all code with large codes already to variantmpl code. In such a case, you can apply Monkey patch to Django’s functions/classes.
Caution : This feature is experimental. This may be deleted in the future if unexpected bad effects occur.
# settings.py --
SECRET_KEY = 'xxxxxx'
# You must write this code below SECRET_KEY.
from variantmpl import monkey
monkey.patch_all()
# views.py --
# You don't need to replace to 'variantmpl'.
from django.shortcuts import render
def sample(request):
request.variant = 'v2'
# Actually "index+v2.html" is rendered
return render(request, 'index.html')
All targets for monkey patching.
django.shortcuts.render
django.shortcuts.render_to_response
django.template.loader.render_to_string
django.template.response.TemplateResponse.resolve_template
They are replaced by the functions/methods of the same name in `variantmpl`.
Configuration
VARIANTMPL_VARIANT_FORMAT
You can change variant format. default: +variant.
# settings.py --
VARIANTMPL_VARIANT_FORMAT = '@{variant}'
# The lookup target template name changes as follows. "index+variant.html" -> "index@variant.html"
VARIANTMPL_PROPERTY_NAME
You can rename request.variant property.
# settings.py --
VARIANTMPL_PROPERTY_NAME = 'mutation'
# You can set 'mutation' instead of 'varaiant'
request.mutation = 'v2'
VARIANTMPL_TEMPLATE_FORMAT
You can change the position of the variant inserted into template path.
# For example, you have this path.
render('sample1/sample2/index.html')
# variantmpl inserts the variant(v2) as follows.
'sample1/sample2/index+v2.html'
# At this time, VARIANTMPL_TEMPLATE_FORMAT is like this. (default)
VARIANTMPL_TEMPLATE_FORMAT = '{dirpath}{filename}{variant}.{ext}'
dirpath # => 'sample1/sample2/'
filename # => 'index'
variant # => '+v2'
ext # => 'html'
Change this format like this.
VARIANTMPL_TEMPLATE_FORMAT = '{variant}/{dirpath}{filename}.{ext}'
# variantmpl inserts the variant(v2) as follows.
'+v2/sample1/sample2/index.html'
In this case templates layout will change as follows
templates ├── +v2 │ └── sample1 │ └── sample2 │ └── index.html └── sample1 └── sample2 └── index.html
Python and Django Support
Python 3.4 later
Django 1.10 later
Support only the latest 3 versions.
License
MIT Licence. See the LICENSE file for specific terms.
History
0.1.0(12 26, 2017)
First release
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for django_variantmpl-0.1.0-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 28cbb33ef9d7db1ec3b1e7ac342d1ef5ec4340c79b07198df296136b32836d12 |
|
MD5 | e5af78534e32ec0e2de743db082b70cc |
|
BLAKE2b-256 | 4d5802ea6c085df5993b573c505636a72e8589b8d02b9245f1085583e21aa229 |