Flask如何实现如下图所示类似形式的文章编辑界面?
左侧编辑,右侧实时预览
可以使用 PageDown
Flask-PageDown
Markdown
Bleach
这几个包,其中Flask-PageDown
可以实现Markdown的预览,具体可以参考一下《Flask Web开发:基于python的web用用开发实战》这本书的第十一章,里面做出的效果就是这种带预览的markdown编辑。
SegmentFault似乎使用的是一个叫WMD的编辑器,而我稍微百度了下,发现SF也对这个编辑器做了点改动
首先你得需要一个类似WMD的编辑器,然后根据你的需要放置在页面中即可..
这个具体的问题要具体分析,展开就太长了..
下面是我自己做的一个很丑的md
编辑器,样式没有优化:
用的就是楼上说的PageDown
、Flask-PageDown
、Markdown
、Bleach
这几个库。以后有时间了准备用vue
来重做。
做一个简单的md
编辑器比较容易。
1 定义form
:
class ArticleForm(Form):
title = StringField(u"标题", validators=[Required()])
category = QuerySelectField(u"分类", query_factory=getUserFactory(['id', 'name']), get_label='name')
tags = StringField(u"标签", validators=[Required()]) #这里本来准备绑定到`models.py`定义的`Tag`表的,但是`WTFORMS`貌似没有这种字段,只有用字符串来表示了
content = PageDownField(u"正文", validators=[Required()])
submit = SubmitField(u"发布")
2 模板渲染
主要是控制css
样式,样式用的都是bootstrap
基本样式,不要用quick_form
:
<div class="edit_article">
<form action="" method="post" class="form" role="form">
{{ form.hidden_tag() }}
<div class="form-group required">
{{ form.title(id="title", class="form-control", placeholder=form.title.label.text )}}
</div>
<div class="form-group">
<div class="row">
<div class="col-md-6">
{{ form.category(id="category", class="form-control", placeholder=form.category.label.text ) }}
</div>
<div class="col-md-6">
{{ form.tags(type="text", class="token-input ui-autocomplete-input", id="tokenfield", autocomplete="off", placeholder=form.tags.label.text) }}
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-md-6">
{{ form.content(only_input=True, class="input-markdown", placeholder=form.content.label.text) }}
</div>
<div class="col-md-6">
{{ form.content(only_preview=True) }}
</div>
</div>
</div>
<div class="form-group">
{{ form.submit(class="btn btn-default") }}
</div>
</form>
</div>
3 md
转html
这一步放在models.py
的Article
类中:
class Article(db.Model):
...
@staticmethod
def on_changed_body(target, value, oldvalue, initiator):
# 需要转换的标签
allowed_tags = [
'a', 'abbr', 'acronym', 'b', 'blockquote', 'code',
'em', 'i', 'li', 'ol', 'pre', 'strong', 'ul',
'h1', 'h2', 'h3', 'p', 'img'
]
# 需要提取的标签属性,否则会被忽略掉
attrs = {
'*': ['class'],
'a': ['href', 'rel'],
'img': ['src', 'alt']
}
target.content_html = bleach.linkify(
bleach.clean(
markdown(value, output_format='html'),
tags=allowed_tags,
attributes=attrs,
strip=True
)
)
ps: 标签处理用的bootstrap-tokenfield。
其实你需要的只是Flask-PageDown的文档。
这个WMD好像可以在前端实时预览,应该是stackoverflow衍生出来的!