2006年7月13日,想弄一个类似Wikipedia上文章目录的功能,希望能参考Wikipedia的格式,只要用"==title=="这样就可以自动生成标题,并在文章的开头根据这些标题自动生成目录。写了一点代码,但是没有完成,能力有限啊。2007年1月10日,也就是半个月前,在鼓捣我的Projects页面的时候,偶然发现了Table of Contents Generator
插件,可以为文章自动生成一个目录,方便浏览者查阅。这个功能不错,有点类似Word的目录域功能,只要在合适的地方添加一个目录域,这个地方就会显示当前文档的目录,而且当你修改文档的时候目录也会自动更新。
看了一下这个插件的源代码,不是很满意,于是就重新写了一个,用于我的Projects页面。Scott Yang用的堆栈,我觉得不太好,就用了一个数组模拟堆栈,写出来的代码也短一些。Scott还考虑了对分页文章的处理,我没写过分页文章,而且现在很多喜欢分页文章的人都用了Coolcode.cn的AJAX分页插件,两个插件兼容性上也会有一些问题,所以分页功能我就不予考虑了。再在大的函数开头建几个类变量的引用,这样整个程序小了很多。
给目录上方上面加了一个标题“Table of Contents”,这样就和Wikipedia里的目录很象了。Wikipedia里的文章目录标题旁边有一个链接,点击它可以隐藏或显示目录内容。我懒得弄那个链接了,直接通过JavaScript代码控制当点击标题时隐藏或显示下面的TOC框。参考了WordPress Codex里这个页面的JavaScript代码,弄好了点击隐藏TOC功能。JavaScript代码很简单,但有一个问题是:当隐藏TOC内容后,因为标题“Table of Contents”比目录部分窄很多,所以整个TOC块的会突然变窄,有点难看。Wikipedia里没对这个情况进行处理,点隐藏就突然变窄,点显示又突然变宽。而WordPress Codex里则使用固定宽度的TOC框,固定宽度在目录里有比较长的标题的情况下比较好。查了一些CSS方面的资料,使用JavaScript在隐藏的时候把TOC框的clientWidth值赋给toctitle.style.width。这样在Firefox下没有问题,IE里却还是不行。用JavaScript的alert()函数查看TOC框的clientWidth值,发现是0。在网上逛了很久,都说没有办法。最终,只有用offsetWidth这个属性。offsetWidth和clientWidth的区别是,前者包括border的宽度,而后者不包括。最终写出了比较完美的代码,在IE6 SP2、Firefox 1.5.0.6、Opera 9.10下均测试通过。
还有锚的问题。Scott的插件里用标题生成锚,WordPress Codex里用标题URL encode后去除百分号生成锚。这样做有一个好处就是,当增加标题的时候,锚地址不会变,因为锚地址只和标题文字有关,和顺序无关。缺点是,中文标题生成的锚地址会很长。我用的是序号的方法,这样做的好处是当修改标题时锚地址仍然不变,而且在中文环境下锚地址也会短些。总之,两种方式各有所长吧。
前几天忙于WordPress 2.0.7和WordPress 2.1,今天抽了点时间又看了下这个插件。插件在文章页面显示没有问题,但是在feed里出了问题。查了很久,将近3个小时,看代码看得我快崩溃了,最后才发现类的对象只建立一次,它是被重复使用的。把初始化变量移到函数里,问题就解决了,可以release了。
请移步到“Yskin's Table of Contents Generator”主页下载软件并查看更多信息。
2006年12月27日,突发奇想,觉得可以写一个在后台就可以很方便切换WordPress语言的插件。WordPress通过gettext支持语言包,而语言包有3种:WordPress本身的语言包、模版语言包、插件语言包。我觉得插件可以检索所有已安装的语言包(也就是mo文件),并在WordPress后台显示出来。另外,gettext的语言包总是用空字符串对应的翻译字符串来存储语言包的信息,这些信息可以显示出来供使用者参考。
这个插件花了3个下午。根据我的Google Calendar的记录:12月27日下午,5个半小时;12月28日下午,4个半小时;12月31日下午,3个半小时。12月28号晚上,写了两天,觉得差不多完成了,本来准备发布出来,但是肚子饿,跑去吃饭了,就没发。29、30号忙,又拖了两天,今天又仔细看了一下,发现还有很多或大或小的问题,比如在没修改过wp-config.php里的WPLANG常量定义时没法工作。呼,还好28号没发布出来,要不然就丢人丢大发了。又花了点时间解决了一下,现在发布出来。
插件的原理是设置$locale变量。WordPress的get_locale()函数会先读取这个变量,如果不存在才会去检查常量WPLANG。所以,本插件只要设置一下全局变量$locale,就可以绕过常量WPLANG,控制WordPress的语言。不过,当有插件使用load_plugin_textdomain()函数载入自己的语言包的时候,就会调用get_locale()函数。所以,我们的插件需要成为第一个载入的插件。这个问题在这里有过讨论,有人提出给插件添加等级,高等级的插件先载入;有人说语言包应该在插件都载入完以后再统一载入。最后,markjaquith以一句"Shouldn't plugins be able to manipulate the active plugins array to 'shuffle' themselves to the front if need be?"来结束讨论。所以,没办法,只有从插件调用顺序上想办法。查了下ASCII码表,选中了"$"符号。把插件的名字起成"$language-switcher.php",因为WordPress会按照ASCII码顺序调用插件,而大多数插件的文件名都是以英文字母开头的,所以这个插件将在其他插件之前被执行。
在后台里添加一个选项页。选项页代码里,在/wp-includes/languages/目录里查找*.mo文件,此为WordPress的语言包;在当前模版的目录里查找*.mo文件,此为模版的语言包;在/wp-content/plugins/目录里递归查找*.mo文件,此为插件的语言包。用gettext依次读取各个mo文件,把空字符串的翻译读出来,解析出各项信息,包括名称、修订日期、译者、国家、语言、编码、翻译字符串数,然后显示出来。另外,在当前正在被使用的语言包后面显示一个红色的"(active)"字样。
在选择新的语言,并点更新选项后,新的选项页面还是原来的语言。没办法,设置的更新是在代码执行到很靠后的地方才被完成的。所以,我想加一个自动刷新页面的js,在网上查了些自动刷新页面的JavaScript代码,都说可以用window.location.reload()这个函数。我试了一下,好像有点问题。因为在点“更新选项”后,浏览器是以POST方式把数据发回服务器的。所以在刷新页面时,Firefox会提示“要查看的页面含有过期数据。”,IE也有类似的提示,这样不爽啊。想了一下,用了window.location.href = window.location.href;这句代码,那个提示就没了。然后用setTimeout()函数设置让它在页面载入5秒之后执行,OK了。
拿我写的WordPress简体中文包,还有Kirin Lin的WordPress繁体中文包,还有我的K2模版中文包以及我装的3个插件的中文包做了测试。因为台湾地震的原因,点点游的中文版下不下来,要不然也应该拿来看一下。插件后台截图在这里。那个Dagon Design Sitemap Generator插件的简体中文包,明显是拿Kirin Lin大大的繁体中文包改的,连"Country: TAIWAN"都没改过来,嘻嘻。
Language Switcher插件的简体中文包也写好,一起发布啦。
请移步到“Language Switcher”主页下载软件并查看更多信息。
这两天垃圾评论越来越多了,以前一天20封,现在一天没上网,垃圾评论100多。每次临近过年的时候都会收到好多人的告诫,“快过年了,注意提防小偷啊,因为小偷也要抓紧干活准备过年嘛。”今天是圣诞节,过两天就是元旦了,国外的spammer是不是也在准备过年啊?
以前用的是重量级插件Spam Karma 2,不过已经停用好久了,SK2太重量级了,我的小Blog还用不上。这几个月一直用着WordPress自带的评论审查功能,在WordPress后台->选项->评论选项里可以找到。WordPress提供了两个功能,一个是“评论审查”,将符合审查关键词的评论的comment_approved值设为0,这样评论被缓冲,并不显示出来,等待管理员来处理。另一个是“评论黑名单”,将符合黑名单里的关键词的评论的comment_approved值设为"spam",这样评论不会显示,也不会在后台->管理->等待审查列表里显示出来。
用黑名单固然好,不用管理员处理,不过可能会误封一些正常评论,而且评论仍然在数据库里,还占用一个ID号。用评论审查呢,可以随时到等待审查列表里检查截获的垃圾评论,看一下,把误封的挑出来,其他的全部删除,这样不占用数据库空间。缺点是,还是被占掉一个ID号,而且垃圾评论会同时出现在管理->等待审查和管理->评论两个列表里,每次去看评论都要先去等待审查列表里清一下垃圾评论,也不是很方便。
于是就写了个小插件,解决一下这个问题。在"pre_comment_approved"那里hook一下,检测到评论被设置为spam就直接die(),hoho。
我的Blog只需要设置两个关键词:"...</strong>"和"[/url]",就可以屏蔽掉几乎全部垃圾评论了。
P.S. Merry Christmas. 昨晚平安夜,有没有放袜子在床尾啊?一定要白色棉袜子才行的哦。
Update:修改了一下,添加了一个功能,可以过滤所有包含"...</strong>"字样并且一个汉字都没有的评论。基本上带"[/url]"字样的评论都是针对那些使用UBB之类代码的Blog,可是WordPress本身不支持。带有"...</strong>"字样的,一般都是Trackback。好像有一些系统,甚至有些WordPress发送的Trackback的内容是以"<strong>...</strong>"开头的,不过我的Blog里目前只有7条是这样的。没仔细看WordPress源代码,好像大多数WordPress发送的Trackback不是这样的啊。黑名单只能过滤字符,不能做进一步的判断,所以我给插件加上一个功能,可以判断评论里是否有这样的字样,并且在评论不包含汉字的时候直接清除。这样基本上不会误删了。
写这个插件耗了不少时间,我也学到一些PHP知识。比如,表达式'spam'==true的结果是true,'spam'==0的结果是true。所以要用三个等号===进行判断才准确。还有WP的add_action()函数的用法,唉,复杂复杂。
Update2:到今天为止,这个插件用了整整半个月了。现在垃圾评论平均每天一条吧,插件的效果还算不错。
请移步到“Yskin's Kill Spam Comments”主页下载软件并查看更多信息。
花了点时间写了一个小插件,以解决中国大陆服务器因无法访问Technorati导致WordPress后台Dashboard页面超时的问题。
因为国内无法访问Technorati,当进入WordPress后台Dashboard时,页面因读取Technorati上的RSS而超时。有时会显示空白页,有时则要花30秒钟才能打开页面。很多人需要在Blog主页点登陆后台来进入WordPress后台页面,这样登陆后会自动进入Dashboard页面。我在Firefox里会一直开着一个WordPress后台的页面,每天下网的时候保存tab列表,第二天上网时再打开。由于有cookie记录登陆信息,所以很少进Dashboard页面。可能有些blogger经常在网吧上网,所以才需要经常这样进后台。
解决办法嘛,手工修改/wp-admin/index.php文件,把Incoming Links部分注释掉是个好办法。[via]还有可以每次登陆后台时用一个后台其他页面的地址,比如http://域名/wp-admin/edit.php。
今天突然想到,可以学Kill Preview
插件的办法解决一下这个问题,于是写了这么个小插件,取名叫Kill Incoming Links
。试了一下,应该没啥问题,hoho
Update:升级到2.0,基本全重写了,学Feed Control
插件,激活插件和停用插件时自动配置WordPress,使得插件激活后Dashboard中的Incoming Links部分立刻不显示,插件停用后Incoming Links部分立刻恢复。在DreamHost空间上测试通过。
顺便设置feed的cache的寿命为1天,使得另外两个feed不再频繁读取。
更多信息,请访问Kill Incoming Links主页。
昨天在丸子那儿看到《veryCD的title》这篇文章,谈到VeryCD网站首页标题栏会随机显示一条名言警句。到VeryCD网站看了一下,发现它是利用JavaScript语言修改的title标签,具体的js代码在http://doc.verycd.com/script/title.js里。顺着丸子的指引找到了《VeryCD的版头标语合集》,总共有238条名言警句。
想起前段时间弄的wp-saying插件,当时因为找不到一个比较好的名言警句集而停工。现在有了这238条名言警句,倒是可以好好的利用一下。花了一点时间,参考WordPress自带的Hello Dolly插件写了这么个Wisdom Title
插件,安装激活后,会在Blog首页的标题后面随机显示一条名言警句。效果看我的Blog首页可以了,和VeryCD网站首页的效果一样。
我觉得这么一小条名言警句显示在title上挺好的,而且只显示在Blog首页,因为首页的title比较短,可以利用其后面的空白,其他页面的title还要显示文章标题呢。如果你想要显示在其他位置,那么在模版里的相应位置加一条echo get_wisdom();语句就可以了,hoho
好吧,我承认这个插件蛮无聊的,嘻嘻嘻。
下载地址:
wisdom-title.txt
wisdom-title.phps
Update:
Wisdom Title 1.1 (2006-10-16 11:21)
顺着kerio的提示找到Random Quotes
插件,这个插件写于一年前,也是参考的Hello Dolly插件。Random Quotes的1.1版本修正了调用随机函数时最大值的错误,这个错误源自Hello Dolly插件,所以我的Wisdom Title插件也有这个错误。查看了一下mt_rand()函数的说明,又写了个小程序做了一下测试,mt_rand(5, 15)这样调用生成的随机数范围是[5,15],包含5和15。
另外又学着Random Quotes插件使用定界符,这个东西好,比起双引号来解决了字符串中的双引号需要转义的问题,不过变量仍然会被解析,不过字符串中正好包含一个变量的概率很小。最好的解决办法是使用文本文件存放这些名言警句,这样用户修改起来也方便。不过可能会因为插件使用者分不清DOS行尾符和UNIX行尾符,分不清ANSI格式和UTF-8格式,导致修改后的文本文件格式错误。唉,懒的做那些了,这个插件是给懒人准备的,安装激活即可,不用做更多的设置。
另外加了一个show_wisdom()函数,如果需要在其他地方显示名言警句,可以修改模版,在适当的位置添加<?php show_wisdom(); ?>这段代码。如果想同时禁用在首页标题栏显示名言警句的功能,把插件最后一行add_action('wp_head', 'wt_wp_head');注释掉即可。
Update2:
Wisdom Title 1.2 (2006-10-16 18:51)
重新整理了一下名言警句,添加了一些新的,删除了一些无聊的,修改了一些错误,分成现代文、古文、英文三类。
Update3:
Wisdom Title 1.3 (2006-10-19 13:08)
在后两个<<<EOF后面添加了一个空行,因为不加的话,第一行会和前一个的最后一行连起来,成为一句。唉,定界符还真是麻烦!
对输出给JavaScript的字符串进行处理,参考《用 PHP 生成 JavaScript 字符串》。
昨天在抓虾看feed时突发奇想,觉得可以用导出的OPML文件生成一个链接列表,这样就不用每次都很麻烦地到RSS阅读器里添加了feed再到WordPress后台添加link了。
上网查OPML转HTML的程序,发现williamlong在9月2日写了一个抓虾的OPML频道转换到Z-Blog友情链接插件。Z-Blog的插件,唉,不懂ASP,硬着头皮看了一下,好像只是把其中的链接提取了出来,没有处理目录。
又想起WordPress后台的链接部分有一个“从OPML文件导入链接”的功能,去查看了一下具体的实现代码,好像也是直接抽取链接,并没有处理目录。这可真是奇怪,WordPress的链接是可以分目录的呀。
处理XML文件有一个好办法:XSL。这个办法在Java里用不错,不过PHP里需要支持XSL的函数库才行。找到两个用XSL转换OPML到XHTML的程序:OPML to HTML/XHTML,Optimal。第二个程序是非常好的,生成的树状链接列表用Javascript控制,点击目录名可以显示活隐藏目录内容。不过这个插件太大了,又要在页首输出js和CSS,而且对服务器的环境也有要求,需要PHP5或者PHP4.3加domxml和libxslt函数库。
找到一个PHP写的OPML转HTML的程序,这里是他的示例页面。根据他的提示找到ipodder.opml.class.php这个程序,粗略的看了一下,他用了table,不如第一个程序用ul简洁。不过第一个程序已经不提供下载了,只好在第二个程序的基础上改。
今天开始写这个插件。ipodder.opml.class.php这个程序是为转换一个podcast而专门写的,里面做了很多特殊的处理。大概看了一遍整个程序,又去了解了一下xml_parse_into_struct这个函数。原程序对中文不支持,还有很多小问题。大刀阔斧地修改了整个文件,照着原来用ul的样式输出HTML。我用Bloglines导出的OPML文件进行测试,显示没什么问题。再用抓虾导出的OPML测试,发现抓虾的OPML文件用了一个根目录"base"。为抓虾专门写了几行代码,解决了。
OPML文件里带有标题、类型、Blog地址和feed地址等信息。程序本来会输出feed地址,不过我觉得可能用不着,就给加了一个参数,true就显示,false就不显示。给各个地方的html标签加上class,这样就可以通过CSS控制显示的效果了。
抓虾的OPML必须登陆进去才能导出,Bloglines则可以通过访问类似"http://www.bloglines.com/export?id=Yskin"这样的地址得到。如果只用Bloglines做RSS阅读器,那么利用WP-Cron插件定时读取Bloglines的OPML文件,存到服务器上,这个程序就很完美了。不过我两个都用,唉,只能手工导出抓虾的OPML,再保存到服务器上,伤脑筋啊。
先写到这儿吧,功能基本上已经齐全了。用页面模版建了Blogroll页面,看看效果吧。
WordPress OPMLtoHTML
下载地址
参考WordPress自带的Hello Dolly插件,写了一个小插件,自动在首页显示一段话。
从文本文件里读取文本,随机选取一段,保存出来。每15分钟更新一次。前台只要取出显示就可以了。
起名叫wp-saying,学keso的那个saying tag。发这篇文章,给它安个家。
我刚接触Wordpress的时候——大约在今年3月份或者更早吧——除了Wordpress自带的插件,最先装的插件应该就是桑葚的中文WordPress工具箱
了。(一个小发现,我用紫光V5打出来的是“桑椹”,而他的网站上写出来的是“桑葚”,在金山词霸查了一下,好像紫光打出来的是正确的,桑椹——英文mulberry...汗了)
这个插件提供了很多功能,都是一些国人喜欢的功能——最新文章,最新评论,评论数最多的文章,发表评论最多的网友,随机文章以及适合中文环境的摘要功能。这些功能我感觉并不实用,虽然国内的大多BSP都提供这些功能。最新文章功能Wordpress自带,最新评论功能倒还有点用,随机文章功能对于专门讨论某个方面的Blog还行,而我一直的观点是一个Blog对应一个人,个人的所有文章应该发在同一个Blog上,文章的分类应该靠Blog系统的分类功能解决,而非建立多个Blog。我的研究方向比较多,所以我的Blog分类很广,这样的情况下,一个设计的比较好的相关文章功能可能比随机文章好的多。
继续阅读《中文WordPress工具箱》
今天写了一个小插件,可以在首页的sidebar显示Blog的一些统计信息。起了个名字叫Yskin's wp-statistics
。
目前插件可以显示文章数、评论数、分类数、TAG数和总字数,其中文章数、评论数、分类数的代码copy自WordPress的wp-admin\index.php文件;TAG数的代码参考了UTW插件源代码;总字数的代码来自我以前写的《增加显示文章字数功能》,这个功能执行时间比较长,使用这里提供的计算PHP代码执行时间的代码进行了测试,我的120篇文章7.5万字,大概要执行0.1秒,当然我的网站所在的服务器本身执行速度还可以,如果页面执行速度受到影响可以把这项禁用。还参考了Post Word Count
插件,参考了他不统计未来文章的特性。
这个插件可以输出"<br />"和"<li>"两种格式的html代码,使用<?php ShowStatistics(); ?>输出"<br />"格式,使用<?php ShowStatistics(false); ?>输出"<li>"格式。插件本身比较简单,如果有不需要显示的部分,直接注释掉相应行就可以了,想调整显示的顺序,也是直接改ShowStatistics()函数中的代码就好了。
明天再来做些修改。http://codex.wordpress.org/Plugins/Statistics
请移步到“Yskin's wp-statistics”主页下载软件并查看更多信息。
Name and Homepage
,用于自动产生粗体的软件名,并在后面放置一个指向软件主页的图标。实现的效果就是前面名字的样子。
很早就想写这么个插件,因为经常写Firefox扩展、Wordpress插件还有一些比较好的小软件的说明,可是无奈技术不行啊。现在终于抓住了个葫芦——Quotmarks Replacer
,就照着这个葫芦画了个瓢。找到PHP手册里正则表达式的部分,花了点时间终于把这个瓢画了出来。起了个破烂名字,随手把版本号写上1.0,把信息都改成我自己的,先用着看看。
使用说明:
- 上传到Wordpress插件目录,激活。
- 在需要写软件名称的地方写上
[name]Name,URL[/name],记得中间要用半角逗号。
- 发布后就看到效果了。
说明一下,之所以用[name]是因为这样可以直接在WYSIWYG编辑器里写,如果用了<name>就要去改html代码,而且编辑器里就看不到了。再说了,不知道WordPress会不会因为他不是标准的xhtml标签而把他删掉呢。
下载地址
Update:
1.1(2006-10-20 17:14)
给img标签增加了一个alt属性,这样更符合XHTML标准。
Update2:
1.2(2006-10-27 16:50)
优化了一下处理速度。添加the_content_rss过滤器,用于RSS 0.92。