許多網站後台的內容編輯區會採用「一條工具列和一大塊輸入框,要什麼就自己做。」的功能,通常會用 CKEditor 作為所見即所得線上內容編輯器(online WYSIWYG HTML editors)。好用的線上編輯器其實不只 CKEditor ,還有另一套 TinyMCE 也不錯,只要套件夠多、操作穩定、還有在維護、從 IE8 到 Edge 都支援、可以直接點兩下重複編輯現有內容,可與圖片上傳套件結合,滿足上述幾點,就是一個成熟的編輯器了。而且授權方式也很自由,簡直是佛心來的。

CKEditor

以提供「一條工具列和一大塊輸入框,要什麼就自己做。」的功能來說,CKEditor 是個方便好用的開放原始碼工具,但如何讓它更好用,就得依賴神調校了。只要在 config.js 裡面加入一些屬性,馬上就可擁有更理想的操作體驗。

0.抓對版本

從 CKEditor Builder 下載時,會看到分了三種版本: Basic, Standard, full,一般人避免夜長夢多,通常會直接下載 full,但偶爾還是會遇到明明應該有的功能按鈕,怎麼樣都叫不出來,因為 CKEditor Builder 預設值的 full 裡面的 plugins 不是最完整的,實際上還有 “full-all” 的版本。五種版本的功能比較表可見 CKEditor Presets,完整的 plugins 資料夾可到 ckeditor-releases 的 github 去下載。

1.把多餘的功能按鈕藏起來

出社會後有一個法則,叫做多做多錯,與其把所有功能開放給客戶使用,第一眼就讓人覺得很複雜、不想學、不會用,增加使用者失誤、手殘、耗費口舌解釋,但對方又聽不懂的機會,倒不如只開放一些必要的功能按鈕即可。CKEditor 預設的全功能按鈕有這麼多,如何把不要的藏起來呢?

第一種方法,可以使用官網的 CKEditor Builder,選擇要那些功能套件、哪種主題面板、哪些語言,選完之後就可以產生一個做好的檔案。先決條件是有耐心跟時間,去看那串 plugins 清單。

第二種方法是減法,使用 config.removeButtons,把不要的按鈕停用。
config.removeButtons = 'Subscript,Superscript';

第三種方法是加法,例如用 config.toolbar 設定,只把要用的顯示出來。
config.toolbar = [
['Bold','Italic','Underline','Strike','JustifyLeft','JustifyCenter','JustifyRight'],
['Image','Table','HorizontalRule','SpecialChar'],
['TextColor','BGColor','RemoveFormat','Font','FontSize','Source']
]

第四種方法,是下載 ckeditor 之後,裡面會有個 sample 資料夾,裡面有個 Toolbar Configurator 可以讓你勾選哪些要,哪些不要,並調整按鈕的順序。選完之後讓程式產生設定檔 config.js 即可,輕鬆寫意。

2.減低後台編輯樣式與前台實際網頁的差距

CKEditor 提供 Inline Editing 功能,最接近所見即所得的終極理想,但有時怕前台頁面特效太多,難以使用,或是網頁樣式與編輯器樣式衝突,還是會使用一個大編輯框在後台修改內容的操作模式。

inline editing 範例
inline editing 範例

但是這常常有個問題,就是前後台顯示得有落差。例如網頁是黑底白字,但是在編輯器中是白底黑字,很難編輯。或是使用者抱怨「後台排得看起來好好的,可是在前台又長得差很多」,這時候可以加入編輯器寬高設定,並載入前台的 CSS 樣式檔,讓編輯器中的換行、樣式與前台網頁接近一致。
例如我們在 config.js 加入以下程式碼
config.contentsCss = ['../../css/ckeditor.css'];
config.width=680;
config.height=150;

ps.程式碼不是死的,要依系統內對 ckeditor 的呼叫方式或套用區域不同,而做調整。

但是這樣只能讓前後台的編排顯示「接近」一致,因為 CKeditor 為了讓使用者辨識方便,會替表格加上一些虛線標示,這個虛線也會佔有空間,會讓編輯器中的換行與實際換行差距一兩個字。當然也可以硬改 CKeditor,取消表格的虛線標示。

3.預先排好樣式或區塊,讓操作者套用。(內容範本與預設樣式)

如果您要使用者按一個鍵,本來空白的編輯區突然跑出一大堆東西,那可以使用 Templates 功能。

Templates 功能範例

可載入預先建立好的編排版型,範本設定方式與呼叫方式請上網搜尋 CKEditor Templates。

如果您要使用者建立一個表格之後,再按一個鈕,表格變成會隔行換色,有花花綠綠的背景,那可以使用 Styles 功能。

Styles 功能範例

詳情請見 Styles – CKEditor Documentation

4.避免 CKEditor 自作主張轉換你的原始碼

是否遇過頁面在編輯時好好的,送出之後也好好的,但是再回去編輯時,html 或 css 卻被自動轉換了,div 變成 p ,數值單位跑掉之類的? 因為 CKEditor 內建過濾機制,例如送出時會把沒有閉合的標籤補上 end tag,在載入編輯資料時,也會把一些空的 html 標籤,或是一些特殊的語法轉換、過濾成它覺得正常的語法。詳情可見 CKEDITOR.filter

我們可以在 config.js 內簡單的透過這個設定,讓 CKEditor 不要管太多。
config.allowedContent=true;

這種是否自動轉換的選項還有很多,例如從剪貼簿貼上相關的(如貼上時轉成純文字),從 Word 貼上相關的,勘誤與自動校正相關的(例如少了結尾標籤,CKEditor 會自動補上),詳情請查閱公開說明書。

5.調整字型大小

Gooogle Chorme 瀏覽器有「最小字型大小」的限制,預設值為 12,這設定的意思是 font-size 1~11px 的字型,都會顯示成12px。在 CKEditor 中預設提供的字型大小設定中,很不巧前 5 個幾乎是無用的設定,建議另外再設定過。另外中文有一些地雷 font-size,也應該避免。

預設字型大小-調整前
預設字型大小-調整前

在 config.js 內加入,斜線前面是顯示用的名稱,後面是真的套用的值
config.fontSize_sizes = '12/12px;13/13px;16/16px;15/15px;18/18px;20/20px;22/22px;24/24px;36/36px;48/48px;';

2023/1 更新: Chrome 118 中移除了 12px 最小字體的限制

在 Chrome 118 之前的版本中,如果字型小於 10 像素,則系統無法依指定方式呈現,但如果語言是阿拉伯文、波斯文、日文、韓文、泰文、簡體中文或繁體中文,則系統會將其四捨五入。開發人員必須設法轉譯小型文字,例如使用 transform 屬性。
自 Chrome 118 版起,所有語言都會解除這項限制,使七種語言相符。這項變更改善了與其他瀏覽器的互通性。

相關資訊可參考
正式推出 CSS 的四項全新國際功能 – Chrome for Developers Blog
Issue 36429: The default setting of minimum font size may make layout of some pages broken

6.調整字型

預設字型-調整前
預設字型-調整前

CKEditor 基本上又是洋人的東西,字型選擇功能裡面淨是一些系統通用的英文字型,那我們可以讓它出現楷體、黑體之類的中文字體嗎?

可以在 config.js 內加入以下設定:
config.font_names = 'Arial;Arial Black;Comic Sans MS;Courier New;Tahoma;Times New Roman;Verdana;新細明體;細明體;標楷體;微軟正黑體';

7.還原次數

在編輯器中操作失誤,不用把頁面關掉再重來一次,CKEditor 跟一般文書軟體一樣,可以按 Ctrl+Z 還原上一步。
除了可以在按鈕設定中加入’Undo’,’Redo’,讓工具列上顯示還原與取消還原的按鈕,還可以設定還原的步驟數上限。
config.undoStackSize = 50;

8.想要直接插入 Youtube 影片? 試試下載第三方擴充套件

這年頭很多網頁都有插入多媒體內容的需求,例如 Google Map, Youtube 等等,除了切換到「原始碼模式」內貼上一大串嵌入碼,有沒有更優雅的用法,滑鼠點一點就可以插入,點兩下就可以再編輯之類的?
可以到擴充元件庫 中搜尋關鍵字,有時候可以意外發現一些好用的套件,但防人之心不可無喔。
將套件上傳後,可用以下來呼叫使用,並將新功能按鈕加在 config.toolbar[]裡面。
config.extraPlugins = '套件1名稱,套件2名稱';

9.從別的地方貼東西到 Ckeditor

從別的地方複製東西,貼進 CKEditor,常會夾雜一些不相干的樣式,我們可以在工具列上放置 ‘RemoveFormat’,叮囑使用者在遇到某些跑版、或是樣式異常情況時,去按一下[移除格式」的按鈕。

更激進的話可以設定 config.forcePasteAsPlainText = true; 不管貼什麼進來都會變純文字,不過限制太多會降低使用者的好感度,如非情勢確有必要,建議不要使用。

另外版本比較新的 CkEdior,為了怕有人複製貼上時複製到一些惡意的程式碼,所以預設會把貼上的東西通通打回原形。可以設定以下語法,讓貼上的東西保有雜七雜八的樣式與惡意程式碼。
config.pasteFilter = null;

另外如果使用者習慣從 Word 貼上內容,另外有一系列 Word 貼上的相關功能,可參考 Paste from Word

10.Bootstrap 的 Modal 與 CKEditor

在 Bootstrap 的 Modal 中放置 CKEditor,可能造成一些神秘的事情發生,例如點擊不到編輯框、點擊不到表格屬性或圖片屬性的對話視窗。有以上情形,請在網頁的 js 中加入以下內容:
$.fn.modal.Constructor.prototype.enforceFocus = function() {
modal_this = this
$(document).on('focusin.modal', function (e) {
if (modal_this.$element[0] !== e.target && !modal_this.$element.has(e.target).length
&& !$(e.target.parentNode).hasClass('cke_dialog_ui_input_select')
&& !$(e.target.parentNode).hasClass('cke_dialog_ui_input_text')) {
modal_this.$element.focus()
}
})
};

11.JQuery UI 的 Dialog 與 CKEditor

在 JQuery UI 的 Dialog 元件中放置 CKEditor,可能造成一些神秘的事情發生,例如點擊不到編輯框、點擊不到表格屬性、圖片屬性、超連結設定的對話視窗。有以上情形,請在網頁的 js 中加入以下內容:

orig_allowInteraction = $.ui.dialog.prototype._allowInteraction;
$.ui.dialog.prototype._allowInteraction = function(event){
if (event.target.ownerDocument != this.document[0]) return true;
if ($(event.target).closest(".cke_dialog").length) return true;
if ($(event.target).closest(".cke").length) return true;
return orig_allowInteraction.apply(this, arguments);
};

如果加了還是沒效怎麼辦? 上 Stack Overflow 找哇!

12.使用 CKEditor 的 cdn

近幾年來,瀏覽器與作業系統的快速迭代,常會發生使用者使用最新的 IE 或 Edge 瀏覽器,發生「無法貼上內容」「表格或圖像屬性視窗無法關閉」「編輯框怎麼點都不會出現輸入游標」等各種慘狀,明明之前都好好的呀? 想要一個軟體用一輩子是不行的,官方開發團隊的 changelog 一堆 Fixed 的條目,必須要常常更新。

CKEditor 有提供官方 cdn 路徑,讓你不用每次花許多時間更新伺服器上的檔案,只要在引用 js 的地方改一下版本號,就可使用最新版的CkEditor。
<script src="//cdn.ckeditor.com/4.5.1/full/ckeditor.js"></ script>

主程式用 cdn 上面的檔案,設定檔 config.js 則可設定為網站自己的伺服器路徑,這樣既可快速更新主程式,而且每個客戶網站的編輯器還可以額外做控制。
主程式跟 plugns 盡量一起更新,避免 CKEditor 主程式升級後,部份 plugins 無法使用。或是只把某 plugins 升到最新版,但不相容舊版 CKEditor 的情況。

如果怕天災時海底電纜斷掉,或是台灣哪邊的機房又出事,或是哪個地區的線路又在維修,想讓編輯器與網站共存亡,也可以架設自己的靜態檔案伺服器。總之就是避免每隔一段時間就得挨家挨戶去更新 CKEditor 的情況發生。

13.CKEditor 與 iconfont

有時候遇到編排內容時使用 iconfont,不管是用 Bootstrap 內建的 Glyphicons,還是Font Awesome,最簡單的用法是在 html 中放一個含有特殊 class 的空白內容,如< i class=”fa fa-folder-open-o”>,內容上就會顯示一個資料夾圖示。

但這種沒有內容的空標籤,在 CKEditor 是會被自動過濾清除掉的,而且編輯時也看不到那裏有什麼圖示,雖然單色的 iconfont 在台灣的設計場合常常不合國情,是封印的技能,但難道真的沒法改善嗎?

如果要讓 iconfont 正常的顯示出來,我們可以在 config.js 裡面加入三行內容,讓 ckeditor 可以顯示正確的圖示,並不要濾掉空白的 i 標籤跟 span 標籤。
config.contentsCss = ['bootstrap.min.css','font-awesome.min.css'];
CKEDITOR.dtd.$removeEmpty.i = 0;
CKEDITOR.dtd.$removeEmpty.span = 0;

我們還可以到 CKEditor 的官方套件庫找相關套件,這樣編輯工具列就會直接顯示按鈕,讓你可以直接滑鼠點選插入 iconfont。

革命尚未成功,同志仍須努力
以上介紹了這麼多調校方式,但實際上 CKEditor 對於一般使用者來說,還是一個會用的人就是會用,不會的人還是不會用的內容編輯器。在實際的編排狀況上還是會遇到不得不打程式碼的效果。您可能會看到工程師在一些 10 Best jQuery and HTML5 WYSIWYG Plugins 之類的文章按讚,但只要把他抓去網頁編排、客戶教育訓練的現場,就知道有一半以上都是不實用的。

例如來個應用題,今天要編排一個區塊,左邊寬 70%,右邊寬 30%,然後在手機上這兩塊要變成寬 100%,請問要如何達成?
如果網頁有套 Bootstrap,那可以把 CKEditor 裝上 Bootstrap Responsive Visibility,設定某一塊內容在哪一個螢幕解析度會顯示或隱藏(所以編輯時要一直拉動編輯器的框框? 同樣的內容要打好幾次?),或是使用 Bootstrap grid,把頁面寬度分成2半、3半、4半、6半、12半,只是沒辦法不改 code 達成左欄大右邊小。或是使用 Layout Manager,快速產生一些 grid,但是不行改欄寬,不行改 gap,而且 Bootstrap grid 預設是沒有 70/30 的 grid 的。要排什麼東西,又避免修跑版修到死,還是請使用者直接做一張圖放上去吧!


現在有許多挑剔的業主,都是拿滑鼠比拿毛筆順手,小時候抱著電視長大,學生時代寫部落格、結婚後用 iPad 帶小孩的人。一個新時代的網站,編輯內容時還需要敲 HTML 語法,這種產品是端不上檯面的,這年頭連免費的網站都有文章編輯後台,甚至像 Weebly 這種免費網站已經捨棄「給使用者一條工具列和一大塊輸入框,要什麼就自己做。」,而採用「去挑範本,要啥功能就拖曳進來」,對一些新手賣家來說,操作體驗完勝許多網頁公司的後台。

就是這些美好的東西把消費者的胃口養大,常有「免費的都有,為什麼你的沒有?」「不是 JAVA 套一套就好了嗎?(註1)」「你就排幾個範本,讓我可以直接拉進來套用就好了。」這年頭的網站設計或開發公司,除了把刁鑽的客戶直接請去用 Weebly 或是部落格,或是跟他分析在地化服務或資料轉移之類的利害之處。

註1: 這句話可以激怒工程師兩次,第一個是把 Java Script 簡稱為 Java,兩者的關係就像「熱狗」跟「狗」一樣相差甚遠。第二個是「套一套就好了」,只要聽到這句,相關從業人員心裡都會暗罵「這麼簡單,那你自己來套。」

相關文章
這年頭的內容編輯器已經解決了哪些問題? « 要改的地方太多了,那就改天吧 這年頭還把「給一個大編輯框自己排內容的編輯器」視為高科技,是會被人笑的。讓我們來看一下這年頭的線上內容編輯器還有那些好用又方便功能。
為什麼不再用免費 php 架站套件做網站 « 要改的地方太多了,那就改天吧 wordpress 很好用,weebly 很好用,但真的適合您嗎? 看本文分析。