Author: qingbo

  • JavaScript 慎用 with

    像我这样最初并不是系统学习JavaScript的人,看到with这个东西的第一感觉是兴奋——不用再重复地写“element.style.xxx = …”了,只需要

    [code lang=’javascript’]with (element.style) {
    xxx = …;
    yyy = …;

    }[/code]

    但是作为解释型语言,JavaScript都需要在运行时来决定xxx/yyy到底是什么东西。对每一个名字(不仅仅是被赋值的,也包括读取的变量!)它会首先去在with括号里的对象的属性里去寻找,然后才会找局部变量,最后是全局变量。在JavaScript的虚拟机、JIT技术普及之前,这种性能问题需要非常的注意。

    正确的做法是给element.style做一个local variable的cache:

    [code lang=’javascript’]var es = element.style;
    es.xxx = …;
    es.yyy = …;
    …[/code]

    这样不仅相对减少了代码大小,同时性能上也比element.style.xxx = … 要好得多。

  • 为WordPress 2.7加上鼓励评论功能

    encouraged-commentary
    Jim Jeffers刚刚发布了他的encouraged commentary脚本,功能非常强大,罗列一些主要的:

    • 在文章中选中一段文字即可在留言中引用
    • 在某条留言中选中一段文字可引用,并且针对该条留言回复
    • 回复留言
    • 列出某留言的所有回复
    • 列出某评论者在该文章的所有留言

    在我看来,第一条是最基本的功能也是最重要的。最后两点,对于评论不是太多的blog来说基本是多余,甚至会显得很杂乱。

    而WordPress从2.7版本开始内置了对评论回复的支持,因此第二点、第三点也就没太大意义了。

    Jim Jeffers说不打算做任何插件,只在github上给出了源代码以及详细的实现步骤,不仅针对WordPress,大部分的blog平台都可以应用。

    我就针对WordPress 2.7,简化一下脚本和整个流程,下面是让一个主题支持encouraged commentary的步骤:

    1. 将需要的三个JavaScript脚本放在主题的scripts子目录中,保持主题结构清晰。因为只留下上面所列出的第一条功能,所以Jim Jeffers的脚本大大简化——这个压缩包里的是我简化过的。
    2. 在header.php中,引入需要的脚本:
      [code lang=’php’]



      [/code]

      注意不要使用wp_enqueue_script(’jquery’),它没有提供$函数,而Jim Jeffers用到了。

    3. 在single.php中,找到调用the_content函数的地方,把这个调用包在一个div中。例如:
      [code lang=’php’]

      Read the rest of this entry »

      ‘); ?>

      [/code]

    4. 现在,选中文章中的文字之后,就会浮出一个按钮”Respond”,可惜没有样式。我们现在需要给它和评论中的blockquote加上样式,我的仅作参考:
      [code lang=’css’]#comment-respond {
      width: 96px;
      height: 24px;
      background: transparent url(images/button.gif) left top no-repeat;
      color: #FFFFFF;
      border: none;
      font-family: sans-serif;
      font-size: 20px;
      font-weight: bold;
      vertical-align: middle;
      cursor: pointer;
      }

      ol.commentlist blockquote {
      margin: 0 0 0 20px;
      padding-left: 10px;
      background: transparent url(images/blue-vline.gif) repeat-y scroll left top;
      font-style: italic;
      }[/code]

    还有什么问题?现在就在这篇文章试试这个功能吧!

  • JavaScript simple dialog

    dialog
    前些天做了一个非常简单的JavaScript library,用来模拟模态对话框(modal dialog),刚刚放到Google code上:javascript-simple-dialog

    在一个页面上向用户提示信息、与用户交互有多种方式,最基本的办法就是window的alertprompt函数。不过alert弹出的同时,会有一声比较恐怖的提示音,prompt在某些浏览器里因为安全限制比较麻烦,用户体验都不是太好。

    以前做项目的时候也想找一个现成的对话框来用,但是大部分都不符合我的要求,比如jQuery的插件SimpleModal只能允许同时有一个对话框。jQueryUI的Dialog,当时我记得结构比较复杂,使用的CSS定位比较特殊,对内部内容要求也比较特殊,不知道现在的最新版本怎么样。

    于是这次基本是从自己的需求出发,设计并实现了这么一个小东西。最主要的特性是兼容IE(即可以盖住页面上的select按钮——掩饰IE臭名昭著的bug),以及可同时运行多个实例。

    更多请看Google code上的项目主页,在那里也可以下载代码或者直接从svn check out.

    这里有一个简单的demo.

  • 主题支持2.7评论系统需要注意的几点

    评论支持嵌套和分页是WordPress 2.7的一大亮点,不过让主题支持这个新的评论系统稍微有点麻烦,WordPress Codex上给出了一长串步骤

    其实最简单的,就是仿照默认主题来做,这里有一篇中文的文章讲得很清楚。

    需要注意的是:第三步尤其重要,很多人可能会忘记还要修改header.php,但是如果没有加入这个JavaScript脚本,点击回复就会刷新页面,用户体验很糟糕。

    另外如果要做一个通用的主题,就必须支持分页。仿照默认主题,就是下面的代码:

    [code lang=’php’]

    [/code]

    然而2.7的next_comments_link函数有点问题,在后台启用分页的时候,一切正常。但是禁用分页以后,next_comments_link无论如何都会返回一个链接!这一点用默认主题就可以测试,禁用分页之后,在评论列表的最下方可以看到链接“Newer comments”。我已经在trac里提交了一个bug,希望在下一个版本可以解决。

    目前的解决办法是在主题中判断一下page_comments选项,启用时,才生成导航链接:

    [code lang=’php’]

    [/code]

    我的主题是给自己用的,干脆就直接不生成导航了,因为我现在不打算分页。

  • Firebug 1.3与Ajax response

    如果一个Web开发者从来不使用firebug甚至从未听说过,我真替他感到可悲。

    昨天,Firebug 1.3正式发布release notes在Google code上可以看到,现在查找更新即可自动升级了。Firebug是Firefox的扩展,但是它本身也提供了良好的接口,已经有不少扩展了。1.3版本包含了一些对于扩展开发者非常有帮助的特性,然而对于我们普通的Web开发者用户,最期待的更新当属JavaScript debugger了。在一个inner function里单步的时候,你可以通过scope chain来查看function定义同级的变量值。

    在调试Ajax应用的时候,用Firebug来查看Ajax请求的response即服务器端返回的响应是最方便的,省了使用HTTP抓包工具。然而从某个时间开始,Firebug的这一功能不再好用了,由于Firefox的一个内部实现问题,插件无法对响应进行分析。从这个讨论来看,应该是2.0版本,不过我记忆中似乎没这么早……症状就是,在console的Ajax请求列表中查看一个的时候,response里并不是服务器返回的数据,而是Firebug的一个提示,具体请看这个网页的第一张图片。要想看到response,Firebug必须重新发送这个请求,这在许多情况下是不现实的。

    看到Firebug 1.3发布,我就在console栏里测试了一下Ajax的请求,惊喜地发现response已经可以查看了。

    事实上能否查看response数据在于Firefox而不在于Firebug,所以Firebug新版本发布与之关系不是很大。在前面提到的图片中可以看到,Firebug给出了一个链接,指向一个proposal:

    new nsHttpChannel interface to allow examination of HTTP data before it is passed to the channel’s creator

    等这个proposal被实现,查看Ajax response的功能自然就恢复了。从该bug记录下面的评论来看,应该是在3.0.4版本就实现了。再看3.0.4修正的bug列表,果然430155就在里面。

    好久没有调试Ajax应用了,这个功能的恢复还是挺好的。

  • Blog全新改版——白板

    白板,开会、讨论用的白板。要是麻将里的白板,那下一个主题就是红中了。

    主题中用到图片的地方,就尽量模仿成白板上写字的效果。似乎专业的美工做的时候,都是先把整个页面画出来,然后再切割,实现。我很不专业,先是日思夜想,把整个页面画在脑子里,然后就开始实现。

    首先画出页面的边框(白板的框架),CSS里就写出header, content, sidebar和footer了。然后就盯着首页,把日志的样式调出来,sidebar的样式,接着把原来主题里的评论样式复制过来改改颜色,中间需要什么图片就随时画(不排除“窃”)。

    最后就是最重要的header了。领导亲笔题词,给我开了个好头,让我的心里充满希望:

    星月轮转 (by qingbo)

    中间用bittbox做的免费白板字体弄了个类似tag cloud的文字组合,右边是一列订阅按钮。tag cloud里本来没有”RSS”的,后来加上订阅按钮以后,灵机一动,加了个”RSS”,又连了个箭头。一个全新的主题,就这样诞生了。

    当然,不可避免地要加上“增强WordPress中的Gravatar应用”一文中介绍的小trick 🙂 接下来,慢慢地加一些实用的插件,改善用户体验。

    在做主题的过程中,免不了又跟IE死磕一番。中间也巩固了不少知识,正所谓——越磨砺,越光芒。这些知识都是伟大的IE创造的。有那么两三刻,我都想在主题里针对IE用户放出一个banner:“我谨代表全世界受苦受难的劳苦大众,请求你弃暗投明,放弃史前怪物,使用非IE浏览器。”后来一想,我还得为了这个banner在IE里正常显示而折腾,算了,有空再说吧。

    欢迎测试、指正。

  • 延迟发布Feed须谨慎

    前阵子有人分享了一个延迟发布feed的技巧,在WordPress用户间广为流传。其原理就是利用WordPress的filter机制,发现当前的请求是Feed,即在查询条件中加一条,限制post的发布时间为五分钟之前(原文的代码escape太厉害了,直接复制有错误):

    [code lang=’php’] /**
    * puplish the content in the feed later
    * $where ist default-var in WordPress (wp-includes/query.php)
    * This function an a SQL-syntax
    */
    function publish_later_on_feed($where) {
    global $wpdb;

    if ( is_feed() ) {
    // timestamp in WP-format
    $now = gmdate(‘Y-m-d H:i:s’);

    // value for wait; + device
    $wait = ‘5’; // integer

    // http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html#function_timestampdiff
    $device = ‘MINUTE’; //MINUTE, HOUR, DAY, WEEK, MONTH, YEAR

    // add SQL-sytax to default $where
    $where .= ” AND TIMESTAMPDIFF($device, $wpdb->posts.post_date_gmt, ‘$now’) > $wait “;
    }
    return $where;
    }

    add_filter(‘posts_where’, ‘publish_later_on_feed’);
    ?>[/code]

    当时我看到之后也很兴奋,觉得非常之有用。因为我就经常在发布一篇文章之后马上发现有错误或者遗漏,赶紧修改,但是此时可能已经有些RSS reader过来抓取过了,我所做的修改不一定能被Feed订阅者收到(Atom Feed应该可以)。

    不过当我加上这个功能,又写了一篇文章之后,发现了问题。在文章发布的时候,WordPress会向预定的一些服务器发送ping,通知它们这里有更新,赶紧来抓取。如果该服务器反应很迅速,糟了,它来抓取RSS的时候,发现并没有新的文章——被放鸽子了。它可不知道要等五分钟再来抓取,新文章只好经历漫长的等待才能被抓到。

    所以要保证文章少出错,还得在发布之前多预览,多检查,而延迟发布RSS只能让你点击Publish按钮的时候更加勇猛。使用这个技巧一定要三思而后行

    为什么发布的时候发送ping消息很重要呢?如果不这样,那些RSS Reader只能盲目地周期性来查看,比如每天一次或者每隔3小时一次,Feed托管服务商也是这样。而在发布的同时通知它们,它们就会确切地知道你的blog有更新了,很快就会过来抓取,读者也就能在第一时间看到你的新文章了。

    附带列一下我的Update Services列表:
    http://rpc.pingomatic.com/
    http://ping.feedburner.com/
    http://www.zhuaxia.com/rpc/server.php
    http://www.xianguo.com/xmlrpc/ping.php
    http://blogsearch.google.com/ping/RPC2
    http://blog.youdao.com/ping/RPC2

    如果你使用feedsky的服务,当然也要把它的ping server(http://www.feedsky.com/api/RPC2)加上。

    BANGEC852A4639967E2F93AD50BBXIANGUO
    BANG004B23D38B0F7BB089F9BDD4XIANGUO
    BANGE0FB3CE98688F38AFA7A9C4DXIANGUO
  • 放弃Feed服务商,享受原汁原味的RSS

    人在悲哀之中,才象一个人。
    ——孟德斯鸠

    我们太像人了。

    本来Feedburner是Feed服务的不二之选,然而由于众所周知的原因,我们不得不放弃它转向Feedsky. 最近似乎也听到声音,Google已经把它打造成一台广告机器,而不是原来的专业Feed服务商了。而Feedsky一直在风雨中飘摇,没见过有稳定的时候。

    跟Feedburner一样,feedsky提供了域名绑定功能,让你无后顾之忧——即使你不愿用Feedsky的服务,也可以将该域名指向其它的地址,实现无缝迁移。然而这个功能还不如没有,白白欺骗我绑定了域名,却没有跟上稳定的服务,还不如使用它的默认地址。这几天,绑定的域名就时常不能访问,似乎是有一台服务器出了问题。客服论坛里好多人反映,但是这是假期。记得当初我们的网站虽小,也会在第一时间作出反应。

    我考虑了一下是不是把blog的header/footer的rss链接换成feedsky的默认链接,后来决定不再对它抱有幻想,干脆放弃Feedsky,直接提供WordPress的原始RSS输出,地址是 http://qingbo.org/feed 我发誓只要这个blog还在,这个地址绝对是最新的feed.

    本来指向Feedsky服务器的域名feed.qingbo.org已经做了url转发到 feed.qingbo.org,所以通过该地址订阅的朋友无需修改。不过建议使用Feedsky地址(http://feed.feedsky.com/flimsy)的朋友更改一下 🙂

    可能对Feedsky的要求过高了,逆境中生存,在国内应该算已经做得不错了。不过对于blogger们来说,稳定性还是第一位。

    好处:无需再为Feed服务的稳定性发愁,而且只要读者的阅读器来抓取,肯定是最新的Feed,不存在延时。

    坏处:无法使用Feed服务商提供的高级统计服务,不过我觉得订阅数都是浮云,怎样提升文章质量才是重点,并且有许多提供统计的插件可以使用,稍微弥补一下。牺牲稳定性来换取统计服务,我觉得非常不值得。

    至于Feed服务商为blog分担Feed请求的负载,我觉得在当今online reader统治天下的局面下,不需要考虑。一个Reader服务只需请求一次,即可服务成百上千的读者。实在不行,还可以使用插件将Feed输出静态化。

    BANGB3A348BDD78150D425D1BF9CXIANGUO
  • WordPress post slug与SEO,中文blogger的困惑

    今天在aw的blog看到他写的“中国Web工程师比美国人更厉害的4个原因”,讲了使用中文的计算机用户、以及面向中文用户进行开发的软件工程师需要额外修炼的法术——于我心有戚戚焉。当初在Linux里配置中文显示、输入的痛苦仍然记忆犹新,配置完系统又去配置特殊的软件;大部分的IDE把Ctrl+Blank作为代码提示的快捷键;……最近的ubiquity,也是以Ctrl+Blank作为呼出它的热键,并且其窗口会盖住中文输入法的候选窗口。尽管前辈已经把路铺得够平,我们已经足够幸福,中文在计算机世界里永远无法像英文一样简单、易用。

    晚上吃了饭,又看见WordPress爱好者论坛里有人问日志缩略名的中文如何修改,我不知不觉就像唐僧一样罗里罗嗦回复了一大堆。

    post slug是什么?在wordpress后台的永久链接设置(/wp-admin/options-
    permalink.php)里,用户可以自定义链接格式。绝大多数自定义的用户喜欢在url中包含由文章标题生成的一串字符,这就是post slug.
    一旦永久链接中使用了post slug,编写文章的时候标题下面就会显示post
    slug并允许你编辑,否则不显示,但wordpress仍然会自动生成并保存到数据库中。

    首先,URL中是不允许出现中文的,这个我以前写过一篇“中文URL编码”的文章,里面有详细介绍。简单地说,中文必须以UTF-
    8编码,然后再进行percent encoding,即每个字节转换成百分号后跟两位十六进制数字。英文标题不会引起任何问题,如图所示:

    post-slug

    但是如果标题里有中文(当然其它不是基于英文字母表的语言也一样),问题就麻烦了。为了符合标准,WordPress必须将它们做percent
    encoding,然后你看到的post slug就是一连串的百分号。

    为什么在地址栏看到的是正常的中文?

    我机器上的浏览器当中,除了IE 6,其它的包括Firefox 3,Opera,Chrome,Safari都会自动将url中的中文解码,所以我们会看到正常的中
    文。不仅如此,鼠标悬浮在链接上时,状态栏显示该链接的目标也会对中文进行自动解码。而IE
    6和Firefox以前的版本则没有这么做,浏览器地址栏就会看到一串百分号,IE 7以后的版本我没有测试,不知道它们是怎么处理的。Firefox
    3还有一个特点,它虽然显示了中文,可是复制的时候,剪贴板里仍然是未经解码的原始URL,这样可以防止某些浏览器错误地处理该链接地址。

    为什么post-slug不自动修改?

    post slug是在永久链接(permalink)中使用的。顾名思义,这个链接轻易是不会改动的。否则,搜索引擎所保存的记录就会失效,而指向该页面的链接也会
    失效,造成很多麻烦。

    实际上,post slug在特定情况下会自动更新的,那就是在文章发布之前。因为这时候,搜索引擎不会来抓取该网页,别的页面也不会有意指向这个“尚不存在的”页面
    。但是当文章发布之后再编辑文章标题的时候,post slug就不会自动更新了,这时,即使你主动编辑也要三思而后行。

    我如何更新这些“乱码”?

    好,你确定要修改post slug并承受永久链接失效的损失了。

    对于英文标题的post
    slug,改起来相当方便,因为英文不需要进行额外的编码工作。而中文的标题可就麻烦了,这些满眼的百分号对普通用户来说简直就像刺猬一样,不知道从哪儿下手。

    其实这是一项极为简单的工作,至少你不会经常这么做,所以犯不着做一个WordPress插件来帮助你完成。在Firefox中,打开Tools->JavaScri
    pt Console(Ctrl+Shift+J),代码框输入encodeURIComponent(‘中文标题’)并回车,“中文标题”这四个字的正确编码就显示
    在下面了。当然,如果中间有标点,还是做一些处理例如转换成减号比较好看。

    不喜欢中文post slug?

    毕竟,我们看到了它的本质——一串夹杂着百分号的无法阅读的文字,尽管多数浏览器已经将其解码还原。许多朋友还是喜欢用可读性更好的英文字母来做slug.
    可能有些勤奋而认真的blogger每写一篇文章都会自己写一个英文的post slug,但是更多的人习惯将这一工作交给计算机。cos_slug_transl
    ator
    就是一个自动翻译成英文然后生成slug的插件,还有一些转换成拼音的,大家有兴趣的话自己去搜。

    使用英文或拼音做post slug利于SEO?

    大部分人都这么认为,而我的意见是未必如此(我不懂SEO,如有误请专家指教)。这里仅针对中文内容和标题的blog post. 链接中有文章描述的主题关键字会增
    加该网页在搜索结果中的权重,这是正常的。然而用中文写成的内容和标题,链接却是拼音或者英文,这个,Google和Baidu会考虑吗?

    假设我写一篇文章,标题叫农历。

    如果我用英文做post slug,那么可能是lunar-calendar或者chinese-lunar-calendar.
    搜索引擎在收录该网页的时候,会考虑到链接中有lunar calendar而升高它在“农历”关键字搜索结果中的名次吗?我想不会。而搜索”lunar
    calendar”过来的人,90%的几率是看不懂文章在说什么。

    如果我用拼音做post slug,那么是nongli. 我认为搜索引擎同样不会因此而觉得该网页与“农历”关系更紧密。由于同词多音的存在,这个分析对于搜索引擎
    来说非常鸡肋。对于关键字”nongli”,搜索引擎会提示,是不是要找“农历”。

    如果用中文做post slug呢?我们可以在Google中搜索“农历”试试看。第一页上就有wikipedia的繁体农历词条。Google在这条搜索
    结果的下面给出的链接是“zh.wikipedia.org/wiki/農曆”。实际上该词条的真是链接地址是“http://zh.wikipedia.org/w
    iki/%E8%BE%B2%E6%9B%86”,后面是繁体“農曆”的编码。wikipedia没有使用拼音、英文做”slug”,而是直接使用了中文。而
    Google显然懂得对它进行解码,因为它给出了解码后的链接,并且将该词加粗,表明这是一个匹配,不仅仅是页面标题。

    搜索引擎懂得做简繁转换,懂得对percent encoding解码来寻找信息(这一点不知道百度做到了没有),但是目前似乎不会先翻译再搜索。

    所以我觉得SEO不是用拼音、英文做slug的理由。

    我个人在中文blog里倒是懒得用post slug,文章就用编号来查找,也就省了为中文的slug烦恼了。

    如有疑问或不同意见,请在此留言。

    plugin.html

  • 增强WordPress中的Gravatar应用

    如果你是点击了评论框旁边的“What?”帮助链接而来,推荐先看前一篇文章“Gravatar简介”。本文主要介绍如何用Gravatar来完善WordPress的评论框,实现这一功能,如果感兴趣并且已经了解Gravatar,请继续。

    虽然WordPress早在2.5的版本中就内置了Gravatar支持,似乎也没有人在添加评论form的旁边加上它。我似乎是第一个?呵呵,如有先行者,恕我孤陋寡闻。

    功能:在添加评论的表单旁边显示gravatar头像预览,登录用户直接取其email,而未登陆用户则首先尝试从cookie取得email,若cookie中部存在,则在其输入email之后,取得email值即时更新预览。

    首先说明,本文不介绍排版,即不介绍CSS布局,不过你可以参考我的评论form布局。

    第一步,在主题的comments.php中,找到评论框合适的位置,添加gravatar预览:

    [code lang=’php’]

    echo get_avatar($id_or_email, ’32’); ?>

    [/code]

    第二步,仍旧在comments.php中,给email输入的input绑定blur事件,在其失去焦点的时候更新gravatar头像预览:

    onblur="updateAvatarPreview(this.value)"

    第三步,下载Paul JohnstonJavaScript md5脚本,放在网站中合适的目录(我是放在当前主题的scripts子目录中)。

    第四步,修改主题的header.php文件,在head标签内加入如下代码:

    [code lang=’php’]


    [/code]

    is_singular函数在当前页面为单篇文章、单个页面或者单个附件的时候返回true,这些一般都是有评论的页面,所以正好合适。而另一个条件 (!$user_ID) 则是因为有用户登录的时候,不需要填写Email,也就不需要客户端更新的代码了。根据email的md5 hash值生成图片链接的代码,在末尾加了个参数”s=32″,是指定头像的大小,这个可以参考gravatar的官方说明

    JavaScript代码中要根据“avatar-preview”这个id来找到头像的预览并且更新它,因此这两个地方要统一。另外md5的JavaScript文件位置也要和引用的url统一起来,这样才能成功调用。

    开始的时候考虑了一下要不要做成插件形式,想了想,评论框的修改还是得手动修改才够灵活,于是作罢。谁要是自己做主题,也可以按照这个教程把这个功能添加上。如有不清楚的地方,请在下面留言。