Ticket #1065: fragment_caching.diff
File fragment_caching.diff, 5.7 KB (added by , 17 years ago) |
---|
-
django/templatetags/fragment_caching.py
=== added file 'django/templatetags/fragment_caching.py'
1 from django.template import Library, Node, TemplateSyntaxError 2 from django.template import resolve_variable 3 from django.core.cache import cache 4 from django.utils.encoding import force_unicode 5 6 register = Library() 7 8 class CacheNode(Node): 9 def __init__(self, nodelist, expire_time, fragment_name, vary_on): 10 self.nodelist = nodelist 11 self.expire_time = expire_time 12 self.fragment_name = fragment_name 13 self.vary_on = vary_on 14 15 def render(self, context): 16 # Build a unicode key for this fragment and all vary-on's. 17 cache_key = u':'.join([self.fragment_name] + \ 18 [force_unicode(resolve_variable(var, context)) for var in self.vary_on]) 19 value = cache.get(cache_key) 20 if value is None: 21 value = self.nodelist.render(context) 22 cache.set(cache_key, value, self.expire_time) 23 return value 24 25 def do_cache(parser, token): 26 """ 27 This will cache the contents of a template fragment for a given amount 28 of time. 29 30 Usage:: 31 32 {% load fragment_caching %} 33 {% cache [expire_time] [fragment_name] %} 34 .. some expensive processing .. 35 {% endcache %} 36 37 This tag also supports varying by a list of arguments:: 38 39 {% load fragment_caching %} 40 {% cache [expire_time] [fragment_name] [var1] [var2] .. %} 41 .. some expensive processing .. 42 {% endcache %} 43 44 Each unique set of arguments will result in a unique cache entry. 45 """ 46 nodelist = parser.parse(('endcache',)) 47 parser.delete_first_token() 48 tokens = token.contents.split() 49 if len(tokens) < 3: 50 raise TemplateSyntaxError(u"'%r' tag requires at least 2 arguments." % tokens[0]) 51 try: 52 expire_time = int(tokens[1]) 53 except ValueError: 54 raise TemplateSyntaxError(u"First argument to '%r' must be an integer (got '%s')." % (tokens[0], tokens[1])) 55 return CacheNode(nodelist, expire_time, tokens[2], tokens[3:]) 56 57 register.tag('cache', do_cache) -
docs/cache.txt
=== modified file 'docs/cache.txt'
286 286 above example, the result of the ``slashdot_this()`` view will be cached for 15 287 287 minutes. 288 288 289 Fragment caching 290 ================ 291 292 If you're after even more control, you can also easily cache template fragments 293 using the ``cache`` template tag. To give your template access to this tag, put 294 ``{% load fragment_caching %}`` near the top of your template. 295 296 The ``{% cache %}`` template tag caches the contents of the block for a given 297 amount of time and takes at least two arguments. The first argument is the 298 cache timeout, in seconds. The second argument is the name to give the cache 299 fragment. For example:: 300 301 {% load fragment_caching %} 302 {% cache 500 sidebar %} 303 .. sidebar .. 304 {% endcache %} 305 306 Sometimes you might want to cache multiple copies of a fragment depending on 307 some dynamic data that appears inside the fragment. For example you may want a 308 separate cached copy of the sidebar used in the previous example for every user 309 of your site. This can be easily achieved by passing additional arguments to 310 the ``{% cache %}`` template tag to uniquely identify the cache fragment:: 311 312 {% load fragment_caching %} 313 {% cache 500 sidebar request.user.username %} 314 .. sidebar for logged in user .. 315 {% endcache %} 316 317 If you need more than one argument to identify the fragment that's fine, simply 318 pass as many arguments to ``{% cache %}`` as you need! 319 289 320 The low-level cache API 290 321 ======================= 291 322 -
tests/regressiontests/templates/tests.py
=== modified file 'tests/regressiontests/templates/tests.py'
741 741 'url-fail01' : ('{% url %}', {}, template.TemplateSyntaxError), 742 742 'url-fail02' : ('{% url no_such_view %}', {}, ''), 743 743 'url-fail03' : ('{% url regressiontests.templates.views.client no_such_param="value" %}', {}, ''), 744 745 ### FRAGMENT CACHING ############################################### 746 'cache01' : ('{% load fragment_caching %}{% cache -1 test %}cache01{% endcache %}', {}, 'cache01'), 747 'cache02' : ('{% load fragment_caching %}{% cache -1 test %}cache02{% endcache %}', {}, 'cache02'), 748 'cache03' : ('{% load fragment_caching %}{% cache 100 test %}cache03{% endcache %}', {}, 'cache03'), 749 'cache04' : ('{% load fragment_caching %}{% cache 100 test %}cache04{% endcache %}', {}, 'cache03'), 750 'cache05' : ('{% load fragment_caching %}{% cache 100 test foo %}cache05{% endcache %}', {'foo': 1}, 'cache05'), 751 'cache06' : ('{% load fragment_caching %}{% cache 100 test foo %}cache06{% endcache %}', {'foo': 2}, 'cache06'), 752 'cache07' : ('{% load fragment_caching %}{% cache 100 test foo %}cache06{% endcache %}', {'foo': 1}, 'cache05'), 753 754 # Raise exception if we dont have at least 2 args, first one integer. 755 'cache08' : ('{% load fragment_caching %}{% cache %}{% endcache %}', {}, template.TemplateSyntaxError), 756 'cache09' : ('{% load fragment_caching %}{% cache 1 %}{% endcache %}', {}, template.TemplateSyntaxError), 757 'cache10' : ('{% load fragment_caching %}{% cache foo bar %}{% endcache %}', {}, template.TemplateSyntaxError), 744 758 } 745 759 746 760 # Register our custom template loader.