在theme里区别显示一般分类与freetag标签

Drupal自4.7开始把freetagging引入了分类系统。在实际使用中,大家一般还是愿意区别对待freetags与传统分类,所以通常都是定义两套分类术语表(vocabulary),一套是常用的固定分类,一套则开启自由标签即freetagging。这样既可以按传统办法把文章划分入固定分类,也可以同时自由地贴上个性化标签。但Drupal自带的主题通常对此不加区分,造成的结果就是在显示文章分类时,一股脑地把所有传统分类与自由标签都混在一起显示。这里就介绍一下如何通过模版控制,来区别显示一般分类与freetag标签。

kzeng在4.7刚出来的时候发过一篇分离freetags与分类的显示,很实用,但那个方法需要手动找到freetagging所在分类的vid,如果有好几个站点,需要一个一个找过来还是有点麻烦。drupal.org的handbook里有人提供了一个更通用的办法,感觉还不错。但那里还是4.7的版本,我把它稍微修改了一下,在5.0里也可以用了。

Drupal的phptemplate主题引擎提供了一些基本的站点变量,比如 $site_name $content $footer等,在主题模版里可以直接引用这些变量,非常方便。其中分类的变量是 $terms,但这一变量包含了该节点内容的所有相关分类,如果在模版里直接 print $terms 的话,就会把一般分类与freetag标签全部打印出来。我们现在要做的就是要引入两个新的变量,$myterms包括一般分类,$mytags包括相关的freetags。

  1. 建立template.php文件
    基于phptemplate引擎的模版,可以通过template.php文件来定义自己模版所需的函数与变量。看看你的主题目录下(如 themes/garland/)是不是已经有template.php文件,如果没有则需要新建此文件。
  2. 修改 _phptemplate_variable() 函数
    在template.php文件中,我们将需要使用 _phptemplate_variable() 函数来引进我们所需的两个变量。有的模版(比如garland)已经定义了这一函数,我们需要把下面代码中的 if($hook == 'node') 开始的部分插入到此函数中的最后部分。

    <?php
    function _phptemplate_variables($hook, $vars) {
       
      if (
    $hook == 'node') {
        if (
    module_exists('taxonomy')) {
          foreach (
    taxonomy_get_vocabularies($vars['node']->type) as $vid=>$vocab) {
            foreach (
    taxonomy_node_get_terms_by_vocabulary($vars['node']->nid, $vid) as $term) {
              if (
    $vocab->tags) {
               
    //方案1
               
    $tag_links[] = array('title' => $term->name, 'href' => taxonomy_term_path($term), 'attributes' => array('rel'=>'tag', 'title'=>$term->description));
               
    //方案2
                //$tag_links[] = l($term->name, taxonomy_term_path($term), array('rel' => 'tag', 'title' => $term->description));
             
    }
              else {
               
    //方案1
               
    $term_links[] = array('title' => $term->name, 'href' => taxonomy_term_path($term), 'attributes' => array('rel'=>'tag', 'title'=>$term->description));
               
    //方案2
                //$term_links[] = l($term->name, taxonomy_term_path($term), array('rel' => 'tag', 'title' => $term->description));
             
    }
            }
          }

         
    //方案1
         
    $vars['myterms'] = theme('links', $term_links, array('class'=>'links inline'));
         
    $vars['mytags']  = theme('links', $tag_links,  array('class'=>'links inline'));
         
    //方案2,这里的'|'可以用你自己的分隔符替代
          //$vars['myterms'] = $term_links ? implode('|', $term_links) : '';
          //$vars['mytags'] = $tag_links ? implode('|', $tag_links) : '';
       
    }

      }
      return
    $args;

    }
    ?>

    注意上面列出了两个方案,区别不过是输出的theme格式不同。方案1使用theme_links函数将所有的分类或tag通过 <ul><li> 这样的列表输出;方案2则是直接将表单展平以字符串的形式输出。一般来说,表单输出的可控性更高更灵活,但过于复杂,如果只是要通过分隔符的形式在一行显示,那么方案2也就够用了,这也是沿袭原来awTags的格式。

  3. 在node.tpl.php里面控制输出位置
    现在我们就可以在模版里直接调用新引入的两个变量 $myterms 和 $mytags 了。打开你的主题目录下的 node.tpl.php 文件,以garland主题为例,找到这一段:(注意我在张贴代码时在很多?后面加上了空格,以避免格式被codefilter打乱)

    <?php
    if ($taxonomy): ? >
          <
    div class="terms"><? php print $myterms ? ></div>
        <?
    php endif;
    ?>

    我们可以用 $mytags 来代替原来的 $terms 变量,同时更改对应的CSS类:

    <?php
    if ($mytags): ? >
          <
    div class="tags"><span id="tagbox">Tags</span><? php print $mytags ? ></div>
        <?
    php endif;
    ?>

    这样我们就可以在文章下面输出所有相关的freetags了。我们还想在文章标题右方显示固定分类,那么只要将下面这段插入到相应的位置就可以了:
    (这段的格式也太难搞定了,codefilter总是添乱,还得用HTML entity输入才搞定。。。)

    <h2><a href="<?php print $node_url ?>" title="<? php print $title ?>"<>? php print $title ? ></a></h2>
    <? php endif;? >
    //新插入的部分
    <?php if ($taxonomy): ?>
    <div class="terms"><?php print $myterms ?></div>
    <?php endif;?>

  4. 在style.css里定义样式
    到现在为止,你应该可以看到固定分类显示在标题右方,freetags显示在文章下面。下面就需要你在style.css里定义最终显示样式了。你所要关注的就是 .terms 和 .tags 这两个类,具体怎么美化那就看你的了。

不错

我想在drupal5中尝试这个。谢谢大米。

-----
进门莫问姓名,芳草满庭皆无主;
入室自分雅路,四厢弦歌尽留人。

holz.byethost15.com | gdgpi.com.cn

简直就是一篇生动的

简直就是一篇生动的模板修改教程啊!
--------------------
美国空间,美国主机,营销型网站,美国虚拟主机

很好。很强大。

很好。很强大。