CKeditor如何與自行撰寫的圖片管理頁面整合

之前公司內Portal大部份的的編輯器都是很久之前改寫Discz!NT(版本已不可考)編輯器為User Control,此類型的編輯器幾年前相當流行(現在也還很多網站使用),採用的是稱為BBCode的編碼,可以多少阻擋一些XSS攻擊。但因BBCode的語法相對受限制,例如"有底色的字"就沒有相對應的BBCode語法(也許有,但我真的找不到),因此此次升級編輯器就沒有打算繼續沿用BBCode了,因為不僅功能有限制外,目前我們改寫的版本在Render成html時,或多或少都會有一些例外的情況,尤其是使用者很喜歡從Word直接剪下-貼上,情況更為糟糕!

在一番Survey之後,就決定是CKeditor了(其實是亂槍打鳥啦,TinyMCE也很好用,但個人就是比較喜歡CKeditor)。

之前公司內Portal大部份的的編輯器都是很久之前改寫Discz!NT(版本已不可考)編輯器的User Control,此類型的編輯器幾年前相當流行(現在也還很多網站使用),採用的是稱為BBCode的編碼,可以多少阻擋一些XSS攻擊。但因BBCode的語法相對受限制,例如"有底色的字"就沒有相對應的BBCode語法(也許有,但我真的找不到),因此此次升級編輯器就沒有打算繼續沿用BBCode了,因為不僅功能有限制外,目前我們改寫的版本在Render成html時,或多或少都會有一些例外的情況,尤其是使用者很喜歡從Word直接剪下-貼上,情況更為糟糕!

在一番評比之後,就決定是CKeditor了(其實是亂槍打鳥啦,TinyMCE也很好,但個人比較喜歡CKeditor)。

CKeditor是一套功能強大,且使用方便的Web版WYSIWYG編輯器,也提供了相當良好的plugin及整合介面。之前改寫Discuz!NT的編輯器時,有整合了自訂的圖片上傳及選擇的功能進去,因此要升級,這個功能還是必備的呀,否則一定被人罵到臭頭!原本想說應該要跟之前改寫一樣,必須看一下原始碼,了解編輯器關於插入圖片的語法是怎麼運作的再開始做。沒想到官網上就有提供整合的說明,請參考此處

透過這API,我連之前的圖片上傳及選擇的功能頁面都只要做小部份的改寫就可以用了,哈哈哈,真是輕鬆愜意啊!
我用官網提供的範例做說明,此段script應在CKeditor已被建立Instance後再呼叫,我是放在Body onload內執行。

CKEDITOR.replace( 'editor1', {
    filebrowserBrowseUrl: '/browser/browse.php',
    filebrowserUploadUrl: '/uploader/upload.php'
});

參數1 editor2指的是CKeditor的名稱。
參數2 是一個Key-Value的Array,依我目前知道的共有以下8個:

  1. filebrowserBrowseUrl
  2. filebrowserUploadUrl
  3. filebrowserWindowWidth
  4. filebrowserWindowHeight
  5. filebrowserImageBrowseUrl
  6. filebrowserImageUploadUrl
  7. filebrowserImageWindowWidth
  8. filebrowserImageWindowHeight

其中的差異可自行設定看看便知!

只要執行此設定的Script,CKeditor就會自動在Toolbar的 插入超連結、插入影像及插入Flash等功能裡,自動加上 "瀏覽伺服器端"

及 "上傳"頁面

註:我只抓截取插入影像功能的畫面,在插入超連結及Flash時也會有作用。

像我只需要從Server插入圖片及上傳圖片(我的選擇圖片與上傳做在同一個頁面,所以我只設定filebrowserImageBrowserUrl),因此我的設定如下:

CKEDITOR.replace('<%=ckenewseditor.clientid>editor1', {
    filebrowserImageBrowseUrl: '../ckeditor/customizedpages/ImageBrowser.aspx',
    filebrowserImageWindowWidth: '640',
    filebrowserImageWindowHeight: '640'
});

實作瀏覽器的部份我就不多說了,就是標準的ASP.Net程式而已!重點在如何把頁面所選擇的圖片回傳給CKEditor,只要以下的語法即可:

window.opener.CKEDITOR.tools.callFunction( funcNum, fileUrl [, data] );

funcNum是CKeditor會傳給指定的圖片選擇頁面的參數,用來辨識是CKeditor的哪個功能,可以在Server端就先取出來備用,或是像我使用官網提供的getUrlParam函式來取得。
fileUrl就是要插入圖檔的Url,而data我沒用到,故沒查用途。

我的Javascript如下:

function insertImage() {
    var funcNum = getUrlParam('CKEditorFuncNum');
    var fileUrl = document.getElementById("PicURL").value;
    window.opener.CKEDITOR.tools.callFunction(funcNum, fileUrl);
    window.close();
}

// Helper function to get parameters from the query string.
function getUrlParam(paramName) {
    var reParam = new RegExp('(?:[\?&]|&)' + paramName + '=([^&]+)', 'i');
    var match = window.location.search.match(reParam);

    return (match && match.length > 1) ? match[1] : null;
}

在ASP.Net的圖片選擇頁面中,會將選擇的圖檔的Url指定給PicURL這個Hidden的input,最後再按下"插入圖片"的按鈕時,呼叫前端的 insertImage 即可,如此便完成了上傳圖片及插入圖片的客製功能!

最後再設定一下CKeditor的功能表,只留下需的的部份就大功告成囉!相關CKeditor的初始化設定,可以參考這篇