我正在尝试打印网页中文件的内容。 我想在单独的行上打印文件中的每一行,但缺少换行符。 如何打印文件并保留换行符?
@app.route('/users')
def print_users():
v = open("users.txt","r").read().strip()
# also tried:
# v = open("users.txt","r").read().strip().split('\n')
return render_template('web.html', v=v)
{{ v|safe}}
您可以使用:
v = open("users.txt","r").readlines()
v = [line.strip() for line in v]
然后在你的html中添加类似的内容(但随意使用它):
<form action="/print_users" method="post" >
<div class="form-inline">
{% for line in v %}
<div>{{ line|safe}}</div>
{% endfor %}
<input class="btn btn-primary" type="submit" value="submit" >
</div>
</form>
虽然其他答案提供了很好的技术并且当前接受的解决方案有效,但我需要执行类似的任务(呈现文本电子邮件模板),但需要扩展它以保留文件中宏的处理,这导致我创建我认为最简单、最优雅的解决方案是使用 render_template_string。
def show_text_template(template_name):
"""
Render a text template to screen.
Replace newlines with <br> since rendering a template to html will lose the line breaks
:param template_name: the text email template to show
:return: the text email, rendered as a template
"""
from flask import render_template_string
txt_template = open(
'{}/emails/{}{}'.format(app.config.root_path + '/' + app.template_folder, template_name, '.txt'),
"r").readlines()
return render_template_string('<br>'.join(txt_template))
解决方案是使用
nl2br
Jinja 过滤器。
from markupsafe import Markup, escape
def nl2br(value):
"""Securely replace all newline characters '\n' by HTML '<br>' break tags."""
safe_value = str(escape(value))
formatted_value = safe_value.replace("\n", "<br>")
return Markup(formatted_value)
<p> {{ yourinputstring | nl2br }} </p>
为了解释,您希望将输入字符串中的换行符
\n
替换为输出模板中的 HTML 换行符标记 <br>
。
问题在于,出于安全原因(特别是为了防止
XSS 漏洞),Jinja 会转义特殊字符,例如
<
或 >
。因此,如果您只是将 \n
字符替换为 <br>
标签,它们将被转义并且不起作用。
<p> {{ yourinputstring | safe }} </p> <!-- DON'T DO THIS -->
您可以要求模板中的 Jinja 不要使用
safe
过滤器转义字符,但这会使您容易受到 XSS 攻击(尤其是当输入来自用户时)。强烈建议不要这种做法。
我不知道为什么这没有在本地实现,但唯一的解决方案是使用自定义过滤器。
MarkupSafe
是Jinja和Flask使用的模块,所以它应该已经安装了。
如果您使用 Flask,您的代码将如下所示:
from flask import Flask, render_template
from markupsafe import Markup, escape
server = Flask(__name__)
@server.template_filter()
def nl2br(value):
"""Securely replace all newline characters '\\n' by HTML '<br>' break tags."""
safe_value = str(escape(value))
formatted_value = safe_value.replace("\n", "<br>")
return Markup(formatted_value)
@server.route("/index.html")
def index():
input_string = "hello, world!\n"
dangerous_input = "<script>alert('XSS');</script>"
return render_template("index.html", input_1=input_string, input_2=dangerous_input)
if __name__ == "__main__":
server.run(debug=True, port=8080)
使用
index.html
模板为:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Jinja custom filter for newline characters</title>
</head>
<body>
<p>{{ input_1 | nl2br }}<p>
<p>{{ input_2 | nl2br }}</p>
</body>
</html>
渲染的 HTML 看起来像这样,有效地将
\n
转换为 <br>
,同时防止 XSS 攻击:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Jinja custom filter for newline characters</title>
</head>
<body>
<p>hello, world!<br><p>
<p><script>alert('XSS');</script></p>
</body>
</html>
顺便说一句,有人绝对应该建议 Jinja 维护者在本地实现这个,因为它似乎是非常基本且普遍有用的东西。