Drupal中template.php的作用

论坛: 

你可能知道在drupal的模板中(比如node.tpl.php)隐藏了很多信息,比如:

     <div><?php print $links; ?></div>

如果你是个设计人员或者drupal的使用者,你可能不知道$links中都包含了哪些信息,deve模块提供一个函数dsm()可以很轻松的查看$links的详细信息,用法如下:

    <?php dsm('$links'); ?>

这是一个不错的办法,可是虽然知道了$links的信息,如果要修改$links又要怎么做呢?

 图像

 

比如有一个文章,后面跟了一些链接($links),包括评论数、全部阅读和阅读次数。如果你想修改链接的格式或样子,只要重写theme_links()这个函数就可以了,但是如果你想改变评论数的位置,比如:

图像

 

要把评论数的链接放到日期后面然后删除全部阅读的链接,那我们又要怎么做呢?先来看看node.tpl.php的代码:

    <h1><?php print $title;  ?></h1>
    <div class="meta"><?php print $name ." | " . $date; ?> </div>
    <p><?php print $content ?></p>
    <div><?php print $links; ?></div>

如果要做到我们想要的必须要拆分$links,应该是这样的:

    <h1><?php print $title;  ?></h1>
    <div class="meta"><?php print $name ." | " . $date . " | " . $number_of_comments; ?></div>
    <p><?php print $content ?></p>
    <div><?php print $read_more; ?></div>  //这行代码将被删除,因为需求是删除全部阅读的链接。

但是目前我们还没有$read_more和$number_of_comments变量,所以先看看$links的结构:


    <?php dsm($node->links); ?>

图像

 

可以看出comment_comments就是评论数的链接,所以我们直接将comment_comments放到日期的后面

    <h1><?php print $title;  ?></h1>
    <div class="meta"><?php print $name ." | " . $date . " | " . $vars['node']->links['comment_comments']['title']; ?> </div>
    <p><?php print $content ?></p>

但是这种写法是错误的,我们需要的是链接,所以就要l()函数

    <?php

    l(
         $vars['node']->links['comment_comments']['title'], 

         $vars['node']->links['comment_comments']['href'], 
         array('attributes' => array('class' => 'comment',
'title' => $vars['node']->links['comment_comments']['attributes']['title'] )) 
    );          


    ?>

所以我们的node.tpl.php就是:

    <?php 
    //link comment
    $link_comment =  l($vars['node']->links['comment_comments']['title'], 
$vars['node']->links['comment_comments']['href'], array('attributes' => array('class' => 'comment','title' => $vars['node']->links['comment_comments']['attributes']['title'] )));          

    //and lets create the read more links
    $link_read_more =  l($vars['node']->links['node_read_more']['title'], $vars['node']->links['node_read_more']['href'], 
array('attributes' => array('class' => 'read-more','title' => $vars['node']->links['node_read_more']['attributes']['title'] )));                    
    ?>

    <h1><?php print $title;  ?></h1>
    <div class="meta"><?php print $name ." | " . $date . " | " . $link_comment; ?> </div>
    <p><?php print $content ?></p>
    <div><?php print $link_read_more; ?></div>

虽然实现了我们想要的功能,但是代码看起来很丑陋。如果我们有很多的node.tpl.php(node-blog.tpl.php, node-page.tpl.php, node-news.tpl.php)我们还需要每一个页面都手动修改,这是编程的大忌。

而template.php可以很好的解决这个问题,你可以把所有的逻辑代码都放到这个文件里,从而保证了node.tpl.php干净。如果没有template.php可以在主题(theme)文件夹下新建这个文件,更多信息请参考http://drupal.org/node/11811

<?php
//----------------------------
//file template.php
//----------------------------
function THEMENAME_preprocess_node(&$vars) {
    //comments
if($vars['node']->links['comment_comments']){
           $vars['link_comment'] =  l($vars['node']->links['comment_comments']['title'], $vars['node']->links['comment_comments']['href'], 
               array(
                 'attributes' => array('class' => 'comment', 'title' => $vars['node']->links['comment_comments']['attributes']['title']),
                   'fragment' => $vars['node']->links['comment_comments']['fragment']
               ) 
     );          
   }
if($vars['node']->links['node_read_more']){
     $vars['link_read_more'] =  l($vars['node']->links['node_read_more']['title'], $vars['node']->links['node_read_more']['href'], array('attributes' => array('class' => 'read-more','title' => $vars['node']->links['node_read_more']['attributes']['title'] )));          
   }

?>

THEMENAME_preprocess_node是会在node.tpl.php之前运行的函数,类似的还有THEMENAME_preprocess_page、THEMENAME_preprocess_block等等。

node.tpl.php不变:

<h1><?php print $title;  ?></h1>
<div class="meta"><?php print $name ." | " . $date . " | " . $link_comment; ?> </div>
<p><?php print $content ?></p>
<div><?php print $link_read_more; ?></div>

这样看起来是不是更好一些呢。