本文介绍了适当缩进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'(\r\n|\r|\n)')
INDENT = re.compile(r'(?:\r\n|\r|\n)([\ \t]+)')


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'(\r\n|\r|\n)' + indent, r'\1', text)

        # Add one indentation level
        if isinstance(node, (BlockNode, ConstantIncludeNode, IncludeNode)):
            text = text.strip()
            if '\r' in text or '\n' 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 对象:

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


  • 检查 is_rendered 属性以查看响应是否已呈现

  • 通过以下方式验证文档类型:

    • 在中查找所需的文件类型( .html) code> template_name 属性

    • 查看 content_type 属性(Django 1.5) code> 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模板(没有猴子修补)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-16 08:27