Tinymce 编辑器添加自定义图片管理插件
程序员文章站
2022-05-28 14:04:02
功能实现:用户可以通过文件夹来管理自己的图片,以便在进行文章编辑的时候来快速找到图片将其插入编辑器中, 在使用Tinymce的过程中需要用到图片上传功能,而提供的上传插件在上传文件后是给了一个连接地址,就想用户需要什么图片,不能用最直观的方式表现出来么! 虽然官网上也有一个文件管理的插件moxiem... ......
在使用tinymce的过程中需要用到图片上传功能,而提供的上传插件在上传文件后是给了一个连接地址,就想用户需要什么图片,不能用最直观的方式表现出来么!
虽然官网上也有一个文件管理的插件moxiemanager,可奈何他是收费的!
然后就打算自己弄一个,其实实现效果起来很简单,就只是做了一个类型相册管理的功能,然后在点击图片的时候,将图片的地址信息插入到编辑器里就行了,由于后台用的是layui
的框架,所以界面也就用了layui来实现,这里我只弄了上传,删除功能,也可自己添加检索等功能,实现效果如下
1 、添加插件
我们需要在tinymce的 plugins 目录下新建一个filemanager文件夹,并添加一个名为plugin.min.js ,其中editor传参后再图片管理页面通过
var editor = top.tinymce.activeeditor.windowmanager.getparams().editor; 获取编辑器对象,进行图片插入操作
tinymce.pluginmanager.add("filemanager", function (editor, url) {
editor.addbutton("filemanager", {
title: "图片管理",
icon: 'image',
onclick: function () {
editor.windowmanager.open({
title: "图片管理",
url: "/administrator/filemanager/editor",
width: window.innerwidth * 0.9,
height: window.innerheight * 0.8
}, {
editor: editor // pointer to access editor from cshtml
})
}
})
});
2. 相册功能实现
文件夹管理实体类
public class filemanagerdirectoryentity : baseentity
{
/// <summary>
/// 父级id
/// </summary>
public int parentid { get; set; }
/// <summary>
/// 文件夹名称
/// </summary>
public string name { get; set; }
/// <summary>
/// 路径
/// </summary>
public string fullpath { get; set; }
/// <summary>
/// 子文件数量
/// </summary>
public int childrencount { get; set; }
}
文件管理实体类
public class filemanagerdirectoryentity : baseentity
{
/// <summary>
/// 父级id
/// </summary>
public int parentid { get; set; }
/// <summary>
/// 文件夹名称
/// </summary>
public string name { get; set; }
/// <summary>
/// 路径
/// </summary>
public string fullpath { get; set; }
/// <summary>
/// 子文件数量
/// </summary>
public int childrencount { get; set; }
}
相册功能具体实现controller
public class filemanagercontroller : controller
{
#region core
private readonly irepository<filemanagerdirectoryentity> _filemanagerdirectoryrepository;
private readonly irepository<filemanagerfilesentity> _filemanagerfilesrepository;
private const string smallimage = "_small";
public filemanagercontroller(
irepository<filemanagerdirectoryentity> filemanagerdirectoryrepository,
irepository<filemanagerfilesentity> filemanagerfilesrepository
)
{
this._filemanagerdirectoryrepository = filemanagerdirectoryrepository;
this._filemanagerfilesrepository = filemanagerfilesrepository;
}
#endregion
/// <summary>
/// 编辑器插件
/// 获取文件数据
/// </summary>
/// <param name="dirid"></param>
/// <returns></returns>
public actionresult editor(int dirid = 0) {
list<filemanagerfilemodel> modellist = new list<filemanagerfilemodel>();
//加载该文件夹下的文件夹
var dirlist = _filemanagerdirectoryrepository.table
.where(x=>x.parentid==dirid)
.orderbydescending(x=>x.createtime)
.tolist();
foreach(var item in dirlist)
{
filemanagerfilemodel model = new filemanagerfilemodel();
model.id = item.id;
model.name = item.name;
model.fullpath = item.fullpath;
model.filetype = 2;
model.childrencount = item.childrencount;
modellist.add(model);
}
//加载该文件夹下的图片文件
var filelist = _filemanagerfilesrepository.table
.where(x => x.directoryid == dirid)
.orderbydescending(x => x.createtime)
.tolist();
foreach (var item in filelist)
{
filemanagerfilemodel model = new filemanagerfilemodel();
model.id = item.id;
model.name = item.name;
model.fullpath = item.fullpath;
model.smallfullpath = item.fullpath + smallimage + item.fileext;
model.filetype = 1;
modellist.add(model);
}
return view(modellist);
}
/// <summary>
/// 创建文件夹
/// </summary>
/// <param name="dirid"></param>
/// <returns></returns>
public actionresult _adddirectory(int dirid) {
return view();
}
/// <summary>
/// 文件夹信息保存
/// </summary>
/// <param name="dirid"></param>
/// <param name="dirname"></param>
/// <returns></returns>
public actionresult _adddirectorysave(int dirid , string dirname) {
var parentdirentity = _filemanagerdirectoryrepository.getbyid(dirid);
if (!string.isnullorempty(dirname))
{
var parentdirpath = parentdirentity == null ? "/content/filemanager/" : parentdirentity.fullpath;
if(parentdirentity != null)
{
parentdirentity.childrencount++;
}
filemanagerdirectoryentity entity = new filemanagerdirectoryentity();
entity.parentid = dirid;
entity.name = dirname;
entity.fullpath = string.format("{0}/{1}/", parentdirpath, guid.newguid());
if (!directory.exists(server.mappath(entity.fullpath)))
{
directory.createdirectory(server.mappath(entity.fullpath));
}
_filemanagerdirectoryrepository.insert(entity);
_filemanagerdirectoryrepository.savechanges();
}
return redirecttoaction("editor",new { dirid = dirid});
}
/// <summary>
/// 上传图片
/// </summary>
/// <param name="dirid"></param>
/// <returns></returns>
public jsonresult uploadimage(int dirid)
{
//路径地址
string fileurl = "";
var parentdirentity = _filemanagerdirectoryrepository.getbyid(dirid);
var parentdirpath = parentdirentity == null ? "/content/filemanager/" : parentdirentity.fullpath;
httpfilecollectionbase postfile = httpcontext.request.files;
if (postfile == null)
{
return json(new { code = 1, msg = "文件不能为空" });
}
var file = postfile[0];
string extname = path.getextension(file.filename);
using (system.drawing.image image = system.drawing.image.fromstream(file.inputstream))
{
string filename = guid.newguid().tostring() + extname;
string smallimgname = string.format("{0}{1}{2}", filename, smallimage, extname);
string route = server.mappath(parentdirpath);
fileurl = path.combine(parentdirpath, filename);
string savepath = path.combine(route, filename);
//缩略图路径
string smallimgpath = path.combine(route, smallimgname);
//生成缩略图
try
{
imageresizer.fit(image, 160, 160, imageresizemode.crop, imageresizescale.down).save(smallimgpath);
}
catch (exception)
{
return json(new { flag = false, msg = "生成缩略图出错!" });
}
file.saveas(savepath);
}
#region 添加数据到素材表
filemanagerfilesentity entity = new filemanagerfilesentity();
entity.fileext = extname;
entity.fullpath = fileurl;
entity.name = path.getfilenamewithoutextension(file.filename);
entity.directoryid = dirid;
entity.size = file.contentlength;
_filemanagerfilesrepository.insert(entity);
_filemanagerfilesrepository.savechanges();
#endregion
if (parentdirentity != null)
{
parentdirentity.childrencount++;
}
_filemanagerdirectoryrepository.savechanges();
return json(new { code = 0 });
}
public class deletefilesparams
{
public int id { get; set; }
public int type { get; set; }
}
/// <summary>
/// 删除选中文件夹及图片
/// </summary>
/// <returns></returns>
public jsonresult checkedfilesdelete(list<deletefilesparams> checkeds)
{
var directorylist = _filemanagerdirectoryrepository.table.tolist();
var filelist = _filemanagerfilesrepository.table.tolist();
foreach(var item in checkeds)
{
//删除图片
if (item.type == 1)
{
var fileentity = filelist.firstordefault(x => x.id == item.id);
string path = server.mappath(fileentity.fullpath);
if (system.io.file.exists(path))
{
system.io.file.delete(path);
}
var parentdir = directorylist.find(x => x.id == fileentity.directoryid);
if (parentdir != null)
{
parentdir.childrencount--;
}
_filemanagerfilesrepository.delete(fileentity);
}
else
{
var direntity = directorylist.firstordefault(x => x.id == item.id);
deletechilddirfiles(direntity.id, directorylist, filelist);
string path = server.mappath(direntity.fullpath);
if (directory.exists(path))
{
directory.delete(path, true);
}
var parentdir = directorylist.find(x => x.id == direntity.parentid);
if (parentdir != null)
{
parentdir.childrencount--;
}
_filemanagerdirectoryrepository.delete(direntity);
}
}
_filemanagerfilesrepository.savechanges();
_filemanagerdirectoryrepository.savechanges();
return json(new { code = 0 });
}
public void deletechilddirfiles(int pid,list<filemanagerdirectoryentity> dirlist, list<filemanagerfilesentity> files) {
var direntitylist = dirlist.where(x => x.parentid == pid);
var fileentitylist = files.where(x => x.directoryid == pid);
foreach (var item in direntitylist)
{
deletechilddirfiles(item.id, dirlist, files);
_filemanagerdirectoryrepository.delete(item);
}
foreach (var item in fileentitylist)
{
_filemanagerfilesrepository.delete(item);
}
_filemanagerdirectoryrepository.savechanges();
_filemanagerfilesrepository.savechanges();
}
}
文件管理页面 editor.chtml
@using web.areas.administrator.models
@model list<filemanagerfilemodel>
@{
layout = null;
}
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>文件管理</title>
<link href="/assets/iconfont/iconfont.css" rel="stylesheet" />
<link href="/scripts/layui/css/layui.css" rel="stylesheet" />
<style>
body { background: #f6f6f6; }
.toolbar { padding: 10px; background: #fff; }
.toolbar i.iconfont{margin-right:10px;}
.file-list{margin:20px;}
.file-list li { float: left; background:#fff; margin-bottom:20px; margin-right:20px; }
.file-list li .img-wapper { width:160px; }
.file-list li .img-wapper img{width:100%; height:160px;}
.file-list li .file-name { padding: 0 10px; width: 100%; overflow:hidden; line-height: 30px; height:30px; color: #666; font-size: 12px; background: #fafafa; }
.file-list li .file-name .layui-form-checkbox{width:140px !important; overflow:hidden !important; }
.file-list li:hover { box-shadow: 0 0 10px rgba(0,0,0,.1); }
.file-list li:hover .file-name { background: #f5f5f5;}
</style>
</head>
<body>
<div class="toolbar">
<a class="layui-btn layui-btn-small" href="javascript:;" data-toggle="modal" data-title="新建文件夹" data-url="@url.action("_adddirectory",new { dirid = request["dirid"] == null ? 0 : int.parse(request["dirid"])})">
<i class="iconfont icon-directory"></i>
新建文件夹
</a>
<button id="upload-img-btn" type="button" class="layui-btn"><i class="iconfont icon-photo"></i>上传图片</button>
<button id="delete-img-btn" type="button" class="layui-btn layui-btn-danger"><i class="iconfont icon-photo"></i>删除图片</button>
</div>
<div class="layui-form">
<ul class="file-list">
@if (!string.isnullorwhitespace(request["dirid"]))
{
<li class="file-item">
<div class="img-wapper">
<a href="javascript:history.back(-1);">
<img src="/assets/images/default/admin_directory_back.png" alt="返回上级" title="返回上级" />
</a>
</div>
<div class="file-name">
...
</div>
</li>
}
@if (model.any())
{
foreach (var item in model)
{
<li class="file-item">
@if (item.filetype == 1)
{
<div class="img-wapper">
<a href="javascript:;" class="file-img" data-url="@item.fullpath" data-title="@item.name">
<img src="@item.smallfullpath" title="@item.name" />
</a>
</div>
<div class="file-name">
<input type="checkbox" name="file-id" lay-skin="primary" title="@item.name" data-id="@item.id" data-type="1">
</div>
}
else
{
<div class="img-wapper">
<a href="@url.action("editor",new { dirid=item.id})">
@if (item.childrencount > 0)
{
<img src="/assets/images/default/admin_directory_files.png" title="@item.name" />
}
else
{
<img src="/assets/images/default/admin_directory.png" title="@item.name" />
}
</a>
</div>
<div class="file-name">
<input type="checkbox" name="file-id" lay-skin="primary" title="@item.name" data-id="@item.id" data-type="2">
</div>
}
</li>
}
}
</ul>
</div>
<input id="dirid" value="@request["dirid"]" hidden>
<script src="~/scripts/jquery-3.2.1.min.js"></script>
<script src="/scripts/layui/layui.js"></script>
<script>
//获取tinymce编辑器
var editor = top.tinymce.activeeditor.windowmanager.getparams().editor;
layui.use(['upload'], function () {
var upload = layui.upload;
var dirid = $("#dirid").val() == "" ? 0 : $("#dirid").val();
upload.render({ //允许上传的文件后缀
elem: '#upload-img-btn'
, url: 'uploadimage?dirid=' + dirid
, accept: 'file' //普通文件
, multiple: true
, size: 1024 * 2 //限制文件大小,单位 kb
, exts: 'jpg|jpeg|png|gif' //只允许上传压缩文件
, done: function (res) {
if (res.code == 0) {
window.location.reload();
}
}
});
//删除图片
$("#delete-img-btn").click(function () {
var checkeds = [];
$("input[name='file-id']:checkbox").each(function () {
if (true == $(this).is(':checked')) {
checkeds.push({
id: $(this).data('id'),
type: $(this).data('type')
});
}
});
if (checkeds.length == 0) {
layer.alert('请先选择需要删除的文件!');
}
else {
layer.confirm('删除后将无法恢复,请确认是否要删除所选文件?', {
btn: ['确定删除', '我在想想'] //按钮
}, function () {
$.ajax({
type: 'post',
url: 'checkedfilesdelete',
data: { checkeds : checkeds },
success: function (result) {
if (result.code == 0) {
window.location.reload();
}
else {
showmsg(result.msg);
}
}
})
}, function () {
});
}
})
})
//添加图片至编辑器
$(".file-img").click(function () {
var url = $(this).data("url"),
title = $(this).data("title");
//添加确认
layer.confirm('是否需要添加此图片?', {
btn: ['确认添加', '我在想想'] //按钮
}, function () {
editor.execcommand('mceinsertcontent', false, '<img alt="' + title + '" src="' + url + '"/>');
editor.windowmanager.close();
}, function () {});
})
</script>
<script>
//layui基本代码
$(function () {
layui.use(['element', 'form', "layer"], function () {
var element = layui.element;
//表单渲染
var form = layui.form;
form.on('submit(formdemo)', function (data) {
layer.msg(json.stringify(data.field));
return false;
});
form.render();
//异步加载modal
$(document).on("click", '[data-toggle="modal"]', function (e) {
var $this = $(this),
url = $(this).data('url'),
title = $(this).data("title")
if (url) {
$.ajax({
url: url,
data: { rnd: math.random() },
//datatype: 'html',
success: function (data) {
//示范一个公告层
layer.open({
type: 1
, title: title //不显示标题栏
, shade: 0.8
, shadeclose: true
, fixed: false
, area: ["900px"]
, offset: '40px'
, id: 'ajax-modal-wapper' //设定一个id,防止重复弹出
, move: false //禁止拖拽
, content: data
});
},
error: function (xmlhttprequest, textstatus, errorthrown) {
alert('加载出错。' + textstatus + '. ' + xmlhttprequest.status);
},
complete: function () {
}
});
}
});
});
})
</script>
</body>
</html>
新增文件夹页面 _adddirectory.chtml
@{
layout = null;
}
<div class="modal-content" style="padding-top:20px;">
<form class="layui-form" action="_adddirectorysave" method="post" enctype="multipart/form-data">
<input name="dirid" value="@request["dirid"]" hidden>
<div class="layui-form-item">
<label class="layui-form-label" for="dirname">文件夹名称</label>
<div class="layui-input-block">
<input class="layui-input" id="dirname" lay-verify="required" name="dirname" placeholder="请输入文件夹名称" type="text" value="">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="account-form" type="submit">保存信息</button>
</div>
</div>
</form>
</div>
3. 将选中图片插入编辑器
在图片列表的页面中,我们只需要在点击图片的事件中调用tinymce编辑器的插入方法即可,以下为插入图片的代码
<script>
//获取tinymce编辑器
var editor = top.tinymce.activeeditor.windowmanager.getparams().editor;
layui.use(['upload'], function () {
var upload = layui.upload;
var dirid = $("#dirid").val() == "" ? 0 : $("#dirid").val();
upload.render({ //允许上传的文件后缀
elem: '#upload-img-btn'
, url: 'uploadimage?dirid=' + dirid
, accept: 'file' //普通文件
, multiple: true
, size: 1024 * 2 //限制文件大小,单位 kb
, exts: 'jpg|jpeg|png|gif' //只允许上传压缩文件
, done: function (res) {
if (res.code == 0) {
window.location.reload();
}
}
});
//删除图片
$("#delete-img-btn").click(function () {
var checkeds = [];
$("input[name='file-id']:checkbox").each(function () {
if (true == $(this).is(':checked')) {
checkeds.push({
id: $(this).data('id'),
type: $(this).data('type')
});
}
});
if (checkeds.length == 0) {
layer.alert('请先选择需要删除的文件!');
}
else {
layer.confirm('删除后将无法恢复,请确认是否要删除所选文件?', {
btn: ['确定删除', '我在想想'] //按钮
}, function () {
$.ajax({
type: 'post',
url: 'checkedfilesdelete',
data: { checkeds : checkeds },
success: function (result) {
if (result.code == 0) {
window.location.reload();
}
else {
showmsg(result.msg);
}
}
})
}, function () {
});
}
})
})
//添加图片至编辑器
$(".file-img").click(function () {
var url = $(this).data("url"),
title = $(this).data("title");
//添加确认
layer.confirm('是否需要添加此图片?', {
btn: ['确认添加', '我在想想'] //按钮
}, function () {
editor.execcommand('mceinsertcontent', false, '<img alt="' + title + '" src="' + url + '"/>');
editor.windowmanager.close();
}, function () {});
})
</script>
ps: 还有很多的不足之处,希望能一起成长, 我的博客地址
上一篇: JS中undefined和null的区别,以及出现原因
下一篇: Jquery拼图
推荐阅读
-
CKeditor富文本编辑器使用技巧之添加自定义插件的方法
-
TinyMCE插件:Filemanager [4.x-6.x] 图片自动添加水印
-
TinyMCE插件:RESPONSIVE filemanager 9 图片自动添加水印
-
vue+tinymce 实现上传图片和自定义插件
-
TinyMCE插件:Filemanager [4.x-6.x] 图片自动添加水印
-
Tinymce 编辑器添加自定义图片管理插件
-
KindEditor 在线编辑器 自定义文件上传与图片管理器实现
-
WP相关文章插件修改成批量添加自定义图片地址_PHP
-
TinyMCE插件:RESPONSIVE filemanager 9 图片自动添加水印
-
WP相关文章插件修改成批量添加自定义图片地址_PHP