Is there any possibility to write into generated view verbose informations about template generation in debug mode? For example it could generate such output:
base.html:
<html>
<body>
{% block content %}
{% endblock %}
</body>
</html>
page.html:
{% extend "base.html" %}
{% block content %}
Foo
{% include "inner.html" %}
Bar
{% endblock %}
Into such form:
<html>
<body>
<!-- block content -->
<!-- from "page.html" -->
Foo
<!-- include "inner.html" -->
Bar
<!-- endblock content -->
</body>
</html>
Why? Because sometimes exploring some larger dependencies are very hard just by IDE. Or maybe you know some good tool for easier navigation (generating graphs etc.)? Of course this informations should be generated only in debug mode. In production they should disappear.
You might be able to achieve this using middlware. I was having a similar issue a while back keeping track of templates and the views calling them so I wrote a middleware snippet that added a comment block to the top of the html response. It doesn't quite do what you're asking but you might be able to adapt it.
COMMENT_BLOCK = """
<!--
[ url ] >> http://%(host)s%(path)s
[ referer ] >> %(referer)s
[ module ] >> %(module)s
[ function ] >> %(function)s, line %(line)s
[ args ] >> args=%(args)s, kwargs=%(kwargs)s, defaults=%(defaults)s
[ template ] >> %(template)s
-->
"""
# Add any additional template types you wish to add the comment block to.
MIMETYPES = (
"text/html",
"text/xml",
)
class HtmlTemplateFinder:
def __init__(self):
self.host = None
self.referer = None
self.path = None
self.module = None
self.function = None
self.line = None
self.args = None
self.kwargs = None
self.defaults = None
self.template = None
self.valid_template = False
def _populate_comment_block(self):
return COMMENT_BLOCK % {
'host': self.host,
'referer': self.referer,
'path': self.path,
'module': self.module,
'function': self.function,
'line': self.line,
'args': self.args,
'kwargs': self.kwargs,
'defaults': self.defaults,
'template': self.template,
}
def process_view(self, request, view_func, view_args, view_kwargs):
self.host = request.META.get('HTTP_HOST', None)
self.referer = request.META.get('HTTP_REFERER', None)
self.path = request.path
self.module = view_func.func_code.co_filename
self.function = ('.').join((view_func.__module__, view_func.func_name))
self.line = view_func.func_code.co_firstlineno
self.args = view_args
self.kwargs = view_kwargs
self.defaults = view_func.func_defaults
return None
def process_template_response(self, request, response):
from mimetypes import guess_type
# Use this rather than response.template_name, this always returns str
self.template = response.resolve_template(response.template_name).name
self.valid_template = guess_type(self.template)[0] in MIMETYPES
return response
def process_response(self, request, response):
from <your app> import settings
if settings.DEBUG:
if self.valid_template:
block = self._populate_comment_block()
response.content = "%s%s" % (block, response.content)
return response
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With