2007-11
12

这个Wordpress插件可以统计Feed的订阅者,并可以生成类似于FeedBurner那样的条形统计图。 有如下的一些特点:

  • 可以输出FeedBurner样式的统计图;
  • 支持在线、离线阅读器的统计;
  • 可以自定义各种阅读器的UserAgent标识,自行判断某个UserAgent是否为合法的阅读器;
  • 可以生成FeedBurner样式的订阅者数图片。
my-feed-stats.png

安装方法

首先说明,这个插件仅适用于那些没有使用FeedBurner、FeedSky烧制feed的blogger们。 如果你使用了这些烧制服务,该插件将无法统计到烧制后feed的订阅数。

Windows下的安装方法很简单,解压插件到plugins目录下,在控制台中启动插件即可。 Linux下安装方法略为复杂,因为涉及到目录权限的问题,需要一些简单的Linux知识。

另外,本插件由于需要自己定义阅读器的标识符,所以最初安装时无法识别任何阅读器。 为解决这个问题,我在附件中放了一些阅读器的标识符数据,这是我一个月以来积累下的数据, 虽不敢保证很全面,但一般常见的浏览器都在里面。安装插件之后将其导入到数据库中即可。

下面是完整的安装方法:

  1. 解压缩插件到 wp-content/plugins 目录下;
  2. 进入Wordpress管理界面,在“插件”中找到“My Feed Stats”插件,启用;
  3. 利用phpMyAdmin等工具导入插件附带的 mfs_readers.sql。(如果你修改了wordpress的表前缀,请打开mfs_readers.sql并自行修改其中的表名。)
  4. 进入“管理->Feed统计”,设置订阅者图片的路径、颜色和显示的文字。这里图片路径是相对于wordpress根目录的路径,比如设置路径为 a/feeds.png,实际的图片URL就是 http://yoursite/a/feed.png
  5. 如果操作系统是Linux,请设置插件目录下的 feeds-sample.png 的权限为 777,并利用touch命令手工创建上一条订阅者图片的文件(空文件即可),设置权限为777。
  6. 等待一天之后看统计结果吧!

关于版权

本插件的版权遵循GPL,请阅读插件内附带的license.txt文件。

本插件使用的字体文件 terminal6-modified.gdf 来源于 http://www.widgnet.com/gdf_fonts

下载地址

更新

2007/11/15,版本1.0.1:修改插件安装之后feed访问出错的一个bug。


2007-10
31

这两天一直在忙着做一个新的主题,暂且命名为Crystal吧。希望能带来一些新的体验。

做这个主题并没有花多大工夫,由于没有使用透明png图片,因此IE6的透明png问题就不用考虑,减少了很多工作量。而且也没有在Photoshop里打稿子而是直接写的CSS,因此页面设计上感觉有些粗糙,也是一个缺点吧。页面风格参考了awflasher的blog,在此向他表示感谢。


2007-09
27

最近看到一个Tag丢失事件,想到最近随着Wordpress的不断升级, 各位blogger或许都在考虑着将自己的blog升级吧。但是又有几人考虑到自己数据的安全性呢?

相信okevin就是因为太过于自信而直接在正式服务器上运行升级程序而造成的惨剧吧。 插件本身没有错,自由软件免费提供的前提就是“as-is”,作者不需承担责任的。 当然,作者肯定会尽力让自己的程序没有bug,但谁都不能保证程序不出错。 所以在对你的blog进行改造或升级之前,请务必要备份,备份,再备份。

我采用的方法是:

  1. 在自己的电脑上安装Apache、PHP和MySQL,并搭建好blog程序,数据也要和正式blog相同。在升级blog或安装插件之前,要先在本机上测试并验证没有错误之后才能上传到正式服务器上。
  2. 在自己的电脑上安装subversion来管理blog的代码。这样万一升级导致代码错误,能够轻松地恢复到升级之前的内容。
  3. 修改插件、模板时,先在自己的机器上调试通过后再传到服务器上。不要使用wordpress的模板在线编辑功能。
  4. 服务器上要定期备份数据库,可采用phpMyBackupPro,设置每天自动备份并将备份文件发送到自己的信箱里。
  5. 写个php脚本每个月备份当月的 wp-content/uploads 下的文件。
  6. 如果在正式服务器上有shell权限,上面的备份就可以通过cron来进行。

如果你能做到上面这几点,你的blog的程序和数据基本上就万无一失了。不过它的缺点也是显而易见的——升级一次程序会花掉你几天的时间。所以,没事儿就不要去无休止地升级啦。


2007-09
01

其实做一个像feedburner和feedsky那样的feed统计功能并不难——如果你只是想自己用的话。

做feed统计需要实现的几个功能:

  1. 收集user-agent
  2. 分析近期的user-agent数据并统计每种阅读器的数目
  3. 定义常见阅读器的标记
  4. 绘制图表

而在实际操作中需要注意,统计user-agent时要排除掉浏览器、spider、bot等,仅统计阅读器的数字。而阅读器则分为在线阅读器和离线阅读器两种,在线阅读器一般都会通过user-agent报告订阅者数量(40 subscribers),而离线阅读器则不会。因此在线阅读器仅需要根据报告的数字统计订阅者即可,而离线阅读器则要根据IP地址来统计订阅者。

那么如何安装到wordpress里面?在init action上挂个钩子,判断一下request_uri是不是feed就行了。

最后,这个方法会跟wp-cache插件冲突,因为wp-cache会cache feed,一旦cache之后init action就不动了,所以要注意设置wp-cache使其不cache feed才行。


2007-07
05

半个月前将永久链接的格式从 /archives/%post_id%.html 修改成了 /%year%/%monthnum%/%day%/%postname%/,结果日IP由原来的100多降低到现在的不到30。可能是永久链接的更改影响了Google的收录吧。幸亏fcicq的提醒,我装上了Permalinks Migration Plugin这个插件。这个插件可以识别旧的永久链接格式,然后通过301重定向将它转到现在的永久链接上,这样就不会影响搜索引擎收录了。

这个插件据说是个中国人写的。插件很小,仅一个文件,激活之后在选项中出现一个PermalinksMigration的选项,在其中填入旧永久链接的格式即可完成重定向。


2007-05
04

前两天和fcicq聊天时提到了补充材料的SEO问题, 今天在Digg上发现了那天讨论的原文,特翻译于此以供参考。 原文在这里

今天的主题是一个SEO小技巧,看看你的blog中是否像我一样有“补充材料”。

通过我的Google搜索结果,你可以看到我有106个页面位于补充材料中。 将chrisg.com改成你的域名即可测试你的blog。 (charlee注:我的结果在这里

那么,“补充材料”到底是什么?

我最喜欢Tropical SEO给出的回答:

  • Google补充材料会把页面打入西伯利亚的牢房。
  • Google补充材料会被赋予极低的信任值。
  • Google补充材料不会被用于任何重要的排名。

(charlee注:以上这三句引用自月光博客的译文

从本质上讲,当Google不知道该如何处理你的页面,但却不想抛弃该页面时,就会将它放到补充材料中。

那我为什么会陷入“补充材料”的地狱?

简而言之,原因就是古老的SEO大忌“内容重复”。我的blog中的内部链接和归档页包含大量重复内容, 它们使得Googlebot不知所措。Graywolf有篇视频很清楚地解释了这个问题

我该如何脱离“补充材料”?

最标准的方法就是利用Robots.txt阻止Google索引那些无用的页面。 我不喜欢添加Robots.txt,所以我想找个插件,结果看到了Ogletree给出的建议, 他修改了一个看似完美的Wordpress插件,但后来我在评论中看到了他给出的一段模板代码, 而这正是我想要的。只需少量改动就可以(向Googlebot)说明页面内容。 下面是我在header模板中使用的代码,添加在<title>标签之前即可。

<?php
  if((is_single() || is_category() || is_page() || is_home()) && (!is_paged())){
    echo “<!– ok google, index me! –>”;
  }else{
    echo “<!– google, please ignore - thanks! –>”;
    echo “<meta name=”\”robots\”" content=”\”noindex,follow\”">\n”;
  }
?>

这段代码输出一段特殊指令,告诉搜索引擎不要索引除首页、单篇文章、静态页面、分类页面之外的其他页面。 我遇到的难题就是按日期分类的归档页面,希望这个方法能有效!


2007-04
12

前两天在smalldust的blog上看到了关于扑克牌验证码 的想法。觉得这个想法甚是有趣。 想起了以前在一个网站看到一个猫验证码的想法,基本上就是随机出九张图片, 让评论者选出哪几张图是猫,以此来防止垃圾评论。 而smalldust的扑克牌验证码则是一个更有趣的主意。

与smalldust交涉之后做了这个插件,可以在评论页面上显示扑克牌验证码。 版权采用GPL。截图如下:

扑克牌验证码

另外,我的空间因为有广告,无法使用这个有趣的插件了,遗憾啊。


2007-01
05

Wordpress的官方文档对数据库的结构描述得并不充分,索性自己来分析一下。首先从整体结构入手。 下面是2.0.5版的数据库结构图(E-R图)。为了节约篇幅,这里仅列出了主键和外键。 图中菱形表示1:n的关系,白色部分为1,黑色部分为n。

wordpress-db-er-diagram.png

Wordpress共有10个表,按照功能大致分为四类。

  • user: 用户信息,包括wp_users表和wp_usermeta表。
  • post: 文章及评论信息,包括wp_posts、wp_postmeta、wp_comments、wp_post2cat以及wp_categories五个表。
  • link: 链接信息,包括wp_links表和wp_linkcategories表。
  • option: 全局设置信息,包括wp_options表。

个人认为这个数据库有两个冗余的地方。一个是wp_post2cat表中的主键rel_id,其实可以不要rel_id,而使用post_id和category_id两列作为主键; 另一个是wp_options表,option_id列为自动增长列,仅使用该列即可作为主键,而不需要option_id、blog_id、option_name三列联合做主键。

另外,表的命名规则也很有意思。基本规则总结如下:

  • 保存对象的基本属性,命名为 wp_objects,使用复数(如 wp_posts,wp_comments);
  • 保存对象的扩展属性,命名为 wp_objectmeta,使用单数(如wp_postmeta,wp_usermeta);
  • 多对多关系,命名为 wp_a2b,其中a和b分别为多对多关系两端的对象名的缩写(如wp_post2cat)。

2007-01
02

Wordpress的效率问题似乎一直是议论的热点,今天来看看其中一条SQL语句的效率。

首先将所有插件禁用,并切换为默认模板。 然后按照《WordPress执行效率问题》这篇文章的方法, 在 wp-config.php 中加入

<?php define('SAVEQUERIES', true); ?>

在模板的 footer.php 中加入

<!-- <?php var_dump($wpdb->queries); ?> -->

访问首页,即可从源代码中看到SQL语句。

执行时间最长的是这一条,花了0.02秒:

SELECT DISTINCT * FROM wp_posts  
WHERE 1=1 
  AND post_date_gmt <= '2007-01-02 07:12:59' 
  AND (
    post_status = 'publish' 
    OR
      post_author = 1 
      AND post_status != 'draft' 
      AND post_status != 'static'
  )
  AND post_status != 'attachment' 
GROUP BY  wp_posts.ID  
ORDER BY post_date DESC 
LIMIT 0, 10"

这条语句位于 class.php 的 WP_Query->&get_posts() 函数。

说说这个SQL语句的问题。不妨先来看看 wp_posts 表的结构(省略无关列)。

列名类型索引
IDbigint(20)PRIMARY
post_authorbigint(20)
post_date_gmtdatetime
post_statusenumINDEX
post_namevarchar(200)INDEX

首先是关键字 DISTINCT,DISTINCT的作用是去掉重复的数据, 相当于对选择的列进行 GROUP BY。而这条语句中选择了 * 列,包含了主键列 ID, 每行数据必然不相同,因此 DISTINCT 关键字起不到任何作用, 白白浪费一次排序。

其次是 post_date_gmt 和 post_author 上的比较操作。wp_posts表仅有 ID、post_status 和 post_name 列上有索引,对其他列的比较操作使得mysql不得不访问wp_posts表的所有数据, 影响效率。

然后是 post_status 上的不等于的比较。对索引列使用不等于比较, 会导致数据库不能使用索引(索引只能判断等于关系)。 另外显然已经有了 post_status = 'publish' 的条件, 不必再判断 post_status != 'attachment'。

最后是 GROUP BY wp_posts.ID,仍然是对一个不会重复的列进行 GROUP BY, 毫无意义。

如果不考虑功能损失,将这个 SQL 语句优化为下面这样,则仅需花费0.003秒。

SELECT * FROM wp_posts  
WHERE 1=1 
  AND post_status = 'publish' 
ORDER BY post_date DESC 
LIMIT 0, 10"

使用Apache Bench做测试,优化前平均每个请求的处理时间为 503.125ms,优化后为 478.125ms。


2006-12
29

Wordpress的表名前缀默认为 wp_,该值为Wordpress安装时指定,安装之后无法更改。但若不得已需要改变时,可以使用以下方法。

  • 将数据库导出。
  • 将表中的所有 `wp_ 替换为 `wp2_,其中 wp2_ 为新的表前缀。
  • 导入数据库。
  • 修改 wp2_options 表的数据,在第四行左右有个 wp_user_roles,将其修改为 wp2_user_roles。
  • 修改 wp2_usermeta 表的数据,将所有的 wp_user_level 修改为 wp2_user_level,所有的 wp_capabilities 修改为 wp2_capabilities。

如果忘记修改 wp2_options 和 wp2_usermeta 中的值,后台管理就无法使用。