Archive for the 'Blog' Category

Feedsky新版

欣欣上周MSG我让我看看Feedsky的新版,初一看,吓了一大跳,ASP.NET竟然变成了PHP,这个变化实在不小。且不说这两种技术孰优孰略,看来Feedsky是下了功夫要重新架构一番。
首先,界面比以前清爽整洁了许多,也规范了很多。其实我在Feedsky刚出来的时候就注册了一个,不过一直没有公布,其中的一个原因就是用户名和密码的输入框大小不一样(还是没对齐?忘了),虽说是小问题,但是这样的小问题往往能反映一个团队的实力和态度。细节决定成败!
再说功能上的减法,确实,烧制和统计是RSS Burner的两个最基本也是最重要的功能,Feedsky删除了不少用处不大的噱头,这样挺好,减少了系统的复杂性。问题是,现在没有原因让我放弃Feedburner而转而使用Feedsky,因为没有特殊的地方。差异化生存,作为一个后来者,更要有超越前者的优势才行。加入本地Service(比如豆瓣,土豆)合烧是最容易想到的一个可以改进的地方。
Crawler的问题解决了,访问的时候已经带上了ETag,没有仔细分析Log,不知道对于其它Feed Platform应该遵循的规范考虑了没有。URL的重新设计也更加合理,feed.feedsky.com/user明显比www.feedsky.com/user更好。
团队Blog,终于加上了,这可以Web2.0服务的标志啊:P。我订阅了Feedburner的Blog,可以感觉那是一个充满激情,而且技术非常优秀的团队,希望欣欣和他的同事也能Build up一个这样的团队。
最后说说一些问题:

还是一些细节方面,比如Login.php Load出来后,焦点应该放在Username输入框;
Feed预览,显示英文是"an RSS feed powered by Feedsky";
比较严重的问题,登陆页面没有采用HTTPS。对于WEB应用,如果不能很好的保护PII(Personal Identity Information),一切都明文的传来传去,非常危险;
安全设计考虑的还不够,比如,举两个简单的例子。第一,Login的时候,输入不存在的用户名,会显示"对不起,用户不存在",输入存在的用户名和密码,会显示"登陆失败!",有时候,给用户的信息不是越Detail越好,登陆系统就是这样的例子。因为给用户信息的同时,你也把这些信息暴露给了Hacker,通常的设计要求,这时候的信息要尽量简单一致(Generic Error Messages),尽量少暴露系统信息;第二,连续N次Login错误后,没有任何方法加以限制。通常常用的方法是增加图形验证界面,或者甚至禁止继续试探。
功能上,Burn后还不能完全按照时间排序。

总的来说,还是不错的,希望Skyer们越做越好,也正好公布一下我的Feedsky的Feed:http://feed.feedsky.com/dreamwords。
Popularity: 74%

Popularity: 74%

Subscribe My Most Popular Post

还是在上周末的时候,看到了Microsoft RSS Team的SLE(Simple List Extensions)扩展。三个单词中,最重要的是List,SLE主要是用来解决Feed订阅阅读模式的某种特定需求而产生的:

Treat Feed as List
Define customized sorting functions
Define customized filting functions

从订阅者的角度来说,订阅了这种Feed,本地的Feed列表将完全和Feed服务器提供的保持同步。这种同步包括几个方面:

Feed Item的次序与服务器上完全相同,如果有更新,则Feed Reader也会更新顺序
Feed Reader不会缓存过期的Feed Item,如果某一个Item从Feed中删除,本地Feed Reader也会将它从本地(或者在线Feed Reader Storage)删除。

简单的说,你通过Feed Reader看到的Feed应该与Feed Publisher发布的完全一致。
这种特定应用的需求会有很多,比如典型的几种应用:

Top 10 Best Seller - 比如Top 10 畅销书籍,Top 10 Music等等,对这种Feed的关注通常是更加关注于当前那10个;
Wish List - 如果我已经得到了某个东西,就会把它从SLE中拿去,这样,订阅了我的Wish List的人也就不会再看到这个,不会送重复的东西了:);
Open Positions - 当前职位列表,过期的职位通常意义不大。

可以看到,这些应用都有一些共同的特点,就是Feed本身更倾向于一种通知(Notification),过期的Item意义不大,而且,通常,这个List本身的次序是很重要的。
Specification很简单,通过以下这个声明来确定某个Feed是否是SLE(支持RSS2.0 & Atom),下面是一个RSS 2.0中的例子:
<rss version="2.0"  xmlns:cf="http://www.microsoft.com/schemas/rss/core/2005">
  <channel>
    <cf:treatAs>list</cf:treatAs>
    <title> Top 10 Popular […]

Popularity: 66%

Trackback, Pingback & Backlink

今天看到王建硕的文章《如果过得去那个临界点》

做Ping,需要发的人要支持,收的人也要支持,这种分布的方式的唯一问题是,你需要很多人的协作。不是每个人都愿意协作的,圣经里的通天塔Babel就是一种努力。这就形成了网络外部性--就像一个对讲机没有用,多个才有用处。
网络外部性的东西(email, TCP/IP协议,MSN Messenger,电话)必然需要强大的外因(或者极好的运气),才可形成,但一旦形成,就会病毒性复制。
这个就像核反应堆。谁有能力击破第一个原子,以后的事情就不用你管了。这个点,有人叫做引爆点(tipping point),有人叫做临界点(Critical Mass)。
所以,搜索引擎不需要被爬的网站的配合,就可以工作,所以成功。如果依赖于别人的ping, 就像有了C2C的交易平台,却没有那足够市场经费(这是一种办法),或者经过几年的积累(这是另外一种做法)轰击原子核,很难达到Critical mass。这个和技术无关无关了。

不久前曾有过一场关于Trackback是否会死去的大讨论,我也恰巧想过这个问题。于是,昨天仔细看了Trackback,Pingback,以及Backlink。
从使用的难度来说,Trackback > Pingback > Backlink。Trackback的使用方法实在太过Geek,你需要到对方的Blog上找到Trackback
URI(虽然Trackback支持Auto-Discovery,但是真正用的似乎并不多),然后把它Paste到Blog软件的Trackback
Field里面去,我觉得,这个过程对于普通用户来说绝对不可忍受。即使你做到了这点,不同Blog程序间标准的不统一,对国际化支持不佳,使得Trackback的送出是如此之难。
相比之下,Pingback要好很多,如果你的Blog软件和对方的Blog都支持了的话,用户什么都不需要做。比如WordPress,会自动的向文章引用的每一个URL发送Pingback,当然,只有对方支持才会Ping成功。支持Pingback的Blog程序也很多,包括WordPress,Dupral,其它像是MSDN
Blog也都支持(用的是.Text?)。
这里废话一下Pingback的实现,其实很简单,每个客户端负责对指定的URL发送Pingback。而服务器端有两种办法来提供Pingback的地址:HTTP Header和Link Element。

HTTP/1.1 200 OK
Date: Sun, 08 Sep 2002 15:05:37 GMT
Server: Apache/1.3.26 (Unix)
Last-Modified: Thu, 28 Dec 2000 03:18:26 GMT
ETag: "65044-15b9c-3a4ab102"
Accept-Ranges: bytes
Content-Length: 88988
Connection: close
Content-Type: image/png
X-Pingback: Pingback Server URI

<link rel="pingback" href="Pingback Server URI">

可惜,标准总是好的,现实总是残酷的,并不是每个人都愿意遵循标准。显然,Trackback的提出者MT就不愿意支持Pingback。因此,我认可建硕说的,“当一件事情有赖于多于一个人的努力才能成功的话,他成功的可能性就小很多”。
这样看下来,Backlink就是最简单的了。如果你不知道什么是Backlink,就去看看Google的官方Blog。哦,对,这个。。。,那就拿Google中国黑板报来说吧,每篇文章后面会有一个“引用此贴的链接:”,就好比MT中Trackback到此篇文章的链接一样。下面列出的是一些链接到这篇文章的Blog。看看代码,你会发现,其实很简单:
<script
 type="text/javascript" src="http://www.blogger.com/dyn-js/backlink.js?blogID=20904277&postID=113976536783718339" defer="true">
  </script>
 
  <noscript>
  <a href="
http://search.blogger.com/blogsearch?q=link:http%3A%2F%2Fgooglechinablog.com%2F2006%2F02%2Fgoogle.html">See links to this post</a>
  </noscript>
正是Google Blog Search中的反向链接查询结果。
就像建硕所说的那样,搜索引擎不需要被爬的网站配合,就可以自己工作。有的时候,与其花费时间去推广一个标准,真的不如另辟蹊径,去找执行力更好的解决方案。
我觉得,无论从实现者的角度,还是从最终用户的角度,Backlink都是最简单的,事实上,他也确实成为我现在查看Backlink,进行Ego
Surfing的主要工具了。
还有,如果你希望Backlink成为文章的一部分,要展现给读者,那么就学习GoogleChinaBlog吧。Google Blog Search提供了Backlink的RSS,然后再用RSS -> […]

Popularity: 69%

coComment Preview

一直希望有一个很好的Comments解决方案,帮我解决以下几个问题:

帮我追踪我所有的留言,记录这些留言的痕迹;
更进一步的追踪这些留言的Post,来看看Blog的主人对我的留言有什么反馈。

有一段曾经用Trackback来解决问题,这样做的结果是只有长篇大论才被记住,很多一两句的留言就不自觉地放弃了,反正也无法跟踪反馈 :P。久而久之,积极性越来越低,已经很少留言了。
Herock曾经建议采用社会化书签来对留言进行统一管理,可是关键在于,Bookmark下这些URL只是一些静态的信息,留言的组织和追踪还是靠你自己,还是很麻烦。
这两天偶尔看到coComment这个服务,看起来能够帮我解决我所面临的问题,就想试试。昨晚留下了Email,没想到一早就收到了invitation code。
用起来说简单也简单,说复杂也复杂,需要你在Browser中添加一个Bookmarklet,在点击留言提交的按钮前,点击这个Bookmarklet,然后点击的时候就同时把留言提交到coComment去了。
简单看了一下它的Bookmarklet代码,发现它是根据各种Blog系统的特征找到Comments的Form,然后在这个Form的提交Button后面添加一个个人信息的Logo,然后在修改Form的提交部分,让留言同时提交到coComments去。
看了一下代码,现在支持的Blog系统包括:
xanga.com
myspace.com
msn.com
blogger.com
typepad
blogs.com
wordpress.com
kaywa.com
这种做法够Hack的,不过想想也没办法。本来最好的办法是弄一个标准,然后大家都按照这个标准把留言Ping到某一个服务,不过,这似乎是不可能的,于是,就Hack这个提交的Form了。
不过,这种太过Geek的做法能够被普通用户所接纳么?我很担心。
最后的Conversation组织的不错,Fancy,而且也提供RSS来让我追踪我留言的各条Post,目前还没有收到更新,只能看看再说了,呵呵。对了,还提供Share的功能,把自己的留言Share出来。
还有,就是要提两个意见:

能不能做的更彻底一点儿,点击这个Bookmarklet的时候能自动帮我填留言的Form呢?我指的当然是Name,Blog这些信息,可以把它存在coComments的帐户里面。
把针对各种Blog系统的模版尽量抽象,然后提供一个可以方便扩充的Plugin机制(或者叫做Provider,Add-on),毕竟,coComments根本没精力提供所有系统的Comments模版,可以把这些工作留给社区来做,比如,吉子就可以做一个针对Sohu Blog的,嘿嘿。

Update:

简单测试了一下,发现coComment只能追踪同样是通过coComments服务的留言,不爽,不过也没有太好的办法,除非各家都提供自己的Comments RSS;
昨天用的时候就像可以写一个GreaseMonkey的脚本,来自动干这件事儿,结果这不,今儿就有了,这下更方便了;
还有一点想说的就是,这个服务的一个让我用的原因就是他不会让你失去什么,你的留言只是拷贝了一份在他那儿,所以,得到的就算是赚得吧。

Popularity: 54%

Popularity: 54%

IE7 Beta2 Preview

距离上次装Beta1已经有半年的时间了,这半年,用IE的时间大大的增加,不舍Firefox的主要原因是开放的架构和丰富的插件。
昨晚装上了IE7 Beta2试了试(这回也是英文版,不过不需要像上次那样Hack了:P),注意到一些细小的地方,比如:

上次的CSS Fixed的问题得到了解决;
Tab上的Close按钮(据说这是得到了Blog中的反馈而加上的功能);
Alt键开/关菜单;
Quick Tabs预览,这个太Cool了(估计Firefox会很快出来类似的插件吧);
"Delete Browse History"(虽然是已有功能的汇总,不过这个功能应该会有很多人需要);
Full Screen的处理非常好,比Firefox的处理更加方便和人性化;
Search Engine中默认为MSN Search,不过可以很方便的设置为Google或者其它;
Native XMLHTTPRequest Object的支持,这样,今后写AJAX代码不用再区分浏览器了。

最让我印象深刻的是IE Blog这次的宣传攻势:
Native XMLHTTPRequest object - IE7中对XMLHTTPRequest的Native支持
Frequently Asked Questions for the IE7 Beta 2 Preview - IE7中的常见问题
Windows RSS Platform - RSS的支持,期待API的公开
Security issue in IE7? - 第一个漏洞?
A New Look for IE - IE7 UI的变化
Part 1: Hello feeds - 对Feed的支持,Feed Reading Page不错,非常方便
Part 2: Discover and Subscribe to […]

Popularity: 59%

升级到WordPress2.0后,只有少数插件遇到了问题,都与Permalinks有关。不过,最近发现,SK2也有些问题,留言数目总是0,今晚有时间Debug了一下,发现WordPress2.0中”wp-posts”表里面新增了一个”comment-count”字段,这其实是”wp-comments”中取出的这个Post所有留言之和。之所以做这样违反范式的冗余设计,应该是效率上的考虑。这就带来了更新上的问题。SK2做的时候当然不会知道这个,所以就带来了问题。
发现了一个SK2的插件,用于解决这个问题 - SK2-WP2Compatibility (注意,这是SK2的插件,而不是WordPress的插件,有时间我要研究一下SK2的插件机制)。这个插件很简单,看看代码就知道了。
$c = $wpdb->get_row( "SELECT count(*) as c FROM {$wpdb->comments} WHERE comment_post_ID = ‘$cmt_object->post_ID’ AND comment_approved = ‘1′" );
if( is_object( $c ) ) {
$this->log_msg(__(" Wordpress 2.0 detected - going to update comment counts" ), 4);
$wpdb->query( "UPDATE $wpdb->posts SET comment_count = ‘$c->c’ WHERE ID = ‘$cmt_object->post_ID’" );
}
不过,SK最新的2.1版本中已经解决了这个问题,所以,只需要升级到SK2.1就可以了。
Popularity: 35%

Popularity: 35%

升级到WordPress2.0

前两天升级到了WordPress 2.0,可惜Jerome’s Keywords不能正常工作,点击会出现404的错误。看了一下代码,发现WP2.0对底层Permalinks的实现作了很大的改动,郁闷。正巧看到有人推荐Ultimate Tag Warrior,决定元旦的时候换一下。昨天下午把这个插件推荐给Robin,没想到这家伙手脚真快,晚上就升级了。结果今天早晨来就看到Jerome’s Keywords升级到1.9,兼容WP2.0,呵呵。
Update:  同样是由于Permalinks的原因,WordPress Feedburner Plugin的作者也给出了最新的版本。
昨晚升级的时候看了一下Archives,这两个月的Post真是少得可怜,忙是一种借口。手头想干的事情很多,却还都没有开始或者进展缓慢,还是得给自己加油 。
Popularity: 34%

Popularity: 34%

Flock

今早收到Flock的邀请,下了一个体验一下。
Flock最大的特色就是加入了对Delicious, Flickr, Blog等社会化软件的支持,将他们集成到这个浏览器中。
1) Delicious
Flock的Favorite管理默认就是采用Delicious,第一次导入需要的时间长一些,这样,可以直接用Favorite中的”Star and Tag …”将你感兴趣的内容贴到Delicious上面去,不过我觉得原来的Bookmarklet也很方便 :P。

2) Flickr
试了一下,可以把Flickr的图片拖入到Blog Editor窗口中来,确实挺方便。

3) Blog
很简单,还是利用开放的XML-RPC接口,来远程的进行Blog发送,并且支持Ping到Technorati的Tag。
总的感觉是像一个装了各种社会化插件的Firefox,这些确实都是我平常经常用到的,其实原来的Firefox + Extension + Bookmarklet已经能很好的满足我的需求,不知道能不能用起来这个浏览器。

Technorati Tags: Flock, Firefox, Delicious, Flickr, Browser

Popularity: 34%

Popularity: 34%

一直用Stattraq插件来统计Blog的访问信息,使用起来还不错。后来发现,我的Blog上很多关键词都是来自Baidu,而Stattraq根本没有对Baidu的特殊处理,于是Hack一下,让Stattraq也能统计百度的信息。
1)BaiduRobot
在"stattraq.php"的函数"statTraqGetBrowser"中,添加对Baidu Robot的识别(顺便也识别一下Sogou的Robot吧):

<?php
}else if(strpos($ua, "Baiduspider") !== false){
        $browser_type = ST_BOT;
        $s_id = "Baiduspider";
        return "Baiduspider";
    }else if(strpos($ua, "sohu-search") !== false){
        $browser_type = ST_BOT;
        $s_id = "SogouBot";
        return "SogouBot";
    }
?>

原理很简单,就是分析HTTP头中的"HTTP_USER_AGENT"信息,负责任的搜索引擎都会给出自己的标志,比如Google的"Googlebot",MSN的"msnbot"等等,对于那些把自己伪装成浏览器的搜索引擎,不统计也罢。
一个需要注意的问题是大小写不能搞错。
然后再修改一下"stattraq-install.php",主要是为了今后的升级:
<?php
$sqlQuery = "UPDATE {$tablestattraq} SET user_agent_type=1
        WHERE browser = ‘Googlebot’ OR
            […]

Popularity: 56%

Dissect WordPress Themes

还是想用Nat在OOS上的一段话来作为开头:

You have to give people work to do.
Create an “architecture of participation” as Tim O’Reilly says.

要想真正成功,必须能够提供一个可以供人参与的架构,Eclipse如此,Firefox亦如此。与Plugin一样,WordPress中的Theme机制也非常灵活和强大,社区贡献出的一个个漂亮的Theme都是这个良好架构下的杰作。
1)读取系统中所有可用Themes
<?php 
function get_themes()
?>
这个函数用来从文件系统得到所有的Themes。首先列出’wp-content/themes’的文件夹,然后跳过”.’、’..’、’CVS’(跳过CVS目录,这个在Xerdoc DSearch的Theme中也遇到过,因为都是采用CVS进行源码管理 :-)):
<?php 
if ($theme_dir{0} == ‘.’ || $theme_dir == ‘..’ || $theme_dir == ‘CVS’) {
    continue;
}
?>
然后会判断每个目录中是否有Stylesheet ’style.css’文件,如果有,列为Theme候选目录,否则加入到’$wp_broken_themes’中。
接下来,就利用函数
<?php 
function get_theme_data($theme_file);
?>
来从’style.css’中提取Theme的描述信息,包括’Theme Name’、’Version’、’Author’等等。同WordPress中的插件类似,这些描述信息是存在’style.css’中的。
<?php 
Theme Name: WordPress Default
Theme URI: http://wordpress.org/
Description: The default WordPress theme based on the famous Kubrick.
Version: 1.5
Author: Michael Heilemann
Author URI: http://binarybonsai.com/
?>
第三步,需要判断命名冲突。这种情况发生的原因是:将一个Theme拷贝,然后做修改,可是Theme的Descriptor并没有修改。可见,WordPress在人性化上真是做足了功夫,值得学习。
这样,合格的Theme就读取完毕了。不合格的Theme会被放到"Broken Theme"这个Section中,需要重新进行修改才能使用。
2)更换Theme
更换Theme很简单,先来看看当Active一个Theme的时候我们所Access的URL:
http://localhost/blog/wp-admin/themes.php?action=activate&template=sixties-datetitle&stylesheet=sixties-datetitle
同Plugin一样,Active Theme的信息(其实就是目录名称)也保存在数据库中。但是需要存两项,分别是"template"和"stylesheet"。这是为了处理Style的CSS文件与模板文件(比如index.php)放在不同目录的情况。
<?php 
if (isset($_GET[’template’])) {
    update_option(’template’, $_GET[’template’]);
}
 
if (isset($_GET[’stylesheet’])) {
    update_option(’stylesheet’, $_GET[’stylesheet’]);
}
?>
3)Theme的加载
首先看看我们访问WordPress的过程。当我们访问’http://yoursite/blog/’的时候,访问的是’index.php’文件:
<?php 
define(’WP_USE_THEMES’, true);
require(’./wp-blog-header.php’);
?>
在’wp-blog-header.php’文件中,可以看到下面的重定向过程:
<?php 
// Template redirection
if ( defined(’WP_USE_THEMES’) && constant(’WP_USE_THEMES’) ) {
    do_action(’template_redirect’);
    if ( is_feed() && empty($doing_rss) ) {
        […]

Popularity: 53%


Creative Commons License
This work is licensed under a Creative Commons License.

那一年你正年轻,总觉得明天肯定会很美,那理想世界就象一道光芒,在你心里闪耀着