xhEditor簡介
xhEditor是一個基於jQuery開發的簡單迷你並且高效的可視化HTML編輯器,基於網絡訪問並且兼容IE 6.0+, Firefox 3.0+, Opera 9.6+, Chrome 1.0+, Safari 3.22+。
xhEditor曾經是我比較喜歡的編輯器,也是率先支援拖曳上傳的編輯器之一。 xhEditor在當年是優秀的編輯器,功能夠強大,使用體驗也相當好,拖曳上傳是我最喜歡的功能,只可惜已經停止開發了。 xhEditor最後的穩定版本是1.1.14,至今已超過2年未更新(2013年發布了開發版本1.2.1),作者已經停止開發和維護了,社區論壇完全不能打開。
由於xhEditor是基於jQuery開發,而對於新版本的jQuery,它並不能很好的支持,只有1.4版本的jQuery是支持得最好的。
雖然已經不再更新了,但在一些需要富文本編輯器的場合,她還是可以完全勝任的。
本文以1.1.14版本為例,講述如何在Flask專案中使用xhEditor編輯器,並實作圖片上傳、檔案上傳的後端功能。
xhEditor主要特點:
#精簡迷你:初始載入4個文件,包括:1個js(50k)+2個css(10k)+1張圖片(5k),總共65k。若js和css檔案進行gzip壓縮傳輸,可以進一步縮減約24k。
使用簡單:簡單的呼叫方式,加上一個class屬性就能將您的textarea立刻變成一個功能豐富的視覺化編輯器。
無障礙存取:提供WAI-ARIA全面支持,全鍵盤精細操作,全程語音嚮導,提供完美無障礙存取體驗,讓殘疾人也能夠譜寫精彩人生。
內建Ajax上傳:內建強大的Ajax上傳,包括HTML4和HTML5上傳支援(多檔案上傳、真實上傳進度及檔案拖放上傳),剪切板上上傳及遠端抓取上傳,追求完美的使用者上傳體驗。
Word自動清理:實作Word程式碼自動偵測並清理,提供高效完美的Word程式碼過濾方案,產生程式碼最優化精簡,但卻不遺失任何細節效果。
UBB視覺化編輯:提供完美的UBB視覺化編輯解決方案,在您獲得安全高效程式碼儲存的同時,又能享受視覺化編輯的便利。
在Flask專案中使用xhEditor
首先我們需要到xhEditor官網下載1.1.14版本的xhEditor編輯器,下載之後解壓縮到
Flask專案的static/xheditor目錄。
xhEditor提供2種初始化方式:Class初始化和JavaScript初始化。 Class初始化只需為textarea設定值為xheditor的class屬性,它就會自動變成xhEditor編輯器,一個頁面可以同時同在多個編輯器,而且這個類別屬性可以加入參數。 (PS:CKEditor也有這個功能)
對於這兩種初始化方式,官網有提供設定很方便的設定嚮導,使得設定相對比較簡單。
範例程式碼:
<head> <script type="text/javascript" charset="utf-8" src="{{ url_for('static', filename='xheditor/jquery/jquery-1.4.4.min.js') }}"></script> <script type="text/javascript" charset="utf-8" src="{{ url_for('static', filename='xheditor/xheditor-1.1.14-zh-cn.min.js') }}"></script> <style>.xheditor {width: 640px; height:320px;}</style> </head> <body> <textarea id="content" name="content" class="xheditor {tools:'mfull'}"></textarea> </body>
現在,我們就擁有一個xhEditor編輯器了。
開啟上傳功能
xhEditor的上傳功能需要設定幾個參數(以圖片上傳為例):
upImgUrl : 圖片檔案上傳接收URL,範例:/upload/,可使用內建變數{editorRoot}
upImgExt : 圖片上傳前限製本機文件副檔名,預設:jpg,jpeg,gif,png
這裡假設上傳檔案接收URL為/upload/,我們的編輯器初始化程式碼就變成:
<textarea class="xheditor {tools:'mfull',upImgUrl:'/upload/'}"></textarea>
其他類型的檔案上傳設定類別推。
Flask處理上傳請求
xhEditor支援2種上傳方式:標準HTML4上傳和HTML5上傳。
HTML4上傳使用標準的表單上傳網域,上傳檔案網域的name為:filedata
HTML5上傳的整個POST資料流就是上傳的檔案完整數據,而本地檔案名稱等資訊儲存
存於HTTP_CONTENT_DISPOSITION這個伺服器變數中
返回內容必需是標準的json字串,結構可以是如下:
{"err":"","msg":"200906030521128703.gif"} 或者 {"err":"","msg":{"url":"200906030521128703.jpg","localfile":"test.jpg","id":"1"}}
註:若選擇結構2,則url變數是必有。
文件上传处理示例代码:
def gen_rnd_filename(): filename_prefix = datetime.datetime.now().strftime('%Y%m%d%H%M%S') return '%s%s' % (filename_prefix, str(random.randrange(1000, 10000))) @app.route('/upload/', methods=['GET', 'POST']) def upload(): '''文件上传函数 本函数未做上传类型判断及上传大小判断。 ''' result = {"err": "", "msg": {"url": "", "localfile": ""}} if request.method == 'POST' and 'filedata' in request.files: # 传统上传模式,IE浏览器使用这种模式 fileobj = request.files['filedata'] fname, fext = os.path.splitext(fileobj.filename) rnd_name = '%s%s' % (gen_rnd_filename(), fext) fileobj.save(os.path.join(app.static_folder, 'upload', rnd_name)) result["msg"]["localfile"] = fileobj.filename result["msg"]["url"] = '!%s' % \ url_for('static', filename='%s/%s' % ('upload', rnd_name)) elif 'CONTENT_DISPOSITION' in request.headers: # HTML5上传模式,FIREFOX等默认使用此模式 pattern = re.compile(r"""\s.*?\s?filename\s*=\s*['|"]?([^\s'"]+).*?""", re.I) _d = request.headers.get('CONTENT_DISPOSITION').encode('utf-8') if urllib.quote(_d).count('%25') > 0: _d = urllib.unquote(_d) filenames = pattern.findall(_d) if len(filenames) == 1: result["msg"]["localfile"] = urllib.unquote(filenames[0]) fname, fext = os.path.splitext(filenames[0]) img = request.data rnd_name = '%s%s' % (gen_rnd_filename(), fext) with open(os.path.join(app.static_folder, 'upload', rnd_name), 'wb') as fp: fp.write(img) result["msg"]["url"] = '!%s' % \ url_for('static', filename='%s/%s' % ('upload', rnd_name)) return json.dumps(result)
远程抓图
一般情况下,当复制站外的图片时,我们希望可以把图片保存到本地,远程抓图就可以完成这个事情。
启用远程抓图功能,需要设置2个参数:
localUrlTest : 非本站域名测试正则表达式
remoteImgSaveUrl : 远程图片抓取接收程序URL
设置这2个参数之后,我们的编辑器初始化代码变成:
复制代码 代码如下:
这里表示抓取除localhost之外其它域名的图片。
远程抓图处理示例代码:
def gen_rnd_filename(): filename_prefix = datetime.datetime.now().strftime('%Y%m%d%H%M%S') return '%s%s' % (filename_prefix, str(random.randrange(1000, 10000))) @app.route('/uploadremote/', methods=['POST']) def uploadremote(): """ xheditor保存远程图片简单实现 URL用"|"分隔,返回的字符串也是用"|"分隔 返回格式是字符串,不是JSON格式 """ localdomain_re = re.compile(r'https?:\/\/[^\/]*?(localhost:?\d*)\/', re.I) imageTypes = {'gif': '.gif', 'jpeg': '.jpg', 'jpg': '.jpg', 'png': '.png'} urlout = [] result = '' srcUrl = request.form.get('urls') if srcUrl: urls = srcUrl.split('|') for url in urls: if not localdomain_re.search(url.strip()): downfile = urllib.urlopen(url) fext = imageTypes[downfile.headers.getsubtype().lower()] rnd_name = '%s%s' % (gen_rnd_filename(), fext) with open(os.path.join(app.static_folder, 'upload', rnd_name), 'wb') as fp: fp.write(downfile.read()) urlreturn = url_for('static', filename='%s/%s' % ('upload', rnd_name)) urlout.append(urlreturn) else: urlout.append(url) result = '|'.join(urlout) return result
更多Python的Flask站點中整合xhEditor文字編輯器相关文章请关注PHP中文网!