From 7a6fd8f90e64cae5f741ac6a75af47145263f0f2 Mon Sep 17 00:00:00 2001 From: Jannis Leidel Date: Wed, 13 Apr 2011 15:56:19 +0200 Subject: [PATCH] Refactored render method of the template tag by popular request. Refs issue #21. --- compressor/templatetags/compress.py | 94 ++++++++++++++++------------- 1 file changed, 52 insertions(+), 42 deletions(-) diff --git a/compressor/templatetags/compress.py b/compressor/templatetags/compress.py index 3850b5b..4e5337b 100644 --- a/compressor/templatetags/compress.py +++ b/compressor/templatetags/compress.py @@ -48,54 +48,64 @@ class CompressorNode(template.Node): def cache_key(self, compressor): return "%s.%s.%s" % (compressor.cachekey, self.mode, self.kind) - def render(self, context, forced=False, debug=False): + def debug_mode(self, context): if settings.COMPRESS_DEBUG_TOGGLE: # Only check for the debug parameter # if a RequestContext was used request = context.get('request', None) if request is not None: - debug = settings.COMPRESS_DEBUG_TOGGLE in request.GET - # If enabled and in offline mode, and not forced or in debug mode - # check the offline cache and return the result if given + return settings.COMPRESS_DEBUG_TOGGLE in request.GET + + def render_offline(self, forced): + """ + If enabled and in offline mode, and not forced or in debug mode + check the offline cache and return the result if given + """ if (settings.COMPRESS_ENABLED and - settings.COMPRESS_OFFLINE) and not forced and not debug: - content = cache.get(get_offline_cachekey(self.nodelist)) - if content: - return content - # Render the actual tag content to return it if in debug mode - content = self.nodelist.render(context) - if debug: - return content - # The actual compressor instance - compressor = self.compressor_cls(content) - # If compression is enabled check the cache with the compressor's - # cache key (that containes mtime values if files are involved) - if settings.COMPRESS_ENABLED: - cachekey = self.cache_key(compressor) - output = self.cache_get(cachekey) - # or just ignore that part completely - else: - cachekey = output = None - # If there is any previously handled output or an active force, - # use it, Luke. - if output is None or forced: - try: - output = compressor.output(self.mode, forced=forced) - # If a cache key from the compressor was previously - # generated use it to store the compressor output - if cachekey: - self.cache_set(cachekey, output) - except: - # Catch all exception, I know :( - if settings.DEBUG or forced: - # Be very loud about the exception we just encountered - from traceback import format_exc - raise Exception(format_exc()) - else: - # Or don't do anything in production - return content - # Well, show the cached entry from earlier, if found. - return output + settings.COMPRESS_OFFLINE) and not forced: + return cache.get(get_offline_cachekey(self.nodelist)) + + def render_cached(self, compressor, forced): + """ + If enabled checks the cache for the given compressor's cache key + and return a tuple of cache key and output + """ + if settings.COMPRESS_ENABLED and not forced: + cache_key = self.cache_key(compressor) + cache_content = self.cache_get(cache_key) + return cache_key, cache_content + return None, None + + def render(self, context, forced=False): + # 1. Check if in debug mode + if self.debug_mode(context): + return self.nodelist.render(context) + + # 2. Try offline cache. + cached_offline = self.render_offline(forced) + if cached_offline: + return cached_offline + + # 3. Prepare the actual compressor and check cache + compressor = self.compressor_cls(self.nodelist.render(context)) + cache_key, cache_content = self.render_cached(compressor, forced) + if cache_content is not None: + return cache_content + + # 4. call compressor output method and handle exceptions + try: + rendered_output = compressor.output(self.mode, forced=forced) + if cache_key: + self.cache_set(cache_key, rendered_output) + return rendered_output + except: + if settings.DEBUG or forced: + # Be very loud about the exception we just encountered + from traceback import format_exc + raise Exception(format_exc()) + + # 5. Or don't do anything in production + return self.nodelist.render(context) @register.tag def compress(parser, token):