Login

EditingMiddleware (quickly open views and templates in your text editor!)

Author:
johnboxall
Posted:
June 2, 2009
Language:
Python
Version:
1.0
Score:
1 (after 1 ratings)

Heavily based on Snippet 1033 and Snippet 766.

This snippet tracks what view and templates are used to render HTML responses and inserts a small dialog in the top right corner of the output with links to all the files. If your text editor support opening files from a browser protocol you can click the links to open the files right up! For example TextMate supports the txmt:// protocol. Really saves some time if you find yourself editing a lot of templates.

txt

Usage

  1. Save this snippet in a file called middleware.py on your Python Path.
  2. Add middleware.EditingMiddleware to your MIDDLEWARE_CLASSES.
  3. Browse to any HTML page on your site!
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import os.path
from django.conf import settings
from django.template import Template, Context
from django.test.signals import template_rendered
from django.test.utils import instrumented_test_render
from django.utils.encoding import force_unicode


TEMPLATE = """
<div id="debug" style="background:#85BE40 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAASCAIAAAAVNSPrAAAAOElEQVQIHWMwSnZi2PGkjunWi5NM/xkYmBj+/2f6/x9IA9n/gGwGIPs/SOwfkGaA0iA+TP4fWD0AipEie4hB/+0AAAAASUVORK5CYII%3D) repeat-x;position:absolute;top:3px;left:3px;padding:5px;-moz-border-radius:5px;text-align:left;">
 <ul>
  <li>
   <a href="{{ view_link }}">{{ view_name }}</a>
   <a style="position:absolute;right:7px;" onclick="document.getElementById('debug').style.display='none';">x</a><br />
  </li>
  {% for t in templates %}
    <li {% if forloop.first %}style="border-top:1px solid white;margin-top:3px;padding-top:3px;"{% endif %}>
     <a href="{{ t.0 }}">{{ t.1 }}</a>
    </li>
  {% endfor %}
 </ul>
<div>
</body>
"""


# Monkeypatch instrumented test renderer from django.test.utils - we could use
# django.test.utils.setup_test_environment for this but that would also set up
# e-mail interception, which we don't want
if Template.render != instrumented_test_render:
    Template.original_render = Template.render
    Template.render = instrumented_test_render
# MONSTER monkey-patch
old_template_init = Template.__init__
def new_template_init(self, template_string, origin=None, name='<Unknown Template>'):
    old_template_init(self, template_string, origin, name)
    self.origin = origin
Template.__init__ = new_template_init


class EditingMiddleware(object):
    link_format = "edit://%s?%s"

    def process_request(self, request):
        self.templates = []
        template_rendered.connect(self.store_template)

    def process_view(self, request, view_func, view_args, view_kwargs):
        self.view_func = view_func
        self.view_args = view_args
        self.view_kwargs = view_kwargs

    def process_response(self, request, response):
        if not self.should_process_response(request, response):
            return response

        view_func = getattr(self, "view_func", None)
        if view_func is None:     
            return response
        
        debug_content = self.get_template().render(self.get_context())
        content = response.content
        response.content = force_unicode(content).replace('</body>', debug_content)
        return response
        
    def get_template(self):
        return Template(TEMPLATE)

    def should_process_response(self, request, response):
        return 'text/html' in response['Content-Type']

    def store_template(self, **kwargs):
        template = kwargs.get("template")
        if template is not None:
            self.templates.append(template)
        
    def get_context(self):
        templates = [
            (self.build_link(os.path.join(settings.TEMPLATE_DIRS[0], t.name)), t.name)
            for t in self.templates
        ]
        
        view_link = self.build_link(self.view_func.func_code.co_filename, 
            self.view_func.func_code.co_firstlineno)
        view_name = "%s.%s" % (self.view_func.__module__, self.view_func.func_name)
        
        return Context({
            "view_link": view_link,
            "view_name": view_name,
            "templates": templates})
    
    def build_link(self, filename, lineno=0):
        return self.link_format % (filename, lineno)
    
        

class TextMateEditingMiddleware(EditingMiddleware):
    link_format = "txmt://open/?url=file://%s&line=%s"        

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 3 months, 1 week ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 3 months, 2 weeks ago
  3. Serializer factory with Django Rest Framework by julio 10 months, 1 week ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 11 months ago
  5. Help text hyperlinks by sa2812 11 months, 3 weeks ago

Comments

Please login first before commenting.