Flask实现Markdown在线编辑与解析
[Python] [Web Development]
思路
- 前端加载Markdown编辑器,数据通过POST传数据到后端并存入数据库。
- 后端取出数据,在模板中将Markdown解析为HTML再输出给用户。
在线编辑器
使用开源产品: Editor.md
安装
从github下载zip,解压重命名为editormd
,并置入Flask的static
文件夹。
路由
model.py
@main_blueprint.route('/test1')
def test_1():
mkd = '''
# header
## header2
[picture](http://www.example.com)
* 1
* 2
* 3
**bold**
'''
return render_template('test_1.html', mkd=mkd)
模板
注意使用url_for()导入css和js文件,并以其中一个div的id值初始化editormd(),这个div即显示为在线编辑器。
test_1.html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8"/>
<title>Simple example</title>
<link rel="stylesheet" href="{{ url_for('static',filename='editormd/css/editormd.css') }}"/>
</head>
<body>
<div id="test-editormd">
</div>
<script src="{{ url_for('static',filename='js/jquery.min.js') }}"></script>
<script src="{{ url_for('static',filename='editormd/editormd.min.js') }}"></script>
<script type="text/javascript">
var testEditor;
$(function () {
testEditor = editormd("test-editormd", {
width: "90%",
height: 640,
syncScrolling: "single",
path: "{{ url_for('static',filename='editormd/lib/') }}"
});
});
</script>
</body>
</html>
效果
运行Flask之后访问路由效果:
解析器
解析器使用 Flask-Markdown 插件
安装
pip install flask-markdown
使用
绑定app
from flask_markdown import Markdown
app=Flask(__name__)
Markdown(app)
然后在Jinja中使用过滤器将Markdown转为HTML
{{post.text|markdown|safe}}
实例
使用Flask-WTF设置<textarea>
标签存放文章内容。
forms.py
class PostForm(FlaskForm):
title = StringField('Title', [DataRequired(), length(max=255)])
text = TextAreaField('Content', [DataRequired()])
categories = SelectMultipleField('Categories', coerce=int)
def __init__(self):
super(PostForm, self).__init__()
self.categories.choices = [(c.id, c.title) for c in Category.query.order_by('id')]
从库中查出文章内容,并将其赋予Form的<textarea>
标签,传入模板文件。
controller/blog.py
@login_required
@blog_blueprint.route('/edit/<int:id>', methods=['GET', 'POST'])
def edit_post(id):
p = Post.query.get_or_404(id)
if current_user != p.user:
abort(403)
form = PostForm()
if form.validate_on_submit():
p.title = form.title.data
p.text = form.text.data
p.modified_date = datetime.datetime.now()
db.session.add(p)
db.session.commit()
flash('Edit Saved.', category='success')
return redirect(url_for('.post', id=p.id))
form.title.data = p.title
form.text.data = p.text
return render_template('edit.html', form=form, post=p)
模板中将编辑器与我们Form中的<textarea>
组合。
post_edit.html
{% extends "base.html" %}
{% block title %}Edit Post{% endblock %}
{% block body %}
<link rel="stylesheet" href="{{ url_for('static',filename='editormd/css/editormd.css') }}"/>
<div class="row">
<h1 class="text-center">Edit Post</h1>
<form method="post" action="{{ url_for('.edit_post',id=post.id) }}">
{{ form.hidden_tag() }}
<div class="form-group">
{{ form.title.label }}
{% if form.title.errors %}
{% for e in form.title.errors %}
<p class="help-block">{{ e }}</p>
{% endfor %}
{% endif %}
{{ form.title(class_='form-control') }}
</div>
<div class="form-group">
{{ form.text.label }}
{% if form.text.errors %}
{% for e in form.text.errors %}
<p class="help-block">{{ e }}</p>
{% endfor %}
{% endif %}
<div id="editormd" class="form-control">
{{ form.text(style="display:none;") }}
</div>
</div>
<input class="btn btn-primary" type="submit" value="Edit">
</form>
</div>
{% endblock %}
{% block js %}
<script src="{{ url_for('static',filename='editormd/editormd.min.js') }}"></script>
<script type="text/javascript">
var testEditor;
$(function () {
testEditor = editormd("editormd", {
width: "100%",
height: "100%",
syncScrolling: "single",
path: "{{ url_for('static',filename='editormd/lib/') }}"
});
});
</script>
{% endblock %}
最终效果
现在使用这个编辑器输入的数据将以Markdown格式存入数据库。
接下来在解析页面的模板中加入markdown
过滤器即可。
<div class="col-lg-12 post-text">
{{ post.text|markdown|safe }}
</div>
页面效果(也就是本篇文章的效果)
Tip
Flask-Markdown使用Python第三方库Markdown解析,其默认不识别三个反引号的code-block,需开启扩展。
import markdown
def markdown2html(text):
return markdown.markdown(text, ['extra'])