Skip to content

Create a cacheback template tag #70

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

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cacheback/templatetags/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

79 changes: 79 additions & 0 deletions cacheback/templatetags/cacheback.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
from __future__ import unicode_literals

import time

from django.core.cache.utils import make_template_fragment_key
from django.template import (
Library, Node, TemplateSyntaxError, VariableDoesNotExist)

from cacheback.base import Job

register = Library()


class CacheJob(Job):
"""Class to handle asynchronous loading of all cacheback template tags"""

def fetch(self, nodelist, context, expire_time, fragment_name, vary_on):
"""Render the node"""
return self.nodelist.render(context)

def expiry(self, nodelist, context, expire_time, fragment_name, vary_on):
"""When to expire"""
return time.time() + expire_time

def key(self, nodelist, context, expire_time, fragment_name, vary_on):
"""Make the cache key"""
return make_template_fragment_key(fragment_name, vary_on)


class CacheNode(Node):
def __init__(self, nodelist, expire_time_var, fragment_name, vary_on):
self.nodelist = nodelist
self.expire_time_var = expire_time_var
self.fragment_name = fragment_name
self.vary_on = vary_on

def render(self, context):
try:
expire_time = self.expire_time_var.resolve(context)
except VariableDoesNotExist:
raise TemplateSyntaxError(
'"cacheback" tag got an unknown variable: %r' % self.expire_time_var.var)
try:
expire_time = int(expire_time)
except (ValueError, TypeError):
raise TemplateSyntaxError(
'"cacheback" tag got a non-integer timeout value: %r' % expire_time)

vary_on = [var.resolve(context) for var in self.vary_on]
return CacheJob().get(self.nodelist, context, expire_time, self.fragment_name, vary_on)


@register.tag('cacheback')
def do_cacheback(parser, token):
"""
This will cache the contents of a template fragment for a given amount
of time.
Usage::
{% load cacheback %}
{% cacheback [expire_time] [fragment_name] %}
.. some expensive processing ..
{% endcacheback %}
This tag also supports varying by a list of arguments::
{% load cacheback %}
{% cacheback [expire_time] [fragment_name] [var1] [var2] .. %}
.. some expensive processing ..
{% endcacheback %}
Each unique set of arguments will result in a unique cache entry.
"""
nodelist = parser.parse(('endcacheback',))
parser.delete_first_token()
tokens = token.split_contents()
if len(tokens) < 3:
raise TemplateSyntaxError("'%r' tag requires at least 2 arguments." % tokens[0])
return CacheNode(
nodelist, parser.compile_filter(tokens[1]),
tokens[2], # fragment_name can't be a variable.
[parser.compile_filter(t) for t in tokens[3:]],
)