CKeditor插件开发流程(二)SyntaxHighlighter
CKEditor整合SyntaxHighlighter实现代码高亮显示
1,版本说明
CKEditor:ckeditor_4.0.1_standard.zip
SyntaxHighlighter:syntaxhighlighter_3.0.83.zip
2,解压syntaxhighlighter_3.0.83.zip,将得到的目录syntaxhighlighter_3.0.83复制到站点目录下,我的是放在/plugins目录下(可以是其它目录,或者根目录),结果得到目录结构/plugins/syntaxhighlighter_3.0.83。
3,在CKEditor中配置插件(安装方法在《CKEditor安装》有介绍,这里就不介绍了)。在ckeditor/plugins目录下创建一个目录syntaxhighlighter,此目录名即为插件名,这点要注意。在syntaxhighlighter目录下创建icons、
dialogs两个目录和
plugin.js一个文件。icons目录用于存放
CKEditor插件
在编辑器工具栏上相应按钮的图标,dialogs用于存放该插件对话框相关类,plugin.js是严格要求这样命名的。因此在中新增的目录结构如下:
ckeditor/
plugins/
syntaxhighlighter/
icons/
syntaxhighlighter
.png
dialogs/
syntaxhighlighter
.js
plugin.js
4,编辑plugin.js文件,内容如下:
// mo_yq5 在编辑器中定义一个插件,注意,插件名称与插件目录名要保持一致 CKEDITOR.plugins.add( 'syntaxhighlighter', { // mo_yq5 初始化插件 init: function( editor ) { //mo_yq5 引入对话框的定义,所引入的文件的内容是对话框的具体逻辑定义 CKEDITOR.dialog.add( 'shDialog', this.path + 'dialogs/syntaxhighlighter.js' ); //mo_yq5 在编辑器中追加一条指令 editor.addCommand( 'shDialog', new CKEDITOR.dialogCommand( 'shDialog' ) ); //mo_yq5 在编辑器中追加一个工具栏按钮 editor.ui.addButton( 'shButton', { //mo_yq5 鼠标移到按钮上时的提示文本 label: '插入代码', //mo_yq5 点击按钮时要执行的指令,即上面添加的指令 command: 'shDialog', //mo_yq5 在编辑器工具栏中嵌入按钮的方式 toolbar: 'insert', //mo_yq5 工具栏上按钮的图标 icon: this.path + 'icons/syntaxhighlighter.png' }); } });
5,编辑
代码如下:syntaxhighlighter
.js文件,定义对话框的实现逻辑,
//mo_yq5 定义一个对话框。 CKEDITOR.dialog.add( 'shDialog', function ( editor ) { return { //mo_yq5 对话框标题。 title: '插入代码', //mo_yq5 对话框最小宽度。 minWidth: 400, //mo_yq5 对话框最小高度。 minHeight: 200, //mo_yq5 对话框内容,一个元素对应一个选项卡。 contents: [ { //mo_yq5 选项卡标识id。 id: 'tab_hightlighterCode', //mo_yq5 选项卡标题。 label: '代码内容', //mo_yq5 选项卡内容,一个元素对应一个表单项。 elements: [ { //mo_yq5 表单类型。 type: 'select', //mo_yq5 表单名。 label: '语言:', //mo_yq5 表单标识id。 id: 'lang', //mo_yq5 是否为必填项。 required: true, //mo_yq5 表单默认值。 'default': 'java', items: [['ActionScript3', 'as3'], ['Bash/shell', 'bash'], ['ColdFusion', 'cf'], ['C#', 'csharp'], ['C++', 'cpp'], ['CSS', 'css'], ['Delphi', 'delphi'], ['Diff', 'diff'], ['Groovy', 'groovy'], ['JavaScript', 'js'], ['Java', 'java'], ['JavaFX', 'jfx'], ['Perl', 'perl'], ['PHP', 'php'], ['Plain Text', 'plain'], ['PowerShell', 'ps'], ['Python', 'py'], ['Ruby', 'rails'], ['Scala', 'scala'], ['SQL', 'sql'], ['Visual Basic', 'vb'], ['XML', 'xml']] }, { type: 'textarea', style: 'width:418px;height:250px', label: '代码:', required: true, id: 'code', rows: 13, 'default': '' } ] } ], //mo_yq5 定义提交事件。 onOk: function(){ //mo_yq5 从下拉列表获取到的语言类型。 var lang = this.getValueOf('tab_hightlighterCode', 'lang'); //mo_yq5 将要被渲染成高亮显示的内容(代码)。 var code = this.getValueOf('tab_hightlighterCode', 'code'); //mo_yq5 在当前页面上创建的一个用于存放代码的容器,因为渲染器SyntaxHighlighter是取页面内容来渲染的。该容器不显示。 if($("#brushContainer").length==0){ $("body").append('<div id="brushContainer" style="display:none;"></div>'); } //mo_yq5 主要目的是将‘<’这样的标签转换成实体。 code = CKEDITOR.tools.htmlEncode(code); //mo_yq5 将要渲染的代码放入容器。 $("#brushContainer").html('<pre class="brush:'+ lang +';">'+code+'</pre>'); //mo_yq5 将渲染各种语言的类准备好 。 SyntaxHighlighter.autoloader.apply(null,shBrushArray); //mo_yq5 开始渲染。 SyntaxHighlighter.all(); //mo_yqr@163.com 等待2秒(因为渲染是异步的,可能需要点时间),将渲染后的内容插入编辑器。 setTimeout(function(){ //mo_yq5 将类似‘<’等的实体标识为文本内容,不然下次用编辑器打开时会被认为是html标签,造成编辑器上看不到该字符。 code = $("#brushContainer").html().replace(/(&){1}(lt;){1}/g,"<code>&"+"lt;</code>"); code = code.replace(/(&){1}(amp;){1}/g,"<code>&"+"amp;</code>"); //mo_yq5 将渲染后的内容插入编辑器,加‘<p/>’是为了让光标移出被渲染后的代码块。 editor.insertHtml(code+"<p/>"); },2000); } }; });
代码说明:此代码虽然是在CKEditor插件syntaxhighlighter
中定义,但使用到了一些全局对象,比如59行的‘
SyntaxHighlighter
’
是
SyntaxHighlighter组件中定义的对象,‘shBrushArray’是
我在页面上定义的全局数组对象,以及代码中使用了JQuery类库,这些对象的引入将在后面进行说明。重点说明65、66行之目的所在:1,将内容的标签实体用code标签包装(ckeditor内部机制决定),是为了防止编辑器显示内容时,将内容中的标签实体转换为html标签,造成内容在编辑器显示结果与保存结果跟预想的不一致;2,将标签实体(如“&”与“lt;”的连接串)拆分成如代码所示的形式,是为了保证即使在编辑器中编辑上面的代码时显示结果也是正确的;这两点也是我纠结了两三天才写出来,其它问题有待发现。
6,至此,syntaxhighlighter
插件在CKEditor上的配置已经完成,效果如下图:
7,完成以上步骤,已经可以将代码插入到编辑器中,但代码还不能在编辑器上高亮显示。要达到这个目的,我们需要考虑被渲染后的代码引用的样式起效情况。被渲染后,代码内容已经定义上SyntaxHighlighter组件中定义的样式,因此我们需要将SyntaxHighlighter组件定义的样式文件引入到编辑器所在页面中来。经过深入,我们了解到,编辑器的编辑框是定义在编辑器所在页面的一个iframe标签下的(即在不同的document对象中),所以直接在编辑器所在页面引入SyntaxHighlighter组件定义的样式文件,是不起作用,因为样式影响不到iframe下的内容。我们需要想法办能够在编辑框所在iframe(即document对象)中引入SyntaxHighlighter组件定义的样式文件。通过用火狐浏览器访问编辑器所在的页面,鼠标右键查看页面元素可以发现,编辑框所在iframe中引入了ckeditor/contents.css这个样式文件。经过测试,引入SyntaxHighlighter组件定义的样式比较简便的方法就是在ckeditor/contents.css中追加SyntaxHighlighter组件定义的样式。具体方法就是加入以下两行(根据自己SyntaxHighlighter的实际路径进行变动):
@IMPORT url("../plugin/syntaxhighlighter_3.0.83/styles/shCoreEclipse.css");
@IMPORT url("../plugin/syntaxhighlighter_3.0.83/styles/shThemeEclipse.css");
8,要体验最终效果,需要在编辑器所在页面引入一些必要的类库,如下(包括之前CKEditor安装所引入的):
- 在需要显示编辑器的位置贴入
-
<textarea name="article.body">${article.body }</textarea>
- 在页面底部引入类库
-
<script src="${pageContext.request.contextPath}/include/js/jquery-1.4.1.min.js"></script> <script src="${pageContext.request.contextPath}/plugin/syntaxhighlighter_3.0.83/scripts/shCore.js"></script> <script src="${pageContext.request.contextPath}/plugin/syntaxhighlighter_3.0.83/scripts/shAutoloader.js"></script> <script src="${pageContext.request.contextPath}/ckeditor/ckeditor.js"></script> <script> var g_contextPath="${pageContext.request.contextPath}"; //mo_yq5 syntaxhighlighter插件的定义中需要到此对象,具体请看dialogs/syntaxhighlighter.js。 var shBrushArray = (function(){ var args = arguments,result = []; for(var i = 0; i < args.length; i++) result.push(args[i].replace('@', g_contextPath+'/plugin/syntaxhighlighter_3.0.83/scripts/')); return result; })( 'applescript @shBrushAppleScript.js', 'actionscript3 as3 @shBrushAS3.js', 'bash shell @shBrushBash.js', 'coldfusion cf @shBrushColdFusion.js', 'cpp c @shBrushCpp.js', 'c# c-sharp csharp @shBrushCSharp.js', 'css @shBrushCss.js', 'delphi pascal @shBrushDelphi.js', 'diff patch pas @shBrushDiff.js', 'erl erlang @shBrushErlang.js', 'groovy @shBrushGroovy.js', 'java @shBrushJava.js', 'jfx javafx @shBrushJavaFX.js', 'js jscript javascript @shBrushJScript.js', 'perl pl @shBrushPerl.js', 'php @shBrushPhp.js', 'text plain @shBrushPlain.js', 'py python @shBrushPython.js', 'ruby rails ror rb @shBrushRuby.js', 'sass scss @shBrushSass.js', 'scala @shBrushScala.js', 'sql @shBrushSql.js', 'vb vbnet @shBrushVb.js', 'xml xhtml xslt html @shBrushXml.js'); //mo_yq5 指定编辑的显示高度 CKEDITOR.config.height=450; //mo_yq5 启用代码高亮显示插件 CKEDITOR.config.extraPlugins="syntaxhighlighter"; //mo_yq5 初始化页面上的编辑器 var editor = CKEDITOR.replace( 'article.body'); </script>
代码说明:“article.body”是表单名。第4到27行是针对各种语言渲染类;按照官方文档上意思,定义第30到61行即可(
)。但实际测试结果是,如果只定义30到61行的代码,在编辑器中插入代码时只是第一次插入有效,第二次插入时如果选择的语言类型与上次插入的不同,将会报“Can't find brush for XXX”的错误,所以在我看来4到27行也是需要的(至少目前当作是SyntaxHighlighter的bug来处理),根据需要提供的语言类型进行增减即可。syntaxhighlighter
.js文件中有调用9,编辑器配置完成,代码在编辑器中高亮显示的效果,如图:
10,以上是针对编辑器的配置,当编辑后的文章需要在页面中显示时,我们需要在显示文章的页面引入样式文件即可(不需要SyntaxHighlighter的类库),如(也可点击鼠标右键来查看本页面的源代码):
<link rel=stylesheet type=text/css href="${pageContext.request.contextPath}/plugin/syntaxhighlighter_3.0.83/styles/shCoreEclipse.css" /> <link rel=stylesheet type=text/css href="${pageContext.request.contextPath}/plugin/syntaxhighlighter_3.0.83/styles/shThemeEclipse.css" />
以上内容来自:http://www.moyq5.me/article/1/detail/32
补充:
1、在"ckeditor\"目录下找到“config.js”文件,这是CKEditor的配置文件,添加如下代码
2.如果出现中文乱码问题,是页面编码不对,我是ASP.NET,折腾了一番,最终解决,修改Web.config文件
-----旧的 <configuration> <system.web> <compilation debug="true" targetFramework="4.0"/> <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/> <customErrors mode="Off" /> <globalization fileEncoding="GB2312" requestEncoding="GB2312" responseEncoding="GB2312"/> </system.web> </configuration>
--乱码问题新的解决办法,,原来是新增的那两个JS文件编码不对,重新打开编码另存为UTF-8格式即可
3.如果CkEditor 添加源码后没有 高亮颜色等,需要 添加配置
config.allowedContent = true;