前几天向大家介绍了如何实现“随机文章”的方法,今天将要介绍的这个“相关文章”的方法其实是差不多的,在随机文章的基础上稍加修改即可。

首先我们看一下什么样的文章才算是“相关文章”,对“相关文章”这个词的理解,不同人的理解可能会有点出入。我是这样认为的:具有相同标签的文章相关性最强,然后是具有相同分类的分章。

根据上面我对“相关文章”的理解,查找“相关文章”的过程如下:

  1. 首先随机显示和文章具有相同标签的文章
  2. 如果找到的文章数量不足指定的数量,则继续随机显示和文章分类相同的文章
  3. 如果还是不足指定的文章数量,则随机在全站显示几篇文章

关键代码分析

由于随机显示的工作比较多,我们首先来定义一个可以根据分类ID或者标签名显示随机文章的函数the_rand_posts,有关the_rand_posts函数,可以参看WordPress添加“随机文章”模块 一文。下面是升级版本的the_rand_posts函数

function the_rand_posts($args = '',$post_not_in = array()){

 global $post;

 $default = array('showposts'=>10,
  'cat'=>'',
  'tag'=>'',
  'class'=>'randomPosts',
  'useul'=>1);

 $r = wp_parse_args($args,$default);

 extract($r);

 $r['orderby'] = 'rand';
 $r['post__not_in'] = $post_not_in;
 $rand_query = new WP_Query($r);

 $output = '';
 $post_ids = array();

 foreach($rand_query->posts as $p){
  $post_ids[] = $p->ID;
  $output .= '<li><a href="'.get_permalink($p).'">'.get_the_title($p->ID).'</a></li>';
 }

 if($useul)
  $output = '<ul>' .$output . '</ul>';
 echo $output;

 return $post_ids;
}

其中showposts指定显示的文章数量,cat指定查找的分类ID范围,tag指定查找的标签名范围,useul决定是否使用<ul></ul>标签。该函数返回查找到的文章ID数组。

下面看一下如何根据文章标签查找指定数量的相关文章:

$terms = get_the_tags();
 foreach($terms as $term){
  $tags[] = $term->name;
 }

这段代码的作用是获取文章的标签名,保存到$tags数组中

接下来把$tags数组转换为用’,’号隔开的字符串,并传递给the_rand_posts来随机显示

$tag = implode(",",$tags);
  $post_not_in[] = $post->ID;
  $post_ids = the_rand_posts("useul=0&showposts=$showposts&tag=$tag",$post_not_in);

如果知道查找到的文章的数量呢,通过计算$post_ids数组的长度即可。$post_not_in是用来避免查找复制的文章。如果文章数量不足我们指定的$showposts,则再根据文章分类ID继续查找

$post_not_in = array_merge($post_not_in,$post_ids);
  $count = count($post_ids);
 if($count < $showposts){
  $showposts -= $count;
  $categorys = get_the_category();
  foreach($categorys as $category){
   $cats[] = $category->term_id;
  }
  $cat = implode(",",$cats);
  $post_ids = the_rand_posts("useul=0&showposts=$showposts&cat=$cat",$post_not_in);

}

该段代码中通过调用get_the_category函数来获取文章的分类信息,并通过一个循环来保存分类ID列表,然后传递给the_rand_posts函数进行查找并随机显示。

最后我们再做一次判断,如果显示的文章数量仍然不足我们指定的文章数量,就从全站的文章中随机显示几篇

$count = count($post_ids);
  $post_not_in = array_merge($post_not_in,$post_ids);
 if($count < $showposts){
  $showposts -= $count;
  the_rand_posts("useul=0&showposts=$showposts",$post_not_in);
 }

使用方法

完整代码如下:

function the_rand_posts($args = '',$post_not_in = array()){

 global $post;

 $default = array('showposts'=>10,
  'cat'=>'',
  'tag'=>'',
  'class'=>'randomPosts',
  'useul'=>1);

 $r = wp_parse_args($args,$default);

 extract($r);

 $r['orderby'] = 'rand';
 $r['post__not_in'] = $post_not_in;
 $rand_query = new WP_Query($r);

 $output = '';
 $post_ids = array();

 foreach($rand_query->posts as $p){
  $post_ids[] = $p->ID;
  $output .= '<li><a href="'.get_permalink($p).'">'.get_the_title($p->ID).'</a></li>';
 }

 if($useul)
  $output = '<ul>' .$output . '</ul>';
 echo $output;

 return $post_ids;
}
function the_related_posts($args = ''){
 global $post;

 $default = array('showposts'=>10,
  'class'=>'relatedPosts');
 $r = wp_parse_args($args,$default);
 extract($r);

 echo '<ul>';

 $tags = array();
 $terms = get_the_tags();
 foreach($terms as $term){
  $tags[] = $term->name;
 }
 if(!empty($tags)){
  $tag = implode(",",$tags);
  $post_not_in[] = $post->ID;
  $post_ids = the_rand_posts("useul=0&showposts=$showposts&tag=$tag",$post_not_in);
  $post_not_in = array_merge($post_not_in,$post_ids);
  $count = count($post_ids);
 }
 if($count < $showposts){
  $showposts -= $count;
  $categorys = get_the_category();
  foreach($categorys as $category){
   $cats[] = $category->term_id;
  }
  $cat = implode(",",$cats);
  $post_ids = the_rand_posts("useul=0&showposts=$showposts&cat=$cat",$post_not_in);
  $count = count($post_ids);
  $post_not_in = array_merge($post_not_in,$post_ids);
 }
 if($count < $showposts){
  $showposts -= $count;
  the_rand_posts("useul=0&showposts=$showposts",$post_not_in);
 }
 echo '</ul>';
}

如果你懒得分析代码,可以把以上完整的代码复制到你正在使用主题文件夹下的functions.php文件中,然后在single.php文件中调用

<?php if(function_exists('the_related_posts')) {the_related_posts();} ?>

或者继续关注本站,不日将发布”随机文章”插件的升级版本,集成“相关文章”功能。

The End

添加评论

15 条评论

  1. 1 F

    phoenixwright

    2009-11-23 星期一 20:31

    写得很好啊,真强大,学习了

    回复
  2. 2 F

    软件开发

    2009-11-24 星期二 01:42

    发现现在WP的主题越来越多了,博主的模板挺漂亮的

    回复
    • DDBug

      2009-12-01 星期二 22:12

      我倒不怎么喜欢这个主题,准备制作一个自己的主题了

      回复
  3. 3 F

    软件

    2009-11-24 星期二 02:47

    你的版块很不错,我好喜欢喔!

    回复
  4. 4 F

    六月成人

    2009-11-30 星期一 23:52

    不错,挺喜欢你站

    回复
    • keke

      2010-09-03 星期五 13:55

      这是我见过的最完整的介绍了,谢谢分享

      回复
  5. 5 F

    tiny

    2010-02-07 星期天 19:23

    Hi,博主你好…
    你上面的代码有些英文标点被格式化成中文标点.我修改了下还是报错,能麻烦你发一份到我的邮箱吗
    谢谢

    回复
  6. 6 F

    aserlee

    2010-05-08 星期六 17:37

    不错,加入“相关文章”标题进去就完美了……

    回复
  7. 7 F

    G字头老大

    2010-05-16 星期天 09:09

    好棒的教程!虽然早已有了wp related post之类的插件,但对于像设计自己主题的家伙,您发的这个教程无疑是“黄金”!

    谢谢分享!

    回复
  8. 8 F

    mark

    2010-06-12 星期六 12:42

    你好,我想让相同类别的文章显示在sidebar内,用了楼主的这个方法调用了相关文章,请问如何让这些文章按顺序排列,并能够显示当前文章也能在列表中,显示出选中状态。望回复,十分感谢!!

    回复
  9. 9 F

    阿达

    2010-08-31 星期二 19:57

    太强大了!我转走了啊~~~~

    回复
  10. 10 F

    keke

    2010-09-03 星期五 17:07

    复制代码到functions.php文章后,在single.php中添加【】后,显示如下的错误,不知道是什么原因,恳请赐教,况且我希望相关文章中不要再显示当前single页这篇文章了。

    【Warning: Invalid argument supplied for foreach() in C:\wamp\www\wangzhan\wp-content\themes\jingdianban\functions.php on line 41】

    和【Warning: array_merge() [function.array-merge]: Argument #1 is not an array in C:\wamp\www\wangzhan\wp-content\themes\jingdianban\functions.php on line 62】

    回复
  11. 11 F

    亿品元素

    2010-09-03 星期五 18:58

    还是插件来的方便

    回复
  12. 12 F

    阿达

    2010-09-07 星期二 19:35

    老大~
    复制代码到functions.php文章后,在single.php中添加【】后,显示如下的错误,不知道是什么原因,恳请赐教,况且我希望相关文章中不要再显示当前single页这篇文章了。

    【Warning: Invalid argument supplied for foreach() in C:\wamp\www\wangzhan\wp-content\themes\jingdianban\functions.php on line 41】

    和【Warning: array_merge() [function.array-merge]: Argument #1 is not an array in C:\wamp\www\wangzhan\wp-content\themes\jingdianban\functions.php on line 62】

    回复
  13. 13 F

    阿达

    2010-09-08 星期三 21:11

    老大 很忙啊。。怎么不出现了= =

    回复

添加评论