继上回的改造工作,这回主要是优化页面边栏结构。每部分的内容如下:
首页:
- Popular Tags
- Sugested Content ( Featured Posts )
- Random Posts
- No Recent Posts
- No Archives
- No Ads.
首页的主要目的是能尽量多的展现想推荐给别人看的东西,所以不放冗长的归档列表以及可能没有什么主题的广告。Recent Posts 实在没有什么意义,首页那几篇文章不正和 Recent Posts 撞车了么,所以干脆去掉。推荐内容那一条还没有想好怎么搞定,也许可以读取统计信息,挑被看次数最多的页面作为 Featured Posts?
文章页:
- Related Tags
- (Related Posts)
- Random Posts
- Ads
- No Recent Posts
- No Archives
这部分主要是想让读者能够继续扩展阅读,所以用 Related Tags 和 Related Posts 把尽可能相关的信息列出来。Ads. 也是处于这个考虑加上的,因为文章页面的内容主题更为突出,也许广告能展示更有趣的东西。退一万步说,就算广告内容不行,光冲着他花花绿绿的图片也值了,正好可以调节一下页面上单调的视觉效果。Related Posts 在正文后面用了无觅的插件搞定了,不过还在犹豫要不要挪到边栏来,因为很遗憾无觅的图片最大只有 120 像素,满足不了我一篇文章的缩略图占满一行 300 像素的设想。至于 Related Tags 的功能,本来想通过插件来完成,但是翻来翻去硬是找不到合适的,遂写了个简单的函数来搞定。主要的思路是查找包含文章 tags 的其他文章,并认为这些文章的 tags 是原文章的 related tags 了。函数代码在后面列出来了,是属于 php 门外汉捧着手册拼出来的玩意儿,凑合这看吧,呵呵。
归档和搜索页:
- Popular Tags ( All Tags in Tags Archive Pages )
- Archives by Months
- Ads.
归档和搜索页主要是为别人找东西方便而设立的,所以终于把冗长的归档列表搬出来了。更有甚者,在 Tags 归档页还把全部的 tags 都搬出来了,看上去有点吓人。加上 Ads. 则是考虑到 Tags 归档和搜索的时候主题也还算明确,不会出一些莫名奇妙的广告,按月归档的页面还只能请观众无视广告了。
大概就是这个样子了,除了首页的推荐内容和文章页面的 Related Posts 还没有太想好怎么搞以外,其他就这么定稿了,过后慢慢调整。
ps. 首页和文章页两个 Random Posts 主要用于提供一种扩展阅读的途径。值得一提的是两个地方用的插件并不一样。首页上用的是 Rob Marsh, SJ 的 Random Posts,而文章页则用的是 Phoenixheart 的 AJAX Random Posts。当然这个是有意为之。前者是 php 型的,显示速度快;后者是 AJAX 型的,显示速度慢。但是文章页会通过 WP Super Cache 缓存,php 型的自然一缓存就随机不了了,要想随机还必须得上 AJAX。而且随机文章和原文章的相关性不高,如果用 php 型生成内容,会被搜索引擎搜到,搞不好会给页面带来意想不到的关键字。想想看通过搜索引擎找到一篇文章,结果正文里完全没有提到搜索的内容,仔细一看发现关键字出现在边栏里,这岂不是很郁闷?AJAX 型的则没有这个问题。前面提到的无觅插件,也是用 js 加载相关内容的,同样不会被搜索引擎索引,带来莫名其妙的关键字。
update(20110425). 其实首页上没有用 AJAX Random Posts 还有一个更重要的原因,那就是不能使用…这个插件的功能只能在 single.php 页面里调用。貌似是使用了 $post->ID 这类变量。
附录,Related Tags 功能代码如下:
function wk_get_related_tags_id( $post_id = 2012 ) {
global $wpdb;
$str_o_tags = '';
$str_r_posts = '';
$str_r_tags = '';
// 获得指定 id 的 post 的所有非大类 tags
// tag_id = 155:悟; 157:感; 158:见; 82:观; 88:解决问题
// t_t.count == 0 代表 tag 没有对应的文章或者全部文章都是 private 的
$q1 = <<<term_taxonomy t_t, $wpdb->term_relationships t_r
WHERE t_t.term_taxonomy_id = t_r.term_taxonomy_id
AND t_t.taxonomy = 'post_tag'
AND t_t.count <> 0
AND t_t.term_id NOT IN (155, 157, 158, 82, 88)
AND t_r.object_id = $post_id;
SQL;
$o_tags = $wpdb->get_results( $q1, ARRAY_N );
if ( 0 != count( $o_tags ) ) {
// 格式化 tag 列表
foreach ( $o_tags as $o_tag ) {
$str_o_tags .= strval( $o_tag[0] ) . ',';
}
$str_o_tags = rtrim( $str_o_tags, ',' );
// 获得包含上述 tags 的 posts 的列表,这是一种简单的相关 posts 获取方法
$q2 = <<<term_taxonomy t_t, $wpdb->term_relationships t_r
WHERE t_t.term_taxonomy_id = t_r.term_taxonomy_id
AND t_t.taxonomy = 'post_tag'
AND t_r.term_taxonomy_id IN ( $str_o_tags )
SQL;
$r_posts = $wpdb->get_results( $q2, ARRAY_N );
// 格式化相关 posts 列表
foreach ( $r_posts as $r_post ) {
$str_r_posts .= strval( $r_post[0] ) . ',';
}
$str_r_posts = rtrim( $str_r_posts, ',' );
// 获得包含上述相关 posts 的所有 tags
// 这些 tags 与指定 id 的 post 的 tags 可以认为有较高的相关性
// t_t.count == 0 代表 tag 没有对应的文章或者全部文章都是 private 的
$q3 = <<<term_taxonomy t_t, $wpdb->term_relationships t_r
WHERE t_t.term_taxonomy_id = t_r.term_taxonomy_id
AND t_t.taxonomy = 'post_tag'
AND t_t.count <> 0
AND t_r.object_id IN ( $str_r_posts )
SQL;
$r_tags = $wpdb->get_results($q3, ARRAY_N);
// 格式化相关 tags 列表
foreach ( $r_tags as $r_tag ) {
$str_r_tags .= strval( $r_tag[0] ) . ',';
}
$str_r_tags = rtrim( $str_r_tags, ',' );
}
return $str_r_tags;
}
其中第一个查询的 NOT IN 主要是为了排除宽口径 tags 的影响。函数参数随便设定了个文章的 id 作为默认参数,可要可不要。函数返回的是逗号分割的 related tags 的 id 列表字符串。在边栏里用可以这么用:
<?php $r_tags_id = wk_get_related_tags_id( $post->ID );
if ( '' == $r_tags_id ) {
wp_tag_cloud( 'smallest=12&largest=28&number=30&unit=px&include=' . $r_tags_id );
} ?>
其中 wp_tag_cloud 的用法还请参考手册。因为函数里没有对 $post->ID 的数据类型做判断,所以只能保证在 single 页面功能正常,其他页面要是使用的话,不知道会有什么后果。这个简单的功能居然需要查询三次数据库,有点无奈。我的虚拟主机上耗时大概 10ms 不到吧,感觉不算太过分。希望尽量减少数据库查询的请无视好了。