我看部落格后台使用的是TinyMCE作为rich text editor,这么做主要是为了兼容wordpress——把wp的数据迁移过来可费了牛鼻子劲了——多处代码都是在兼容wp的html过滤和输出,因此为了保持一贯性,现在也就继续使用TinyMCE(我用的版本是3.x,一下代码不适用于2.x)来写东西。
TinyMCE的扩展性还是很不错的,wordpress就把它改了个乱七八糟。我没那个本事也没那个功夫,但是上传图片还是得做的。放狗搜了一把,大都是在讲怎么集成别人做好的上传插件,于是我自己啃了半天wiki,这里把大概的流程记一下:
1. 首先工具栏上得有按钮,名字是叫image。还有一个advimage,看名字就知道功能更牛鼻,不过当然用起来也就更复杂了; 添加了按钮之后点击它弹出的窗口(以下称窗口甲)并没有什么地方可以浏览要上传的文件,因为这个按钮本身的意思只是插入一个<img>标签,所以必须再弹一个窗口来上传,然后把生成的URI填进来。在TinyMCE的初始化函数init里面添加一个叫file_browser_callback的键值对,指向我们的浏览回调函数(先写一个空壳);
tinyMCE.init({ //其他的参数 file_browser_callback: 'wfb'});
function wfb(field_name, url, type, win){}
2. 这样子窗口甲上就会出现一个browse按钮了,那我们需要点击它之后弹出来上传的页面,就是调一个函数,最关键的其实就是file那个键
//field_name: 窗口甲等待填入URI的文本框的id
//url: 对于上传来说就别管了
//type: 这个也不说了,对我们没用
//win: 这就是窗口甲的句柄,后面用来通信
function wfb(field_name, url, type, win){
tinyMCE.activeEditor.windowManager.open({
file : '/admin/uploadImg', //上传窗口的路径
title : '浏览图片',
width : 420,
height : 200,
resizable : "no",
inline : "yes",
close_previous : "no"
},{
window : win, //告诉它是被谁弹出来的
input : field_name //这个是指生成的图片地址要往哪里填
});
return false;
}
3. 这么一写,点击browse之后就会弹出我们的页面(以下称窗口乙)了,这也就是后台要做的事了。这里还有一个问题,上传完之后如何把生成的URI填回窗口甲?这里要用到popup这个东西,我也没空研究这是什么了,总之它能在TinyMCE弹出的窗口之间传递参数,我们需要让窗口乙告诉窗口甲URI。我的做法是后台使用同一个类(/admin/uploadImg)来处理,收到GET请求的时候就返回一个简单的上传页面,收到POST请求的时候就保存图片,然后输出类似这样的代码:
var FileBrowserDialogue = {
init : function () {
var win = tinyMCEPopup.getWindowArg("window");
//就这句关键,IMG_URI应该由服务端生成 win.document.getElementById
(tinyMCEPopup.getWindowArg("input")).value = 'IMG_URI';
tinyMCEPopup.close();
}
};
tinyMCEPopup.onInit.add(FileBrowserDialogue.init, FileBrowserDialogue);
4. 于是URI就能填回去了。 其实蛮简单的,就是几个概念有点绕。