blog如何赚钱?

本来赚钱和盈利是两个概念,赚到钱了不一定就能够盈利,而盈利不见得就只有赚钱这一种方式。可是高调唱完了,blogger们还是会回到原点:从哪里补贴服务器费用?从哪里补贴所花费的时间和精力?写blog难道就只是一种娱乐么?难道除了自娱自乐或者是写写枪文,就没有其他方式么?

虽然keso比较反感付费话题,代表了一部分人的观点,可是别忘记了那后半句话“没有钱是万万不能的”,本来我们的口粮就不多,理想化的东西恐怕都要打折销售了。

原来的reviewme没赶上,现在的feedsky也没兴趣,倒是这个 Bloggerwave算是我的第一把,虽然没有太多特色,目前的赞助机会也比较少,但是要求不高,形式也简单,最方便的是直接付款到paypal,10块美刀好歹也够一个域名一年的费用了,干嘛不试试呢?

另外付费评论如何“写”也是个值得研究的话题,让你写什么就写什么那太笨了,但如果让你写产品,你就来个横向评测,让你写网站你就写写相关现象,我想不但起到了宣传的作用,对blog文章质量的影响也会减少一些。当然如果你本来是写IT的blog,非要去宣传谁家的苹果好卖,还是先三思的好。

FeedBurner不认我的Feed了

突然发现,我最近写的几篇文章都没有被rss阅读器收录,以致于我也无法用email转发到其他镜像上去,本来以为是FeedBurner等网站访问国内受阻,今天无意中使用FeedValidator检查才发现,无法访问我的feed!同时,GoogleReader也无法访问,看来真的是出问题了。

FeedBurner的错误提示为:

There is an issue that must be addressed with your source feed for the feed "Fwolf's Blog"

Read timed out

FeedValidatorW3C的feed检查工具(似乎W3C使用的是FeedValidator的开源程序,可以在这里下载,同时在sf.net上也登记了,不过没在上面发布文件),都会返回超时错误:

Server returned timed out

偶尔还会返回更离谱的错误信息:

Server returned (104, 'Connection reset by peer')

让我有一种自己的网站被封锁了的感觉(封锁是双向的,出国访问和从国外访问国内都受影响)。

GoogleReader的错误提示:

No feed available for "http://www.fwolf.com/blog/feed"

开始查找错误的原因,首先看看是不是被封锁了的原因,使用匿名web代理http://anonymouse.org/anonwww.html能够访问,从DreamHost主机上wget也能成功,排除被封锁了的可能。本来我写的内容也不应该会被封锁嘛,那是不是FeedBurner服务器的问题呢?有这个可能,但我没法实验去。

分别把AkismetSpam Karma 2等反spam插件停止,问题依旧,说明不是被anti spam程序阻止的问题。

是不是WordPress的问题呢?记得WP 2.0.6曾经和FeedBurner有过冲突,参见:

不过我现在用的版本是2.1.1,应该没有上述问题,不过还是排除一下的好,把WP升级到了最新的2.1.3版本,问题依旧,初步排除WP自身的问题。

是不是升级之后,.htaccess简化网址的配置文件出问题了?但是我分别用FeedValidatorFeedBurner检查RSS Feed的直接网址http://www.fwolf.com/blog/wp-rss2.php,依然都是超时错误,排除。

是不是php执行出了什么错误了呢?在php的errorlog文件中我发现了:

[04-May-2007 19:45:27] PHP Fatal error:  Maximum execution time of 90 seconds exceeded in D:\fwolf\wordpress\wp-content\plugins\markdown.php on line 1761

不过我直接用浏览器访问我的Feed是可以的,应该也不是php的问题,不然我的blog应该整个显示不正常才对。

继续探索,发现了更离奇的事情,在apache的access.log中我发现如下记录:

66.150.96.109 - - [04/May/2007:20:12:13 +0800] "GET /blog/feed/ HTTP/1.1" 200 24315 "-" "FeedBurner/1.0 (http://www.FeedBurner.com)"

208.97.167.25 - - [04/May/2007:20:14:14 +0800] "GET /blog/feed HTTP/1.0" 200 86896 "-" "Wget/1.9.1"

67.19.173.84 - - [04/May/2007:23:16:44 +0800] "GET /blog/feed/ HTTP/1.1" 200 24315 "-" "FeedValidator/1.3"

这说明FeedValidatorFeedBurner都确实访问到了我的服务器,可他们怎么还是会超时呢?从浏览器访问的时候,虽然不是很快,但也没有30秒、60秒那么长,应该不会超时的。不过为了确认一下,找了一篇文章的comment的feed:http://www.fwolf.com/blog/post/310/feed,结果就可以通过检查:

Congratulations!

[Valid RSS] This is a valid RSS feed.

会不会是没有返回文件大小的原因?在wget的时候会看到:

HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/xml]

FeedBurner只允许小于512k的feed,如果服务器不返回文件大小,FeedBurner就会中止操作?我试着返回一个伪装的文件长度,在wp-rss2.php中添加header("Content-Length: 10000");,这样用wget只能下载10k的内容,但是feed检查工具仍然报timed out错误。

无奈,只好给FeedBurner反馈意见,虽然是5.1休假期间,还是很快就收到了回信,大概说仍然是网站响应速度太慢了的问题(我从其他搜索得知限制大概是10秒以内),除了提升响应速度之外,暂时没有其他解决办法。

精疲力尽,忽然禁用Markdown Extra这个plugin之后,居然没问题了,看来还是响应时间的问题,Markdown Extra用到了太多的正则替换,加上最近写的几篇文章都不算太短,服务器响应略微慢了一些,加上中国到美国的数据传输时间,怪不得会超时呢。我也是疏忽了,上面的access.log和php的errorlog,都多少有些提示,但我没有注意到。

虽然定位了问题所在,但Markdown Extra还是要用的,没了它我写文章的兴趣会减少一大半,好在WP可以调整RSS中输出的文章数量(Options->Reading->Show the most recent: ? posts),我试了一下,默认是返回10篇,不过会超时,调整到7篇的时候就不会超时了,为了保险起见还是设置为5好了。希望网上的抓FEED机器人不要太懒,免得把文章跳过去喽。

几点感受:

  1. 发现问题之后,要善于寻找原因,不能盲目瞎摸,有些问题不找到根源,重试一万遍也不会改变,还是要一层一层的反复分析、排除。

  2. 如果在程序中要大量用到Markdown语法的话,为了提高速度,可以采用空间换时间的方法,除了保存原文之外,把解析的结果也存一份,这样访问速度快。

  3. 作开发的时候对速度考虑的优先级要提高,10秒就超时啊,怪不得我不适应,被铁通蹂躏惯了。。。

顺便推荐一个不错的在线工具:

WordPress 插件编写简例

虽然市面上有很多 WordPress 的插件,但未必能够满足我们那些稍微“变态”一些的需求,所以,参照wp官方的插件编写指南,写下这个简单的说明和小例子,希望对大家有所帮助。

插件编写需要php的基础知识,并且本说明的内容大多只适用于wp1.5以后版本。

插件程序建议放置在wp-content/plugins/目录,如果有多个程序文件的话,可以在这个目录下建立子目录,程序所需的资源文件建议也放在这个目录下,便于更新和管理。

wp插件主要分为两种:

  • Action 对wp的行为事件进行修改,比如修改数据库,发送邮件或者修改显示结构等。
  • Filter 对wp的输入输出内容进行修改。

在本例中,我们将建立一个简单的Filter插件,替换wp本来的文章摘要生成功能,把以前手工修改代码实现的内容,用插件来替代。

wp推荐在插件程序中加入这样的文件头,便于wp辨认插件的信息,就像下面这样:

<?php
/*
	Plugin Name: 插件名称
	Plugin URI: http://插件网址
	Description: 插件说明
	Version: 插件版本
	Author: 插件作者
	Author URI: http://作者网址
*/

插件的代码风格主要是基于过程方式的,所以要尽力避免函数重名,可以在函数名之前加上自己的名称前缀,也可以把自己的类包含在一个类当中,不过小型插件还不至于复杂到要使用类的程度吧?

函数的编写就是php代码了,注意Filter一定要返回数据,即使没有修改也要返回,不然后续的其他函数就没法干活了。更多的信息可以看官方的插件api

编写完成之后,函数是不会自动执行的,wp为插件函数的执行提供了一种hook机制,就是在原始的wp程序中,预置了一些hook或者叫挂载点,通过把插件函数挂在这些hook上,就可以被执行,目前wp提供的挂载点一览见Hooks列表。

针对我编写的函数,是要挂在生成文章摘要的地方,查找了一下Hooks列表,发现和摘要(excerpt)相关的有:

default_excerpt 
excerpt_edit_pre
excerpt_save_pre 
get_the_excerpt
the_excerpt

从名称可以看出,default_excerpt是文章的默认摘要,excerpt_edit_pre和excerpt_save_pre是编辑文章是对摘要进行的预处理,get_the_excerpt是取摘要,the_excerpt是返回摘要。我编写的是生成摘要的功能,应该挂在get_the_excerpt或者是the_excerpt上,考虑the_excerpt可能更“底层”一些,挂在这里。

挂载的语法也是一个php函数调用,格式如下:

add_filter('hook_name', 'your_filter', [priority], [accepted_args]);

priority为优先级,默认为10,数字小的会先执行;accepted_args为参数个数,默认值为1,如果插件函数需要多个参数的话需要自行设定。这两个参数在使用默认值的时候都可省略。

基本上有这些就够了,我的插件程序完整代码如下:

<?php
/*
	Plugin Name: Excerpt Trimmer
	Plugin URI: http://www.fwolf.com/
	Description: 替换wp本身的“摘要”生成功能,用于在列表或者查询页面显示文章部分内容。
	Version: 1.0
	Author: Fwolf
	Author URI: http://www.fwolf.com/
*/
 
function fw_excerpt($text)
{
	$excerpt_length = 4;
	$words = explode("\n", $text, $excerpt_length + 1);
	if (count($words) > $excerpt_length) {
		array_pop($words);
		array_push($words, '<p />......<a href="' . get_permalink($post->ID) . '">[阅读全文]</a>');
		$text = implode("\n", $words);
	}
	return $text;
} // end of func fw_excerpt
 
add_filter('the_excerpt', 'fw_excerpt');
?>

可以看出插件程序也就是由上面介绍的3部分组成:文件头,函数体,挂载声明。

其实就简单插件来讲,最关键的是找对相应的hook,这就要靠经验和摸索了,wp官方文档好像也没有对每个hook作出详细的解释。

现在,把我这个插件程序保存为wp-contents/plugin/excerpt.php,登录wp,进入plugin设置,就能够看到“Excerpt Trimmer”插件了,启用之就大功告成了。我还存了一份在这里,方便下载。

blogger无法正常发布文件到blogspot的问题

大概2003、2004年我就注册了blogger帐号,具体时间记不请了,不过我的gmail帐号就是从这里来的,后来有人宣传blogger可以自动发布到sitesled,而blogger还支持邮件发布,反正我的blog内容也会用邮件订阅到自己的邮箱,所以我就在sitesled开了个分店,一直正常使用。

后来,blogger又搞了个beta,我也去趟了趟混水,不过这次没有用ftp发布,而是直接发布到blogger的blogspot上了,这就形成了第二个分店

由于自己的blog一直是在独立域名和空间上挂着,所以这些分店偶尔会少个一两篇文章我也不怎么在意,可是当blogger的beta结束之后,blogger改用了google account帐号登录,我的两个分店也都整合到了一个blogger帐户下,不仅邮件发布地址冲突了(已经更正,没事了),我还发现sitesled的分店就能够正常发布文章,而blogspot分店在beta结束之前没事,beta结束之后就无法正常发布文章了。

逐项进行检查,邮件发布地址没问题而且不冲突、不重复,转发邮件也没有退信,都正常发出去了,问题出在哪儿呢?碰巧gfans上也有人反映blogger发布的问题,于是乎我把两个分店的设置逐一对比,终于找到了问题所在。

在能够正常发布的sitesled分店设置页面,“格式设定”中的时区和语言都是中文,而无法正常发布的blogspot分店,“格式设定”中的时区和语言都是英语,所以把他们更改为中文和香港时间东8区,再次发送邮件,果然能够正常在blogspot发布了。

简单猜测一下原因,是不是blogger在生成发布页面的时候,针对用户所设置的语言来生成页面文件,虽然目标文件是utf8格式的,但是文字内容需要经过从邮件中解码、un-base64等计算,再转换为utf8,如果用户语言设置错误的话,在这些转换的过程中会出错,所以文章根本就没有存到blogger当中,更别提后续的发布操作了。

我还联想到,同样是gfans中有人问,google的spreadsheet&docs生成的pdf文件,中文怎么无法显示或者乱码呢?这个的原因应该就简单了,因为在我们伟大祖国的it领域,没有一款免费的中文矢量字库,google显然不会用盗版,安装windows系列服务器也不现实,所以,生成的pdf中自然就没有中文的身影了,这一点和linux下有些应用程序生成的pdf文档中的中文是一样的情况和道理。

Update @ 2007-02-24 好像还有其他的问题,当文章转发到多个邮箱的时候,blogspot分店的邮箱在最后一个,不工作,而单独转发到blogspot分店的邮箱的时候,就工作了。另外把发布邮箱地址”Fwolf@Blogger” <fwolfcn.secretcode@blogger.com>里面的”Fwolf@Blogger”更改为”Fwolf @ Blogger”(@前后添加了两个空格),是不是这个原因呢?结果要到下次再发布文章的时候揭晓了。

如何为网站添加sitemap文件

什么是sitemap?简单的说,就是一个xml文件,定义了你网站“主要栏目”的结构,以方便搜索引擎更好的建立索引和抓取文件。是对一些从其他页面不怎么链接得到的页面尤其有用,更详细的信息可以查阅Wikipedia上的说明

Google是支持sitemap的,Google帮助中的How do I create a Sitemap file?一文列举了一些生成sitemap的方式和工具,我采取的是第一种——sitemap protocol方式,详细说明在这里,英文好的朋友可以直接去啃,不用看我在下面罗嗦了。

第一步,准备工作

由于Google Sitemap Generator是使用python语言编写的,所以需要python 2.2以上的版本支持,其余的要求如要有文件的访问权等等不再详述。由于我的操作系统是Ubuntu,所以python支持也没问题。

http://www.sourceforge.net/project/showfiles.php?group_id=137793&package_id=153422下载Google Sitemap Generator的程序文件,在本机建一个目录把它解压缩。

第二步,创建配置文件

把刚才解压缩得到的example_config.xml文件另存为config.xml,并编辑之:

<site base_url=”http://www.example.com/” store_into=”/var/www/docroot/sitemap.xml.gz” verbose=”1″ >

其中base_url是网站地址,store_into是sitemap文件的地址,最好使用绝对路径,于是上面的内容修改为:

<site base_url=”http://www.fwolf.com/” store_into=”/home/fwolf/sitemap.xml.gz” verbose=”1″ >

接下来修改** MODIFY or DELETE **开头的sitemap生成方式定义部分,要删除掉不打算使用的生成方式,按照xml语法标签来分,生成方式有以下几种:

  • url,网页地址,附加定义为最后修改时间,更新周期,优先级,个人认为这种方式比较麻烦。
  • urllist,通过一个包含网页地址列表的文件,可以定义文件优先级,个人认为这种方式还不如直接使用urllist文件省事。
  • directory,文件地址,附加定义为文件、对应网址、默认索引页,个人认为这种方式比较适合我们,因为在本机一般都会有一套比较完整的网站文件,用他们来生成sitemap再合适不过了。
  • accesslog,网站日志文件,有必要么?
  • sitemap,sitemap节点文件,主要用于把多个分散的sitemap文件集合起来。

在这里我们删除掉其他的方式,只保留directory方式,并对其进行修改,结果如下:

<directory path=”/home/fwolf/website” url=”http://www.fwolf.com/” default_file=”index.html” /> <directory path=”/home/fwolf/website/wordpress” url=”http://www.fwolf.com/blog” default_file=”index.php” /> <directory path=”/home/fwolf/website/bnt” url=”http://www.fwolf.com/bnt” default_file=”index.php” /> <directory path=”/home/fwolf/website/dokuwiki” url=”http://www.fwolf.com/dokuwiki” default_file=”index.php” />

注意一般简单的网站只要有一个directory就可以了,但也可以有多个directory段,仅当你的网站是用子目录来划分栏目,也就是对应到本机不一定放在一个目录下调试的情况下才建议使用。可以用default_file来定义首页文件。

接下来修改FILTERS段,索引文件过滤部分。过滤规则是自上而下匹配的,匹配动作action有两种drop和pass,drop明确不索引文件,pass则是索引文件(但也有可能被后面的规则排除),匹配规则type可以是wildcard或者regexp,wildcard是使用通配符*和?来匹配文件,regexp自然就是正则表达式了。注意默认的匹配动作是drop不索引文件,所以要想简单的索引所有文件,这一段留空就可以了。

<filter action=”drop” type=”wildcard” pattern=”*/cert/*” />

这里我只简单的屏蔽掉信息产业部备案文件保存的那个目录,注意pattern是要和完整的网址进行匹配,略微不同于apache conf文件中的rewrite规则写法。

第三步,运行Google Sitemap Generator

很简单,./sitemap_gen.py –config=config.xml 就可以了,生成的sitemap文件会保存在刚才定义的store_into目录中,要想解压缩查看的话,用gunzip -d sitemap.xml.gz解开就可以了。一定要仔细查看这个sitemap文件,并根据它的内容,再去修改config.xml,反复直到满意为止。

最后,登录Google Webmaster Tools提交你的sitemap文件即可。

Google Sitemap Generator生成的sitemap文件中还是存在很多不必要的文件的,比如dokuwiki和wordpress的源文件、说明文档有上千个,手工和用FILTERS来去除我觉得都不是很方便, 所以再介绍一种更简单的添加sitemap的方式,就是纯文本文件,例如:

http://www.fwolf.com/ http://www.fwolf.com/blog/ http://www.fwolf.com/bnt/ http://www.fwolf.com/dokuwiki/

上述内容保存为sitemap.txt,然后上传到网站根目录,就可以到Google Webmaster Tools里面提交了,使用地址http://www.fwolf.com/sitemap.txt,注意每行一个网址,不能有其他任何内容,最好放在网站的根目录下。相对于使用Google Sitemap Generator生成sitemap.xml来说,我觉得这种纯文本文件的方式更简单、实用,包含的内容也更容易控制,应该更适合小型网站使用。

Update @ 2008-07-10

推荐一个不错的WordPress插件,用来管理和生成Sitemap:Google (XML) Sitemaps Generator for WordPress,我现在也在用它。

升级WordPress从1.5到2.0

今天正好有些空闲时间,就顺便把WordPress 1.5升级成了2.0,升级很简单,上传所有新文件,然后吧wp-config.php配置好,把原来旧的theme目录、.htaccess文件等拷贝过来,然后运行wp-admin/upgrade.php基本上就差不多了。

同时还是不要忘记添加mysql要求的set names(文件是wp-includes/wp-db.php):

function wpdb($dbuser, $dbpassword, $dbname, $dbhost) { $this->dbh = @mysql_connect($dbhost, $dbuser, $dbpassword); //加上下面这行 $this->query(‘SET NAMES “utf8″‘);

还有修改一下生成摘要的方式,参见更改WordPress自动生成摘要的方式

一点点使用感受:

  • 默认下载的版本好像没有带新的模板,所以仍然拿原来的模板用上了。
  • 分类Category的链接地址处理和1.5有些不同,2.0可以在链接前面和网站地址之间添加“Category base”,这样分类页面的地址定制就更灵活了。
  • 增加了缓存机制,缓存存在wp-content\cache目录下,如果发现更改设置没有生效,可以清空这个目录试一下。
  • 增加了WYSIWYG所见即所得的编辑器,不过我更喜欢直接控制HTML的感觉,几个简单的b、link、img就足够我用了。
  • Permalink定制的功能更强大和方便了,不过原来我用的.htaccess文件拿来照样能用。
  • 依然会将单引号替换成‘ ’,双引号替换成”,源码中还发现了更多的替换条件。
  • 后台管理界面更好看了,现在的蓝色背景和blogger有点像。
  • 增加了导入其他blog或rss内容的功能,对有些朋友应该很有帮助。
  • 没有了设置上传文件路径的选项,可能上传文件都要存储到wp自己的目录下面了吧。

update @ 2006-8-9 升级wp 2.0到2.04步骤完全相同,升级后启用了Akismet来防止spam。