【问题标题】:Minify HTML output from Flask application with Jinja2 templates使用 Jinja2 模板缩小 Flask 应用程序的 HTML 输出
【发布时间】:2012-11-15 06:26:56
【问题描述】:

是否有 Flask 或 Jinja2 配置标志/扩展来在渲染模板后自动缩小 HTML 输出?

【问题讨论】:

标签: python web-applications flask wsgi jinja2


【解决方案1】:

找到了一个更好的方法来做到这一点。您可以使用此方法缩小所有页面:

from flask import Flask
from htmlmin.main import minify

app = Flask(__name__)


@app.after_request
def response_minify(response):
    """
    minify html response to decrease site traffic
    """
    if response.content_type == u'text/html; charset=utf-8':
        response.set_data(
            minify(response.get_data(as_text=True))
        )

        return response
    return response

【讨论】:

  • 在 python2.7 上按预期完美运行,但在 python2.6 上表现异常。引发“ValueError:格式中的零长度字段名称”异常。
  • 感谢伟大的代码 sn-p。我已将其调整为 beautify,而不是缩小输出:stackoverflow.com/a/43606937/2648551
  • 这不是在每次请求时都会缩小输出吗?它不能改变模板的缓存版本(或在保存缓存之前缩小它)吗?
【解决方案2】:

看看这里https://github.com/cobrateam/django-htmlmin#using-the-html_minify-function

我意识到它主要用于 django,但我认为该示例显示了如何使用此项目代码通过烧瓶视图执行您想要的操作。

【讨论】:

  • 不幸的是,它的setup.py 文件仍然需要 Django。
  • this之后不再。
  • 是否有“部署时间”的解决方案,类似于很多 js 项目的做法?没有理由每次在每次请求时都缩小大多数模板和静态数据。如果可以缩小在 setup.py 期间可能发生的所有事情,那就太好了。
【解决方案3】:

我使用以下装饰器

import bs4
import functools
import htmlmin


def prettify(route_function):
    @functools.wraps(route_function)
    def wrapped(*args, **kwargs):
        yielded_html = route_function(*args, **kwargs)
        soup = bs4.BeautifulSoup(yielded_html, 'html.parser')
        return soup.prettify()

    return wrapped

def uglify(route_function):
    @functools.wraps(route_function)
    def wrapped(*args, **kwargs):
        yielded_html = route_function(*args, **kwargs)
        minified_html = htmlmin.minify(yielded_html)
        return minified_html

    return wrapped

然后像这样简单地包装了默认的 render_template 函数

if app.debug:
    flask.render_template = prettify(flask.render_template)
else:
    flask.render_template = uglify(flask.render_template)

这具有自动添加到缓存中的额外好处,因为我们实际上并没有触及 app.route

【讨论】:

  • 遗憾的是,您仍然需要应用到导入它的每个视图文件……我曾希望您可以更改引擎,并且我所有文件的所有输出都会被缩小。
【解决方案4】:

我已经编写了一个烧瓶扩展来实现这个目的。您可以使用 pip install flask-htmlmin 安装它,源代码位于 https://github.com/hamidfzm/Flask-HTMLmin 。希望对你有用。

【讨论】:

  • 从“我想知道如何在flask中轻松缩小HTML”的想法到“当然有人对SO有这个问题”到“啊,自然有一个图书馆”,最后得出了这个结论回答“神话般的 hamidfzm 编写了一个烧瓶插件,可以在 2 行中完成所有操作”?
【解决方案5】:

使用装饰器。

from htmlmin.decorator import htmlmin

@htmlmin
def home():
...

或者你可以使用:

re.sub(r'>\s+<', '><', '<tag>   </tag>') # results '<tag></tag>'

【讨论】:

  • 你能提供一些参考链接吗?
  • 小心该正则表达式,它可能会以可见的方式破坏您的 HTML。缩小字符串 a &lt;b&gt;big&lt;/b&gt; &lt;i&gt;fat&lt;/i&gt; &lt;s&gt;edit&lt;/s&gt; here 会导致输出 a &lt;b&gt;big&lt;/b&gt;&lt;i&gt;fat&lt;/i&gt;&lt;s&gt;edit&lt;/s&gt; here - 空格已被破坏。
  • 标准省略了字符之间的空格。例如在 Django 中有一个 {% spaceless %} 标签和 htmlminminify 方法的原因之一。
  • 这对缓存有效还是只有 Ethan McCue 的答案有效? (我还没有进一步调查,但也许你已经知道答案_)
  • 当然会。 Ethan 的方法是 bs4 的一个荒谬的矫枉过正。
【解决方案6】:

为了扩展来自@olly_uk 的答案和@Alexander 的评论的有用性,似乎django-htmlmin 扩展现在设计用于与Django 以外的框架一起使用。

从文档here,您可以在 Flask 视图中手动使用 html_minify 函数,如下所示:

from flask import Flask
from htmlmin.minify import html_minify

app = Flask(__name__)

@app.route('/')
def home():
    rendered_html = render_template('home.html')
    return html_minify(rendered_html)

【讨论】:

  • 这是在模板运行时还是在编译时工作?
  • @llamawithabowlcut,在运行时渲染模板后调用 html_minify。如果问题背后的问题是性能,我也会尽可能将其与 Flask 缓存(在我的实例中为 Flask-cacheify)结合起来。如果这不可能,那么是的,为每个视图服务调用 html_minify 可能会相对昂贵。
  • 我可以使用re 模块做到这一点:return sub(r'\s{2,}|[\r\n]', '', render_template('blah.html'))... 是什么让 minify 如此特别?
  • @Sasili Syrakis - 对于 OP 的用例,我不确定是否有任何构成“特殊”的东西,但它是注释感知的 - 允许您从缩小的 HTML 中包含或排除 cmets .它还带有一个方便的装饰器,具有静态 html 文件的命令行版本,并允许您按路径包含或排除文件。 *我没有用 Flask 尝试过这些功能。
【解决方案7】:

为最新版本的 htmlmin 修改 @Bletch 答案。

from flask import Flask
import htmlmin

app = Flask(__name__)

@app.route('/')
def home():
    rendered_html = render_template('home.html')
    return htmlmin.minify(rendered_html)

https://htmlmin.readthedocs.io/en/latest/quickstart.html

缩小后的 html 在标签之间仍然会有一些空格。如果我们想移除它,则需要在渲染模板时添加remove_empty_space =True 属性。

return htmlmin.minify(rendered_html, remove_empty_space =True)

https://htmlmin.readthedocs.io/en/latest/reference.html

【讨论】:

    猜你喜欢
    • 2010-09-20
    • 2011-03-13
    • 2011-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多