Markdown編輯器——Editor.MD于Flask:
能預(yù)覽的Markdown編輯器中, 讀狗書時用的
Flask-Pagedown
比較不錯, 在逛知乎的時候?qū)W習greyli大神的flask富文本編輯器實現(xiàn)退腥,實踐中遇到 Editor.md很合胃口, 類似簡書或者 Remarkable的左右分欄預(yù)覽方式非常喜歡软舌,見坑就跳吧灿渴。
最終效果大概是這樣的:
Editor.md是個國人維護的開源項目, 四年沒更新不過還是很好用的譬嚣。相關(guān)Issues比較多庭再,基本上小問題翻翻即可解決,
首先進入Editor.md官網(wǎng)下載zip,或者點擊Github download下載
解壓重命名為editormd际起,并置入static文件夾
表單類里使用Flask-WTF設(shè)置<textarea>
標簽存放文章內(nèi)容, 定義TextAreaField字段, 對Body字段進行修改:
forms.py:
from wtforms import TextAreaField
#...
class PostForm(FlaskForm):
#...
body = TextAreaField('Body', [DataRequired()])
#...
此時編輯模板的js腳本, 用于拾取id=editormd
的 textarea 渲染的
這真的是一個坑大的決定悍缠,相關(guān)探究并無太多參考,Editor.MD已經(jīng)荒廢四年姑荷,相關(guān)文檔都未必打得開盒延,基本都是Java做后端,F(xiàn)lask上幾乎沒人用鼠冕。相關(guān)討論比較雜亂添寺,甚至有的錯漏百出⌒阜眩基本只能靠踩坑和閱讀源碼來運作计露。目前還在艱苦奮斗階段,有能力后會編寫相關(guān)拓展憎乙。
為便于支持更多的MarkDown格式甚至emoji代碼高亮表格解析等問題票罐。而不是一點點自定義,這次我們利用更強大的Editor.MD編輯自帶的Markdown2HTML渲染方式泞边。
new_post.html:
<link rel="stylesheet" href="{{ url_for('static',filename='editormd/css/editormd.css') }}"/>
這里我將Editor.MD置于static靜態(tài)文件目錄并重命名為editormd
该押,個人根據(jù)目錄自行更改即可。
使用saveHTMLToTextarea : true
字段開啟自動轉(zhuǎn)換HTML為后臺直接提取html文檔提供接口繁堡。其中js代碼處注意寬度設(shè)置與Bootstrap4的body相沖突沈善,這里我們注釋掉width
字段,否則將無法直接提取html椭蹄。如果是繼承模板闻牡,引入js較多時,可以在js的順序上優(yōu)先保證editor.MD绳矩,上下文在最后繼承
new_post.html:
<script src="{{ url_for('static',filename='editormd/examples/js/jquery.min.js') }}"></script>
<script src="{{ url_for('static',filename='editormd/editormd.min.js') }}"></script>
<script type="text/javascript">
$(function () {
editormd("fancy-editormd", {
// width: "100%", 請不要添加
height: 640,
syncScrolling: "single"罩润,
path: "{{ url_for('static',filename='editormd/lib/') }}",
saveHTMLToTextarea : true
});
});
</script>
{{ super() }}
結(jié)尾scripts段加載JS:順序為jQuery在前, editormd.min.js在后.
相關(guān)的textarea部分 new_post.html:
<div id="fancy-editormd" class="editormd">
{{ form.body(style="display:none;") }}
</div>
在編輯文章的部分也照做即可。
其中的"fancy-editormd"
字段是自定義的翼馆,用于拾取textarea
這里有個坑割以,如果使用WTForms渲染表單的話name屬性是無法更改的金度,而editormd理論上是通過name=“fancy-editormd-markdown-doc"
屬性來渲染我們編輯markdown文件的地方
這里不用擔心太多,如果沒有多個textarea的話严沥,其實我們只需要照常渲染formbody即可猜极,再次渲染時可見Editor.MD會自動找到第一個textarea并渲染為markdown編輯器,并自動為我們生成了一個textareaname=”fancy-editormd-html-code"
里面內(nèi)容即是Editor.MD的HTML文件消玄。
這里我們將其保存下來跟伏,以便歸檔查看以及預(yù)覽方便節(jié)省資源。如果正文渲染的話還是建議用markdown即時轉(zhuǎn)換這樣表格和特殊內(nèi)容更加直觀翩瓜,當然如果服務(wù)器并發(fā)訪問過多的話并不建議這么做受扳。
首先在Forms中我們自定義一個body_html用于保存撰寫文檔時Editor.MD留下的HTML格式文檔:
forms.py:
class PostForm(FlaskForm):
#...
body_html = HiddenField()
添加一個實例化數(shù)據(jù)庫模型字段的Column類在文章模型中,注意如果使用Flask-Whooshee全文搜索的話建立索引字段改為我們的html格式文檔兔跌,還好注意而后使用reindex()方法重建索引勘高。(目前文檔較少做了搜索也沒用,而后會單獨列出文章做詳細討論):
models.py:
@whooshee.register_model('title', 'body_html')
class Post(db.Model):
#...
body_html = db.Column(db.Text)
在文章管理藍本中直接使用request來獲取數(shù)據(jù)坟桅,不使用WTForms
admin.py:
from flask import request
# ...
@admin_bp.route('/post/new', methods=['GET', 'POST'])
@login_required
def new_post():
if form.validate_on_submit():
# ...
body_html = request.form['fancy-editormd-html-code']
post = Post(..., body_html = body_html)
#...
同樣在編輯文章的藍本中也要做相應(yīng)的修改:
@admin_bp.route('/post/<int:post_id>/edit', methods=['GET', 'POST'])
@login_required
def edit_post(post_id):
# ...
if form.validate_on_submit():
# ...
post.body_html = request.form['fancy-editormd-html-code']
# ...
# ...
form.body_html.data = post.body_html
# ...
此時我們要編輯的都編輯完了华望,在文檔正部直接調(diào)用轉(zhuǎn)換好的html即可,加個safe過濾器即可
{{ post.body_html| safe }}
當然代碼高亮以及表格支持這些等等桦卒,想要顯示出編輯時右邊的預(yù)覽的效果立美,還是需要調(diào)用Editor.MD的渲染,在文章正文的模板里做相應(yīng)的修改:
引入靜態(tài)文件方灾,
<link href="{{ url_for('static', filename='editormd/css/editormd.preview.min.css') }}" rel="stylesheet" />
<link href="{{ url_for('static', filename='editormd/css/editormd.css') }}" rel="stylesheet" />
<!--以下是js部分 -->
<script type="text/javascript" src="{{ url_for('static', filename='editormd/lib/marked.min.js') }}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='editormd/lib/prettify.min.js') }}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='editormd/editormd.min.js') }}"></script>
<script type="text/javascript">
editormd.markdownToHTML("fancy-content");
</script>
在文檔中定義我們自定義的fancy-content
<div class="content" id="fancy-content">
{{ post.body_html| safe }}
</div>
這里無需使用post原文建蹄,無需定義textarea,直接用flask-WTF的定義表單即可裕偿,直接使用html文件即可洞慎。
沒有引入Editor.MD的渲染表單:
渲染后:
再對比編輯欄效果:
在文章預(yù)覽處我們做相應(yīng)的修改,
_post.html :
<h3 class=`text-primary`><a href=`{{ url_for('.show_post', post_id=post.id) }}`>{{ post.title }}</a></h3>
<p>
<div class=`post-body`>
{% if post.body_html %}
{{ post.body_html |safe|striptags|truncate }}
{% else %}
{{ post.body }}
{% endif %}
</div>
<small><a href=`{{ url_for('.show_post', post_id=post.id) }}`>Read More</a></small>
</p>
先調(diào)用safe
轉(zhuǎn)義過濾器, 再調(diào)用striptags
清除html渲染后的格式, 最后調(diào)用truncate過濾器只保留開頭255個字符,而后慣例一個Read More
鏈接.
如果使用了Flask-Migrate的Alembic話,創(chuàng)建遷移環(huán)境生成遷移腳本更新數(shù)據(jù)庫三部曲即可嘿棘。由于數(shù)據(jù)庫已經(jīng)從SQlite遷移到了MySQL劲腿, 一切都沒什么。生產(chǎn)環(huán)境還是先備份以下
目前來說Markdown于Flask的實現(xiàn)應(yīng)該是打好了基礎(chǔ). Editor.md的界面比較討喜, 相比其他富文本編輯器更加受青睞. 關(guān)于Editor.md的進階功能還有許多, 日后需要還會繼續(xù)添加.至此鸟妙,Editor.MD的回調(diào)已經(jīng)完成了焦人。在下篇里我會談一下圖片上傳的問題。
個人是新入門的求職學生重父,歡迎大家指教