Django 模板中的正确缩进(没有猴子补丁)? [英] Proper indentation in Django templates (without monkey-patching)?

查看:21
本文介绍了Django 模板中的正确缩进(没有猴子补丁)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为我的独立应用程序生成由 Django 模板系统预处理的人类可读的 HTML 和 CSS 代码(正确缩进).

I want to generate human-readable HTML and CSS code (properly indented) preprocessed by the Django template system for my standalone application.

我修改了 django.template.base 模块中 NodeList 类的渲染方法.我的代码似乎工作正常,但我使用猴子补丁来替换旧的渲染方法.

I've modified the render method from the NodeList class found in the django.template.base module. My code seems to work properly, but I'm using monkey-patching to replace the old render method.

在这种情况下,有没有更优雅的方式不使用猴子补丁?或者,也许猴子补丁是这里最好的方法?

Is there a more elegant way that does not use monkey-patching in this case? Or maybe monkey-patching is the best way here?

我的代码如下:

'''
This module monkey-patches Django template system to preserve
indentation when rendering templates.
'''

import re

from django.utils.encoding import force_text
from django.utils.safestring import mark_safe
from django.template.loader import render_to_string
from django.template import Node, NodeList, TextNode
from django.template.loader_tags import (BlockNode, ConstantIncludeNode,
                                         IncludeNode)


NEWLINES = re.compile(r'(
|
|
)')
INDENT = re.compile(r'(?:
|
|
)([ 	]+)')


def get_indent(text, i=0):
    '''
    Depending on value of `i`, returns first or last indent
    (or any other if `i` is something other than 0 or -1)
    found in `text`. Indent is any sequence of tabs or spaces
    preceded by a newline.
    '''
    try:
        return INDENT.findall(text)[i]
    except IndexError:
        pass


def reindent(self, context):
    bits = ''
    for node in self:
        if isinstance(node, Node):
            bit = self.render_node(node, context)
        else:
            bit = node
        text = force_text(bit)

        # Remove one indentation level
        if isinstance(node, BlockNode):
            if INDENT.match(text):
                indent = get_indent(text)
                text = re.sub(r'(
|
|
)' + indent, r'1', text)

        # Add one indentation level
        if isinstance(node, (BlockNode, ConstantIncludeNode, IncludeNode)):
            text = text.strip()
            if '
' in text or '
' in text:
                indent = get_indent(bits, -1)
                if indent:
                    text = NEWLINES.sub(r'1' + indent, text)

        bits += text

    return mark_safe(bits)


# Monkey-patching Django class
NodeList.render = reindent

推荐答案

修改模板层是可以的,但不是最优的,因为它只是处理节点的渲染方式,而不是整个文档.我建议 编写自定义中间件为您的项目漂亮地打印 html 和 css 页面的渲染响应.

Modifying the template layer would be ok, but not optimal, because it simply handles how a node is rendered, not an entire document. I would recommend writing custom middleware for your project to pretty-print the rendered response for html and css pages.

您的中间件需要实现 process_template_response,它应该用于查看和更新​​ SimpleTemplateResponse 对象:

Your middleware will need to implement process_template_response which should be used to view and update the SimpleTemplateResponse object:

  • 检查 is_rendered 属性以查看响应是否已呈现
  • 通过以下任一方式验证文档类型:
    • template_name 属性的末尾寻找所需的文件类型(.html.css)
    • 查看 content_type 属性(Django 1.5)或可能的 mimetype 以获取较旧的安装
    • Check the is_rendered attribute to see if the response has been rendered
    • Verify the document type by either:
      • Looking for the desired file type (.html, .css) at the end of the template_name attribute
      • Looking at the content_type attribute (Django 1.5) or possibly mimetype for older installs

      我认为中间件是一个更优雅的解决方案,因为这最终不会对您的文件进行词法更改.它与确定模板内容的逻辑完全分离(它没有业务存在).最后,您希望您的所有 html 和 css 看起来都很棒,那么为什么首先将其与您的模板联系起来呢?

      I think Middleware is a far more elegant solution because this ultimately makes no lexical changes to your files. It is entirely separated from the logic that determines your template content (where it has no business being). Finally, you want ALL of your html and css to look great, so why tie that to your templates in the first place?

      这篇关于Django 模板中的正确缩进(没有猴子补丁)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆