彩色标签云的实现与 Simple Tags,Cool Tags,WP Cumulus 三个标签云插件的比较

标签云大家都在使用,各种插件也不少,其中比较突出比较有名的两款插件Simple Tags和WP Cumulus几乎是大家的标配了,Simple Tags这个插件可以说功能非常强大,包括热度、内链、样式规范等都非常强,而WP Cumulus则注重在华丽方面,以一种3D的方式来表现标签,更生动化的体现了标签云的函义,而第三款国人开发的插件Cool Tags则是一个非常短小精悍的插件,它功能不多,但更注重在表现方面,比如字体大小样式的规范化和热度色彩的区分。曾经写主题的时候考虑到标签云的样式问题,也曾想自己写一段函数在主题里,后来考虑到适用性时放弃了,因为如果写代码与Cool Tags这个插件来比,反而不如Cool Tags方便。

下面我就说说关于实现彩色标签云的方法。我们从网上大多可以得到如下的彩色标签云原生代码:

//彩色标签云函数开始
function colorCloud($text) {
  $text = preg_replace_callback('|<a (.+?)>|i', 'colorCloudCallback', $text);
  return $text;
}
function colorCloudCallback($matches) {
  $text = $matches[1];
  $color = dechex(rand(0,16777215));
  $pattern = '/style=(\'|\")(.*)(\'|\")/i';
  $text = preg_replace($pattern, "style=\"color:#{$color};$2;\"", $text);
  return "<a $text>";
}
add_filter('wp_tag_cloud', 'colorCloud', 1); 

这段代码从表面上确实实现了让标签云变为彩色的,但在实际使用当中却很容易发现,其实现的是随机色彩,也就是说每一个标签都随机的生成了一个色彩,如果放在主题里,样式是非常凌乱的,可以说效果有了,但也乱了浏览者的眼睛,而如果你不想使用更加强大但在标签色彩上相对简单的Simple Tags插件,或你不想要那种炫而又炫的云效果呢?那我们就转过来看看Cool Tags吧,这个插件很简单,我试分析如下:

首先,Cool Tags通过插件的option设置功能来设置了五个不同热度的颜色,这段代码就省略不说了。

其次,Cool Tags通过widget的option方式提供了最多显示标签数、最大字号、最小字号、字号单位、排序等的设置,其实这段的设置主要是为WordPress的标签云输出函数wp_tag_cloud来提供参数的,以便让wp_tag_cloud函数更好的显示这些标签,那么关键的东西来了,对不同热度进行分级上色,看如下代码:

1
2
3
4
5
6
7
8
9
10
function setSpeed($num,$fontSizeNum = 5){
  for($i = 1;$i <= $fontSizeNum;$i++){
    if($num > 1){
      return $fontSizeNum;
    }
    else if(((1/$fontSizeNum) * $i >= $num ) && ((1/$fontSizeNum) * ($i - 1) < $num) ){
      return $i;
    }
  }
}

这段函数代码主要实现了步进,下面这段代码中调用了它,并进一步上色:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
function cooltags($text){
  $tag_min_size = 12;//默认最小字体
  $tag_max_size = 22;//默认最大字体
  $fontSizeNum = 5;//热度等级
  //默认颜色
  $colors = array(0 => "#ccc",1 => "#555",2 => "#06c",3 => "#468c00",4 => "#f60",5 => "#f00");
  //如果更改了热度颜色,下面会开始使用用户定义的颜色
  $colors[1] = get_option("x-small");
  if($colors[1] == "") $colors[1] = "#555";
  $colors[2] = get_option("small");
  if($colors[2] == "") $colors[2] = "#06c";
  $colors[3] = get_option("medium");
  if($colors[3] == "") $colors[3] = "#468c00";
  $colors[4] = get_option("large");
  if($colors[4] == "") $colors[4] = "#f60";
  $colors[5] = get_option("x-large");
  if($colors[5] == "") $colors[5] = "#f00";
 
  $num_tags_all = wp_count_terms('post_tag');
  $num_all = number_format_i18n( $num_tags_all );
  $fontSizeSpeed = ($tag_max_size - $tag_min_size) / $fontSizeNum;
  $str_pattern = "/(\<a(.*?)\<\/a\>)/is"; 
  //下面这段分析标签云输出函数给出的数据
  if (preg_match_all($str_pattern, $text, $matches)) {
    $counts = array();
    for ($i = 0; $i < count($matches[0]); $i++) {
      $hcontent = $matches[1][$i];
      $sc = preg_match('/(\<a(.*?)\>)/is', $hcontent, $matcht);
      if ($sc) {
        $htitle = $matcht[1];
      }
      if (preg_match('/title=\'(\d).*?\'/is', $htitle, $match)) {
        $tag_num = $match[1];
      }
      $counts[$i] = $tag_num;
    }
  }
  //对标签云给出的数据进行重组重写
  if (preg_match_all($str_pattern, $text, $matches)) {
    for ($i = 0; $i < count($matches[0]); $i++) {
      $hcontent = $matches[1][$i];
      $num_tags_speed = $counts[$i] / max($counts);
      $fontColor = $colors[setSpeed($num_tags_speed,$fontSizeNum)];
      $newStyle = "style='color:{$fontColor};$2'";
      $oldStyle = "/(style='(.*?)')/is";
      $newtext = preg_replace($oldStyle,$newStyle,$hcontent);
      $a[] = $newtext;
      if(count(explode("<ul class='wp-tag-cloud'>",$text)) > 1){
        $textnew = "<ul class='wp-tag-cloud'>\n\t<li>";
        $textnew .= join( "</li>\n\t<li>", $a );
        $textnew .= "</li>\n</ul>\n";
      }else{
        $textnew = join("\n",$a);
      }
      $text .= "<textarea>".setSpeed($num_tags_speed,$fontSizeNum)."</textarea>";
    }
  }
  //输出
  echo $textnew;
}
add_filter('wp_tag_cloud', 'cooltags',  1);//实现输出

上面的代码完成了最终的工作,嗯,我没有细化的去分解注释,主要是因为我对PHP中的一些东西不是很熟,很多时候还需要查手册,再一个我的目的是提出一种思路,或去分析别人的思路给大家,让大家有一种自己也能做插件的愿望和想法,授之与鱼不如授之与渔,简单的一个标签云,根据大家的立意不同,可以做出不同种的插件,那么这就是一种想法和愿望,而通过不同的路径来实现,不同的算法,不同的逻辑顺序即使结果是相同的,但也会有不同的代码效率。呵呵,希望大家能够通过看代码和比较插件功能来提高自己,更希望大家将自己的想法转化为实际的插件来丰富更多的WordPress的使用者。

  1. 2009年11月8日16:09

    不怎么明白,没系统的学习过PHP,感觉和JAVA有很多地方不同啊。
    比如字符串拼接,用的是 .= ,看起来很吃力。

  2. whitewords
    2009年11月9日09:07

    @冰剑
    呵,不错啦,您还学习过JAVA,可以开发很多手机上的软件,我则不同,我对哪一个语言都没有学习过,只是在需要时查手册和搜网络,然后自己安排好逻辑架构,再去实现,只是接触多,但不精啊,如果一种语言比较精通的话,是可以完成很多工作的。

  3. 2009年11月17日18:02

    呵呵 这里果然都是技术文啊 和life的名字不搭配啊

  4. 2010年1月15日02:51

    正好在找Cool Tags的设置,看来直接改源码才是王道