Categories: WP/WP Plugins | Tags: , , | Views: 1,485

 

WordPress,个人觉得就是为喜欢折腾的人而生的。我就是其中之一,并乐此不疲。

好的插件总想跃跃欲试,好的效果,总是想改了再改。

无论是wp程序的更新,还是主题的更新与更换,我总是要小心翼翼地做好备份。因为程序已经被我改得遍体鳞伤,记得上次更新主题,改到之前的效果,不知道耗死了多少脑细胞!

对于插件,我就更无语,能让人省心的插件还真不多。当然,这也不能怪作者,他们也不可能所有的情况都考虑到,所有的环境都测试到。往往我改过的插件,我都不敢再更新,我的做法就是把他们的版本改得很高。让wordpress不再自做多情地提示升级插件。

无论有多么强大的功能,wp只是一个博客程序,最基本的功能还是发文记事。一个好的编辑器是必不可少的。然而wp自带的编辑器为免显得寒酸了点。这时强大的FCKEditor就有了用武之地。

Dean将其改为wp所用,并加入了wpmore插件,可以很方便的插入readmore。上一个版本是2.5。最近出来3.1。当时我看到FCKEditor有更新的时候,真的欣喜万分,真的很期待很多问题能够解决掉。不过让我失望的是,问题没有解决,还出现了新的问题。原来的编辑器和新的编辑器在Firefox下都表现良好。而IE则出现了各种各样奇怪的问题。

原版本的问题是,如果你的文章中含有某些HTML元素(具体是哪些,这个我没有测试),就无法切换到源代码视图。我看了一下出错的信息:this.Elements[...].outerHTML为空或不是对象。找到出错了那一行,加了一个判断语句: 

1
2
3
4
if(this.Elements[i]){ //pwwang
    this.Elements[i] = '<div> ' + this.Elements[i].outerHTML + '</div>' ;
    this.Elements[i].isHtml = true ;
}

 这样就不影响切换到源代码视图了。

而新版本的问题则更为离谱,先是好用的wpmore插件没了,然后是载入不了文章(这个有可能是网络的问题),最大的问题在于,切换到源代码视图(无法切换的问题已经得到修正)后,竟然无法切换到所见即所得模式视图,这个真是有点不可容忍,于是赶紧卸载了,装回原来的2.5版本。这个时候如果报错的话,检查一下是否需要重新生成smily图片缓存(在wp的设置中)

至少现在2.5在发一般的文章时问题还是不大的。于是将2.5的版本版了一下(在插件主文件的前几行注释中),以免wp总是提示升级。

说了这么多,还没有到代码的问题上来。

上面说过,dean’s fckeditor for wordpress 2.5在发一般文章时是很好用的,可是如果你想贴代码,那可谓是苦不堪言。并且一旦你的文章写好了,你就不敢再修改了,因为你不知道fckeditor会把你的文章变成什么样子。FCKEditor会把你的代码中与HTML相关的代码进行自动转换!!但是,这不能怪fckeditor自作多情,因为fckeditor的很多操作都要用到dom,如果你插入的代码打乱了dom树,那fckeditor的很多功能就不能用了,甚至很有可能崩溃。

那我们就眼睁睁和看着我们的代码被蹂躏得面目全非吗??

No, never!!

早前我就有过尝试,我开始以为是我们用的代码插件对我们的代码抛了媚眼。后来才发现我错了,其实它们(wp-codebox,wp-syntax)从来就没有勾引过我们的代码,也没有从中拿过回扣,他们只是在显示的时候让不同的字符串穿上不同的衣服而已。

那到底是谁动了我们的代码?

毫无疑问,只有编辑器。仔细看就知道,你在源代码视图下输入好的代码,切换到所见即所得视图,再切换源代码视图的时候,代码就已经面目全非了。而写进数据库的,就是源代码视图下的那些字符!我们在源代码视图下敲入的字符就是我们想存进数据库的东西,你乱动个什么?!可是原因我已经在前面解释了,它也很无奈,为了生存啊!之前我写的那篇《告别wordpress贴代码的烦恼》,只治到了标,而没有治到本,之前有想过不让编辑器动我们的代码,可是看看fckeditor的源码,只能望而却步,于是退而求其次,既然你编辑器动了我的代码,那我在显示的时候再动回去就行了。这样在发表和显示文章的时候都没有问题,可以问题还是出在编辑文章上,因为开始编辑文章的时候,语法高亮插件根本就插不上脚!编辑器这时候终于威风一把。

其实想想,有时候我们是需要编辑器对我们的代码动动手脚的。你想想,如果你在源代码视图中,某个tag的名字敲错了怎么办?或者某个tag忘了关闭怎么办 ?如果编辑器不能你纠正的话,等到发表后,在网页中显示的时候,那就很有可能打乱你整个网站的结构了!这一点也不耸人听闻!

那很明显,我们只是想它不动我们的代码而已。而现在主流的语法高亮插件都是通过pre来实现的,就像上面提到的wp-codebox和wp-syntax,语言则采用lang来指定。那就好办了,我们只需要在编辑的时候将这个pre块保护住就行了。

怎么保护?

思路很简单,我们可以先正则表达式将这样的代码块找出来,然后将这些代码块在所见即所得视图下用FakeImage来保护住(FCKEditor的一种机制)。那么我们现在可以来整理一个整个思路了。

我们可以在fckeditor中添加一个工具栏插件:

然后弹出一个对话框,让用户输入语言类型,其他属性以及代码:

代码输入好之后,确定,在所见即所得视图下就会出现一个Fakeimage:

点击右键就可以编辑代码了。这样就算你切换到源代码视图,再切换到所见即所得视图,代码还是被保护住的。(这时候Firefox会将换行转换成br,只需要点击那个Translate BR按钮就可以恢复格式。这一点,IE倒不会转换。)特别值得提一下的是,如果你插入的是HTML代码,请使用Translate <>按钮,这样可以保护你的HTML代码不被浏览器当作源代码处理(这个要先按照《告别wordpress贴代码的烦恼》进行修改)。另外,这样还可以防止你的代码中含有</pre>而将代码截断(正则匹配采用的非贪婪模式)

以后,无论文章里是否包含代码,都可以在源代码和所见即所得视图中随意切换。

后记:

贴代码的问题相信已经困扰了wordpresser们很久了。现在总算有了一个初步的方案。

想说的,还是浏览器的问题。

由于IE没有很好的js调试工具,所以一直是在firefox下调试开发完成的。另外FCKEditor的插件机制实在不敢恭维,至少仅仅在插件目录中写代码是难已完成的。这一点,wp就要好多了。当然,客户端语言和服务端是没法相比的。直到所有的功能在firefox下运行正常之后,我才去ie下测试。

开始的问题的右键点击FakeImage根本就没有Edit Codes菜单出现。还以为是浏览器的缓存问题(IE总是喜欢自作多情的缓存,浏览器真应该有个选项,是否禁用缓存。速度上虽然是快了,但是却给开发者带来不少的麻烦,话说回来,反正MS就没有为开发人员切身考虑过,Firefox下的Web Developer插件就能很好地禁用缓存),后来发现并不是,而是IE根本就无法判断右键菜单的listener是FakeImage,原来IE下要获得一个元素的class属性,用getAttribute(‘class’)是得不到的,只能用getAttribute(‘className’)。真的有点莫名。

在Firefox下功能正常后,我以为会松下一口气,可是没想到,右键菜单的问题解决后,IE又出了问题。它把我所有代码中的换行和制表符全部都变成了空格,这怎么行?代码的美感就来自于此。原来,我在往源代码视图插入代码的时候,获取了原来代码块的代码,然后通过innerHTML赋给了新建的DOM元素pre,问题就出在这个innerHTML上,Firefox中是没有问题的,可是在IE中,问题就是这么千奇百怪。于是迅速上百度Google一下,说的都是innerHTML自动闭合标签和把标签名转变为大写的问题,这样的问题压根没有。这下我可真有点泄气了,好好的一个功能就要实现了,难道要夭折?

这里也许有个会说,插入的时候直接用HTML字符串插入,这样就不会转换了吧。是的,我也这么想,可以FCKEditor不这么想,它只能采用DOM结点的方式进行插入。于是想到了是否可以将HTML字符串转换成DOM Node,再上百度Google,找到一个,但是我一看有innerHTML,就觉得没戏了。

乍然想起jQuery不是可以直接将字符串转化为jQuery对象吗?

我先用jQuery测试了一下,

1
2
3
4
5
6
$('#a').append(HTML2Element('<pre>FCKCode.prototype.Execute=function()\n{\n\tvar oPre = FCK.EditorDocument.createElement( \'pre\' );\n\tvar oFakeImage = FCKDocumentProcessor_CreateFakeImage( \'FCK_Code\', oPre) ;\n\toFakeImage    = FCK.InsertElement( oFakeImage ) ;\n}</pre>'));
 
function HTML2Element(str){
    var $div = $('div').append(str);
    return $div.children(0);
}

发现测试成功,浏览器将换行和制表符都原封不动地输出!IE&Firefox表现都正常。

可是,我总是至于要把jQuery也拉进来吧,本来FCKEditor就不小了。jQuery的插入的实现也是要通过dom的吧,那jQuery肯定在某一步将字符串转换为了Node。翻开jQuery的源码,发现DomManip函数就是干了这样一件事。可是我看到下面仍然用了innerHTML。由于就很奇怪了,难道jQuery用了什么魔法让IE的innerHTML听话了?

于是将jQuery的DomManip(可以转换多个HTML字符串)函数简化,测试了一下,也成功。对比了一下,发现DomManip的innerHTML插入的时候字符串是用tag包裹好的元素,而我插入的就是一个字符串。问题出在这。那么一个简单地将单元素的HTML字符串转化为Node的函数就出炉了:

1
2
3
4
5
function str2Node(str){
    var $div = document.createElement('div');
    $div.innerHTML = str;
    return $div.childNodes[0];
}

顺带贴一下将Node转化为HTML字符串的函数,其实就是IE下outerHTML,可惜Firefox不支持:

1
2
3
4
5
6
7
8
9
10
11
12
13
function node2HTML(node){
    var t = node.tagName;
    var ret = '<'+t;
    var attrs = node.attributes;
    for( var i=0; i<attrs.length; i++ ){
        attr = attrs[i];
        if( attr.specified ){
            ret += ' ' + attr.name + '="' + attr.value + '"';
        }
    }
    ret += '>' + node.innerHTML + '</' + t + '>';
    return ret;
}

这样,就可以不经innerHTML的转换将字符串转化为Node从而插入FCKEditor的源代码视图。按照这个思路,问题终于圆满解决!

这篇文章来自 迷途知返(PWWANG.COM), 转载请注明出处。 版权说明

  1. October 24th, 2009 at 14:10
    Reply | Quote | #1

    学习了,刚开始就很喜欢折腾,现在根本没时间~再说技术也有限,有空跟博主讨教

    • October 24th, 2009 at 20:01
      Quote | #2

      @fcola:讨教不敢当,有时间一起讨论吧 :roll:

  2. October 25th, 2009 at 10:25
    Reply | Quote | #3

    有时间请教一下啊

  3. October 25th, 2009 at 11:00
    Reply | Quote | #4

    @all:大家都很忙啊~ :idea:

  4. October 25th, 2009 at 11:50
    Reply | Quote | #5

    啊?

    • October 25th, 2009 at 23:14
      Quote | #6

      @箫童:大家现在都没有时间 。。。

  5. October 26th, 2009 at 10:21
    Reply | Quote | #7

    哦,那以后常联系啊

  6. Gareth
    December 25th, 2009 at 15:38
    Reply | Quote | #8

    我也遇到这种头痛问题,我想把nextPage加到fckeditor里面,结果fckedtor老是搞个自动闭合 ,而且不知道Dean怎么加载插件的,找到 extraPlugins : ‘wpmore’, 但是我在后面加个’wpnextpage’ 就不行了。望指教。

    • December 26th, 2009 at 10:43
      Quote | #9

      @Gareth:这个不是简单地加上wpnextpage就可以了的,需要采用fckeditor的插件机制来制作一个插件。dean的wpmore实际上做成了fckeditor的一个插件。

  7. Gareth
    December 26th, 2009 at 13:04

    pwwang :@Gareth:这个不是简单地加上wpnextpage就可以了的,需要采用fckeditor的插件机制来制作一个插件。dean的wpmore实际上做成了fckeditor的一个插件。

    恩,是的,不过由于dean对fckeditor修改过多,用以前加载插件的方法我一直未成功,包括那个isert code,我也没弄出来。不过加入 nextpage 功能 ,我已经通过修改dean自带的more插件完成,暂测无错。

;) :| :x :twisted: :roll: :oops: :o :mrgreen: :lol: :idea: :evil: :cry: :arrow: :P :D :?: :? :) :( :!: 8O 8)

你可以使用@somebody:开头, 来邮件通知somebody你回复了他的留言(用户名区分大小写).