代码改变世界

ckeditor+ckfinder+syntaxhighlight实现上传和插入代码高亮(for .NET)

2011-07-25 00:02  观海看云  阅读(799)  评论(0编辑  收藏  举报

最近在做一个BLOG程序,找了好几款编辑器,起初想用FckEditor发现速度稍微有点慢,并且作为一个搞程序的,那肯定要插入代码了,代码高亮那是必须的,美观大方可是也有缺点客户浏览时页面代码过多,影响速度。以前没注意原来Fckeditor已经升级为ckeditor并且不再使用引用dll方式,我个人喜欢用新的,就研究了下最新版的ckeditor如何实现我们想要的功能!在调试期间也遇到了一点问题,现在还有一点BUG没有解决,待会我贴出来,废话说了这么多。呵呵~

  转载请注明出处:http://www.cnblogs.com/root7

  注:本文参考网上同行部分程序,在此致谢!

  进入正题:ckeditor_3.4.1+ckfinder_aspnet_2.0.1 有需要的点击下载(目前是最新版),注意下载ckfinder的时候一定要选择.net版本

由于新版的ckeditor不支持上传管理文件功能,我们要配合ckfinder来实现上传功能。

         

  我在VS2005+xp 环境下进行测试。VS2008 10版本是否能正常调用,我不太清楚,有待大家测试!

第一步:搭建基本结构

  先解压修改下程序,不是必需的文件都可以删除,因为有些文件我们根本用不到,不删除的话还有可能给黑客留下漏洞导致网站被入侵^_^。

ckeditor删除多余文件后结构如下图所示 在lang文件夹下删除那些不需要语言文件,后缀名为.js我们只留下 cn.js zh-cn.js 和en.js三个即可

      

ckfinder删除不必要文件后结构如下:(这里面也有一个lang的文件夹打开和ckeditor进行一样的操作删除那些不必要的语言文件)

    

   接着我们打开VS新建网站

 同时将瘦身后的ckeditor 和ckfinder 添加进来,大致结构如下图所示(在实际网站应用中,你可以修改默认文件夹名称防止被别人猜解目录搞破坏):

    

  bin 文件夹下的CKfinder.dll 在CKfinder/bin/debug 文件夹下有,直接添加引用即可自动生成bin文件夹。

至此我们做完前期的工作,现在肯定是不行的我们要修改一些配置文件。

 第二部:修改配置

  先修改ckeditor,在ckeditor文件夹下找到config.js

添加如下代码

01 config.skin = 'kama';
02 config.language = 'zh-cn';
03  
04 config.toolbar_Full = [
05 ['Source','-','Save','NewPage','Preview','-','Templates'],
06 ['Cut','Copy','Paste','PasteText','PasteFromWord','-','Print''SpellChecker''Scayt'],
07 ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'],
08 ['Form''Checkbox''Radio''TextField''Textarea''Select''Button''ImageButton''HiddenField'],
09 '/',
10 ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'],
11 ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote'],
12 ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'],
13 ['Link','Unlink','Anchor'],
14 ['Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak'],
15 '/',
16 ['Styles','Format','Font','FontSize'],
17 ['TextColor','BGColor']
18 ];

  (注意:尽量不要加入汉字注释,可能导致发布网站是无法调用CSS样式表和JS代码

说明:config.skin 后面是皮肤,默认ckeditor提供三个皮肤;
   config.language 后面是默认语言 我们设置为 zh-cn;
   config.toolbar_full 后面是工具按钮的栏;

    到这里我们就可以在aspx页面中调用默认的ckeditor编辑器了;

  新建一个aspx文件 在HTML代码的head 部分加入<script type="text/javascript" src="ckeditor/ckeditor.js"></script>(这个必需)

在div部分加入  <asp:TextBox ID="txtContent" class="ckeditor" TextMode="MultiLine" runat="server"></asp:TextBox> 运行即可看到ckeditor编辑器了

获取编辑器的值插入数据库 则TextBox.Text即可,绑定的话直就从数据库读取<asp:TextBox ID="txtContent" class="ckeditor" TextMode="MultiLine" Text='<%# Bind("info") %>' runat="server"></asp:TextBox> 

提示:在插入类似'时候ASPX页面提示客户端(*)中检测到有潜在危险的 Request.Form 值。在页面HTML代码第一行加入validateRequest="false"或者修改web.config文件即可,但这不是最安全的做法,可能存在提交非法数据和跨站的危险,这里不做深入探讨。

我们看下效果

    

当我们打开插入图片按钮时候我们会发现跟以前的fckeditor不一样,缺少了上传图片按钮。如下:

    

  那么接下来我们修改下cdeditor下面的config.js 在函数内加入如下代码:

1 config.filebrowserBrowseUrl = 'ckfinder/ckfinder.html';
2 config.filebrowserImageBrowseUrl = 'ckfinder/ckfinder.html?Type=Image';
3 config.filebrowserFlashBrowseUrl = 'ckfinder/ckfinder.html?Type=Flash';
4 config.filebrowserUploadUrl = 'ckfinder/core/connector/aspx/connector.aspx?command=QuickUpload&type=Files';
5 config.filebrowserImageUploadUrl = 'ckfinder/core/connector/aspx/connector.aspx?command=QuickUpload&type=Image';
6 config.filebrowserFlashUploadUrl = 'ckfinder/core/connector/aspx/connector.aspx?command=QuickUpload&type=Flash';

  说明:config.filebrowser* 为上传文件时调用的ckfinder connector.aspx文件相应路径,这个根据您的网站文件结构修改,仅为测试我没有修改文件夹名称。

添加代码后在运行一下看看这个时候你发现有了上传的按钮

    

点击浏览服务器按钮提示如下:

    

  那我们来修改下找到ckfinder下面的config.ascx文件编辑 找到public override bool CheckAuthentication() 方法将return false;修改为 return true;

(这里需要说明一下,这样修改不安全,可以导致任何人上传文件,那么你可以先判断session 或者通过其他的手段达到一般用户不能非法上传,具体不再赘述)

本文只讲调用 所以就没有写的那么严格,修改后代码如下:

01 public override bool CheckAuthentication()
02 {
03     // WARNING : DO NOT simply return "true". By doing so, you are allowing
04     // "anyone" to upload and list the files in your server. You must implement
05     // some kind of session validation here. Even something very simple as...
06     //
07     //      return ( Session[ "IsAuthorized" ] != null && (bool)Session[ "IsAuthorized" ] == true );
08     //
09     // ... where Session[ "IsAuthorized" ] is set to "true" as soon as the
10     // user logs on your system.
11  
12     return true;
13 }

   还是在这个文件内找到 public override void SetConfig() 方法里面的    BaseUrl = "~/UploadFiles/"; 后面的目录根据自己的项目结构写,我单独建立了个UploadFiles文件夹存放上传文件。

    

这样基本的上传算是搞定了!

接下来要实现代码高亮功能了

我们用SyntaxHighlighter来实现,其他的暂时还没研究,有兴趣的朋友可以研究下!

在ckeditor/plugins/下添加syntaxhighlight文件夹(名称可以按照自己爱好来写)我这里就用默认的名称。

在syntaxhighlight文件夹下分别添加 dialogs、images、lang文件夹和一个JS文件 plugin.js

plugin.js文件内容如下

1 CKEDITOR.plugins.add("syntaxhighlight",{requires:["dialog"],lang:["cn"],init:function(a){var b="syntaxhighlight";
1 var c=a.addCommand(b,new CKEDITOR.dialogCommand(b));
1 c.modes={wysiwyg:1,source:1};
1 c.canUndo=false;a.ui.addButton("Code",{label:a.lang.syntaxhighlight.title,command:b,icon:this.path+"images/syntaxhighlight.gif"});
1 CKEDITOR.dialog.add(b,this.path+"dialogs/syntaxhighlight.js")}});

dialogs文件夹下添加syntaxhighlight.js文件 内容如下

001 /*********************************************************************************************************/
002 /**
003  * Syntax Highlighter plugin for CKEditor 3.x (Author: Lajox ; Email: lajox@19www.com)
004  * Insert/Edit Syntax Highlighter code snippet
005  */
006 /*********************************************************************************************************/
007  
008 CKEDITOR.dialog.add("syntaxhighlight",function(c){
009     var a=function(f){
010         f=f.replace(/<br>/g,"\n");
011         f=f.replace(/&/g,"&");
012         f=f.replace(/</g,"<");
013         f=f.replace(/>/g,">");
014         f=f.replace(/"/g,'"');
015         return f
016     };
017     var e=function(f){
018         var f=new Object();
019         f.hideGutter=false;
020         f.hideControls=false;
021         f.collapse=false;
022         f.showColumns=false;
023         f.noWrap=false;
024         f.firstLineChecked=false;
025         f.firstLine=0;
026         f.highlightChecked=false;
027         f.highlight=null;
028         f.lang=null;f.code="";
029         return f
030     };
031     var b=function(i){
032         var h=e();
033         if(i){
034             if(i.indexOf("brush")>-1){
035                 var g=/brush:[ ]{0,1}(\w*)/.exec(i);
036                 if(g!=null&&g.length>0){h.lang=g[1].replace(/^\s+|\s+$/g,"")}}
037                 if(i.indexOf("gutter")>-1){h.hideGutter=true}
038                 if(i.indexOf("toolbar")>-1){h.hideControls=true}
039                 if(i.indexOf("collapse")>-1){h.collapse=true}
040                 if(i.indexOf("first-line")>-1){var g=/first-line:[ ]{0,1}([0-9]{1,4})/.exec(i);
041                 if(g!=null&&g.length>0&&g[1]>1){h.firstLineChecked=true;h.firstLine=g[1]}}
042                 if(i.indexOf("highlight")>-1){
043                     if(i.match(/highlight:[ ]{0,1}\[[0-9]+(,[0-9]+)*\]/)){
044                         var f=/highlight:[ ]{0,1}\[(.*)\]/.exec(i);
045                         if(f!=null&&f.length>0){h.highlightChecked=true;h.highlight=f[1]}
046                     }}
047                     if(i.indexOf("ruler")>-1){h.showColumns=true}
048                     if(i.indexOf("wrap-lines")>-1){h.noWrap=true}
049         }
050         return h
051     };
052     var d=function(g){
053         var f="brush:"+g.lang+";";
054         if(g.hideGutter){f+="gutter:false;"}
055         if(g.hideControls){f+="toolbar:false;"}
056         if(g.collapse){f+="collapse:true;"}
057         if(g.showColumns){f+="ruler:true;"}
058         if(g.noWrap){f+="wrap-lines:false;"}
059         if(g.firstLineChecked&&g.firstLine>1){f+="first-line:"+g.firstLine+";"}
060         if(g.highlightChecked&&g.highlight!=""){f+="highlight: ["+g.highlight.replace(/\s/gi,"")+"];"}
061         return f
062     };
063     return{
064         title:c.lang.syntaxhighlight.title,
065         minWidth:500,
066         minHeight:400,
067         onShow:function(){
068         var i=this.getParentEditor();
069         var h=i.getSelection();
070         var g=h.getStartElement();
071         var k=g&&g.getAscendant("pre",true);
072         var j="";
073         var f=null;
074         if(k){
075             code=a(k.getHtml());
076             f=b(k.getAttribute("class"));
077             f.code=code
078         }else{f=e()}
079         this.setupContent(f)
080         },
081         onOk:function(){
082             var h=this.getParentEditor();
083             var g=h.getSelection();
084             var f=g.getStartElement();
085             var k=f&&f.getAscendant("pre",true);
086             var i=e();
087             this.commitContent(i);
088             var j=d(i);
089             var l=CKEDITOR.dom.element.createFromHtml('<pre class="'+j+'">'+a(i.code)+"</pre>", h.document);
090             if(k){
091                 l.insertBefore(k);
092                 k.remove();
093             }else{
094                 h.insertElement(l);
095             }
096         },
097         contents:[
098             {   id:"source",
099                 label:c.lang.syntaxhighlight.sourceTab,
100                 accessKey:"S",
101                 elements:[
102                 {   type:"vbox",
103                     children:[
104                     { id:"cmbLang",
105                       type:"select",
106                       labelLayout:"horizontal",
107                       label:c.lang.syntaxhighlight.langLbl,
108                       "default":"java",
109                       widths:["25%","75%"],
110                       items:[["Bash (Shell)","bash"],["C#","csharp"],["C++","cpp"],["CSS","css"],["Delphi","delphi"],["Diff","diff"],["Groovy","groovy"],["Javascript","jscript"],["Java","java"],["Java FX","javafx"],["Perl","perl"],["PHP","php"],["Plain (Text)","plain"],["Python","python"],["Ruby","ruby"],["Scala","scala"],["SQL","sql"],["VB","vb"],["XML/XHTML","xml"]],
111                       setup:function(f){if(f.lang){this.setValue(f.lang)}},
112                       commit:function(f){f.lang=this.getValue()}}]
113                 },
114                 {   type:"textarea",
115                     id:"hl_code",
116                     rows:22,
117                     style:"width: 100%",
118                     setup:function(f){if(f.code){this.setValue(f.code)}},
119                     commit:function(f){f.code=this.getValue()}}
120                 ]
121             },
122             {   id:"advanced",
123                 label:c.lang.syntaxhighlight.advancedTab,
124                 accessKey:"A",
125                 elements:[
126                 {   type:"vbox",
127                     children:[
128                     { type:"html",
129                       html:"<strong>"+c.lang.syntaxhighlight.hideGutter+"</strong>"
130                     },
131                     { type:"checkbox",
132                       id:"hide_gutter",
133                       label:c.lang.syntaxhighlight.hideGutterLbl,
134                       setup:function(f){this.setValue(f.hideGutter)},
135                       commit:function(f){f.hideGutter=this.getValue()}
136                     },
137                     { type:"html",
138                       html:"<strong>"+c.lang.syntaxhighlight.hideControls+"</strong>"
139                     },
140                     { type:"checkbox",
141                       id:"hide_controls",
142                       label:c.lang.syntaxhighlight.hideControlsLbl,
143                       setup:function(f){this.setValue(f.hideControls)},
144                       commit:function(f){f.hideControls=this.getValue()}
145                     },
146                     { type:"html",
147                       html:"<strong>"+c.lang.syntaxhighlight.collapse+"</strong>"
148                     },
149                     { type:"checkbox",
150                       id:"collapse",
151                       label:c.lang.syntaxhighlight.collapseLbl,
152                       setup:function(f){this.setValue(f.collapse)},
153                       commit:function(f){f.collapse=this.getValue()}
154                     },
155                     { type:"html",
156                       html:"<strong>"+c.lang.syntaxhighlight.showColumns+"</strong>"
157                     },
158                     { type:"checkbox",
159                       id:"show_columns",
160                       label:c.lang.syntaxhighlight.showColumnsLbl,
161                       setup:function(f){this.setValue(f.showColumns)},
162                       commit:function(f){f.showColumns=this.getValue()}
163                     },
164                     { type:"html",
165                       html:"<strong>"+c.lang.syntaxhighlight.lineWrap+"</strong>"
166                     },
167                     { type:"checkbox",
168                       id:"line_wrap",
169                       label:c.lang.syntaxhighlight.lineWrapLbl,
170                       setup:function(f){this.setValue(f.noWrap)},
171                       commit:function(f){f.noWrap=this.getValue()}
172                     },
173                     { type:"html",
174                       html:"<strong>"+c.lang.syntaxhighlight.lineCount+"</strong>"
175                     },
176                     { type:"hbox",
177                       widths:["5%","95%"],
178                       children:[
179                        {type:"checkbox",id:"lc_toggle",label:"",setup:function(f){this.setValue(f.firstLineChecked)},commit:function(f){f.firstLineChecked=this.getValue()}
180                        },
181                        {type:"text",id:"default_lc",style:"width: 15%;",label:"",setup:function(f){if(f.firstLine>1){this.setValue(f.firstLine)}},commit:function(f){if(this.getValue()&&this.getValue()!=""){f.firstLine=this.getValue()}}
182                        }
183                       ]
184                     },
185                     { type:"html",
186                       html:"<strong>"+c.lang.syntaxhighlight.highlight+"</strong>"
187                     },
188                     { type:"hbox",
189                       widths:["5%","95%"],
190                       children:[
191                        {type:"checkbox",id:"hl_toggle",label:"",setup:function(f){this.setValue(f.highlightChecked)},commit:function(f){f.highlightChecked=this.getValue()}
192                        },
193                        {type:"text",id:"default_hl",style:"width: 40%;",label:"",setup:function(f){if(f.highlight!=null){this.setValue(f.highlight)}},commit:function(f){if(this.getValue()&&this.getValue()!=""){f.highlight=this.getValue()}}
194                        }
195                       ]
196                     },
197                     { type:"hbox",
198                       widths:["5%","95%"],
199                       children:[
200                       {type:"html",html:""
201                       },
202                       {type:"html",html:"<i>"+c.lang.syntaxhighlight.highlightLbl+"</i>"
203                       }
204                       ]
205                     }
206                     ]
207                 }]
208             }
209         ]
210         }
211 });

  images文件夹添加syntaxhighlight.gif图标,自己在网上找一个自己喜欢的即可。

  lang 文件夹下添加 一个en.js 和cn.js文件

   cn.js代码如下

01 CKEDITOR.plugins.setLang('syntaxhighlight''cn',
02 {
03     syntaxhighlight:
04     {
05         title: '添加或更新代码',
06         sourceTab: '代码',
07         langLbl: '选择语言',
08         advancedTab: '高级',
09         hideGutter: '隐藏分割线',
10         hideGutterLbl: '隐藏分割线和行号',
11         hideControls: '隐藏工具栏',
12         hideControlsLbl: '隐藏浮动工具栏',
13         collapse: '代码折叠',
14         collapseLbl: '默认折叠代码块 (需要启用工具栏)',
15         lineWrap: '自动换行',
16         lineWrapLbl: '关闭自动换行',
17         autoLinks: '自动链接',
18         autoLinksLbl: '不自动转换超链接',
19         lineCount: '起始行号',
20         highlight: '高亮行号',
21         highlightLbl: '输入以逗号分隔的行号, 如 <em>3,10,15</em>.'
22     }
23 });

en.js 代码

01 CKEDITOR.plugins.setLang('syntaxhighlight''en',
02 {
03     syntaxhighlight:
04     {
05         title: 'Add or update a code snippet',
06         sourceTab: 'Source code',
07         langLbl: 'Select language',
08         advancedTab: 'Advanced',
09         hideGutter: 'Hide gutter',
10         hideGutterLbl: 'Hide gutter & line numbers.',
11         hideControls: 'Hide controls',
12         hideControlsLbl: 'Hide code controls at the top of the code block.',
13         collapse: 'Collapse',
14         collapseLbl: 'Collapse the code block by default. (controls need to be turned on)',
15         showColumns: 'Show columns',
16         showColumnsLbl: 'Show row columns in the first line.',
17         lineWrap: 'Disable line wrapping',
18         lineWrapLbl: 'Switch off line wrapping.',
19         lineCount: 'Default line count',
20         highlight: 'Highlight lines',
21         highlightLbl: 'Enter a comma seperated lines of lines you want to highlight, eg <em>3,10,15</em>.'
22     }
23 });

 最后在ckeditor/config.js添加两行调用的代码

1 config.extraPlugins = 'syntaxhighlight';
2 config.toolbar_Full.push(['Code']);

在网站你觉得合适的位置添加一个scripts和styles 文件夹里面分别存放给代码着色的JS代码和CSS样式表(代码太长我不贴上来了,你可以去网上搜一下)

 接下来在你要显示代码的页面HTML的head部分加入

01 <script type="text/javascript" src="scripts/shCore.js"></script>
02     <script type="text/javascript" src="scripts/shBrushBash.js"></script>
03     <script type="text/javascript" src="scripts/shBrushCpp.js"></script>
04     <script type="text/javascript" src="scripts/shBrushCSharp.js"></script>
05     <script type="text/javascript" src="scripts/shBrushCss.js"></script>
06     <script type="text/javascript" src="scripts/shBrushDelphi.js"></script>
07     <script type="text/javascript" src="scripts/shBrushDiff.js"></script>
08     <script type="text/javascript" src="scripts/shBrushGroovy.js"></script>
09     <script type="text/javascript" src="scripts/shBrushJava.js"></script>
10     <script type="text/javascript" src="scripts/shBrushJScript.js"></script>
11     <script type="text/javascript" src="scripts/shBrushPhp.js"></script>
12     <script type="text/javascript" src="scripts/shBrushPlain.js"></script>
13     <script type="text/javascript" src="scripts/shBrushPython.js"></script>
14     <script type="text/javascript" src="scripts/shBrushRuby.js"></script>
15     <script type="text/javascript" src="scripts/shBrushScala.js"></script>
16     <script type="text/javascript" src="scripts/shBrushSql.js"></script>
17     <script type="text/javascript" src="scripts/shBrushVb.js"></script>
18     <script type="text/javascript" src="scripts/shBrushXml.js"></script>
19     <link type="text/css" rel="stylesheet" href="styles/shCore.css"/>
20     <link type="text/css" rel="stylesheet" href="styles/shThemeDefault.css"/>
21     <script type="text/javascript">
22         SyntaxHighlighter.config.clipboardSwf = 'scripts/clipboard.swf';
23         SyntaxHighlighter.all();
24     </script>

即可调用。

上一张最终效果图

    

   至此基本上完成了ckeditor实现上传和代码高亮显示的功能,我自己也找了少资料,其中也遇到了不少小问题,最后差不多都解决了!

  如有什么不足或者错误之处还望指出。^_^

本文转载自:http://www.cnblogs.com/root7/archive/2010/11/02/1866712.html