从 simplemde 写入 + inline-attachment 图片拖拽上传 到 parsedown 解析
准备工作#
安装富文本编辑器 sparksuite/simplemde-markdown-editor (感谢 Bestony 推荐)
yarn add simplemde --save
安装 markedjs/marked , 在 JS 中解析 markdown, 用于在编辑页面预览
yarn add marked
安装 erusev/parsedown , 在 php 中解析 markdown (感谢 Summer 鉴定并推荐)
composer require erusev/parsedown
----- 下面是代码部分了,一共涉及两个页面 -----
编辑页面#
HTML 部分:#
{{--文本输入框--}}
<textarea name="content" id="editor"></textarea>
JS 部分:#
// 用于生成预览的 js 文件
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
// 用于富文本编辑器的 js 文件
<script src="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.js"></script>
// 富文本编辑器的配置
<script>
var simplemde = new SimpleMDE({
element: $("#editor")[0],
autofocus: true,
autosave: {
enabled: true,
uniqueId: "#editor",
delay: 1000,
},
blockStyles: {
bold: "__",
italic: "_"
},
forceSync: true,
hideIcons: ["guide", "heading"],
indentWithTabs: false,
insertTexts: {
horizontalRule: ["", "\n\n-----\n\n"],
image: [""],
link: ["[", "](http://)"],
table: ["", "\n\n| Column 1 | Column 2 | Column 3 |\n| -------- | -------- | -------- |\n| Text | Text | Text |\n\n"],
},
parsingConfig: {
allowAtxHeaderWithoutSpace: true,
strikethrough: false,
underscoresBreakWords: true,
},
placeholder: "下笔如有神",
// 在编辑页面生成预览
previewRender: function(plainText, preview) { // Returns HTML from a custom parser, Async method
setTimeout(function(){
preview.innerHTML = marked(plainText);
}, 250);
return "预览生成中......";
},
// 用 highlight.js 使代码高亮, 仅预览时生效
renderingConfig: {
codeSyntaxHighlighting: true,
},
});
</script>
展示页面#
HTML 部分:#
{{--用于代码高亮的样式文件--}}
<link href="https://cdn.bootcss.com/highlight.js/9.15.6/styles/a11y-dark.min.css" rel="stylesheet">
{{--内容输出--}}
{!! Parsedown::instance()->text($post->content) !!}
JS 部分:#
// 用于代码高亮的 JS 文件
<script src="https://cdn.bootcss.com/highlight.js/9.15.6/highlight.min.js"></script>
// for 代码高亮
hljs.initHighlightingOnLoad();
以上,就是从入到出的全过程,这个编辑器的视觉效果还蛮好的,简洁优雅.
But, 桑心的是它不支持图片上传功能,也不支持表情。希望走过路过的大神能随手丢几个 tips, 不胜感激.
2019 年 4 月 6 日更新 --- 增加图片拖拽功能#
一直很想解决这个问题,但是没有方向,终于有天看到了 [@Destiny](https://learnku.com/users/4430) 的 搭建博客必备:图片拖动文本框自动上传。讲的非常的细致。今天满怀开心加兴奋地想要实践到自己的项目里。如果只是普通的文本域,真的很好用。但是,由于我原本用的是 simplemde 编辑器,按照 Destiny 的方法拖拽不生效。看到评论区 [@hedeqiang](https://learnku.com/users/20847) 同学也遇到同样的问题,并用 codemirror 解决了,非常感激提供思路。 但是貌似实现的过程并不简单,因为如果只是简单的换个 js 文件的引用,就会多出一个文本框....... Whatever, 直接记录下我最终实现的过程吧.
首先是在官网下载包,然后把下面提到的 js 文件存到自己的项目里.
// 引入下面的文件
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/codemirror/4.0.3/codemirror.js"></script>
<script src="../js/inline-attachment.js"></script>
<script src="../js/codemirror-4.inline-attachment.js"></script>
// 这里是生成的 simplemde 对象
var simplemde = new SimpleMDE(.........);
// 在已有的 simplemde 对象的基础上再增加图片拖拽
inlineAttachment.editors.codemirror4.attach(simplemde.codemirror, {
// 传递 CSRF token
extraParams: {
'_token': "{{ csrf_token() }}",
},
// 设置图片上传的地址
uploadUrl: '{{ route('web.posts.imagesUpload') }}',
// 上传之后的处理
onFileUploadResponse: function(xhr) {
var result = JSON.parse(xhr.responseText),
filename = result[this.settings.jsonFieldName];
if (result && filename) {
var newValue;
if (typeof this.settings.urlText === 'function') {
newValue = this.settings.urlText.call(this, filename, result);
} else {
newValue = this.settings.urlText.replace(this.filenameTag, filename);
}
var text = this.editor.getValue().replace(this.lastValue, newValue);
this.editor.setValue(text);
this.settings.onFileUploaded.call(this, filename);
}
return false;
}
});
php 接收图片并上传到阿里云
public function imagesUpload(Request $request)
{
$file = $request->file();
// 我这里是对图片做了个裁切
$filename = $this->upload($file['file'], 500);
return \Response::json([
// 这个返回的 'filename' 是根据 inline-attachment.js 文件里的默认配置写的
'filename' => $filename
]);
}
因为 upload
方法比较常用,所以我单独提出来放在父级 controller 里:
protected function upload($file, $size)
{
$image = Image::make($file->getRealPath())->fit($size)->encode('jpg');
$filename = 'files/' . date('Y-m-d-h-i-s') . '-' . $file->getClientOriginalName();
$bool = Storage::disk('oss')->put($filename, $image->__toString());
if ($bool) {
return $filename;
} else {
return '';
}
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
我用这个 markdown 编辑器的时候,在编辑器代码里加
asset()
和{{ csrf_token() }}
会出现导致页面不能打开,这个有什么办法解决吗?
@仙人球上一点红 或者是
route()
之类的都会包没有这个方法上传图片不支持 webp