content-type 決定comment template

原本以為之前的一篇文章總結了*.tpl.php 的用法
但今天還是忍不住寫了這一篇:
content-type 決定comment template

例如, 如果有一個 comment-book.tpl.php 檔存在,
而你正在訪問的node 的node-type又是 book 的話,
drupal 就會使用comment-bookk.tpl.php, 而不使用comment.tpl.php

作為此系列的第二篇,
先從編程的角度解釋整個工作原理
再提供相關的代碼

首先打開modules/comment/comment.module
輕易的找到 theme_comment() 函數,
內裏包含了輸出的html 函數
根據drupal 的命名規則, 這個輸出用的函數可以在theme 內修改

例如, 一個module 內, 使用theme('example')
會順序找出一個輸出的函數, 順序為:
1. template.php 內的 %theme_name%_example() (注:%theme_name%為你的模版風格的名字)
2. template.php / phptemplate.engine 內的 phptemplate_example()
3. *.module 內的 theme_example()

這一次的theme_comment(), 我們可以用 phptemplate_comment() 或 %theme_name%_comment() 覆蓋它
令Drupal 的輸出使用我們定的template, 而不是comment.module 內的預設函數
但你會在phptemplate.engine 內發現一個phptemplate_comment() 函數
所以如果你重定義phptemplate_comment(), 會出現錯誤,
指你非法的"雙重定義"了
所以唯有使用 %theme_name%_comment()

在template.php 內建立一個函數

<?php
function joe2_comment(){
}
?>

(記得要將[joe2]改為你的theme 的名字)

這次的要求是 "不同的node-type 使用不同的comment輸出"
所以我們要知道node-type
要知道node-type 有很多方法
而這次使用了一個全局變量(global)
從theme('node') 的時候將node-type 放到全局變量
theme('comment') 的時候取回它

在template.php 內建立一個函數

<?php
function joe2_node($node, $teaser = 0, $page = 0) {
  if (
page == 0 ){ //只有full node view 的時候才需要這個變量
   
global $nodetype; //定義全局變量
   
$nodetype = $node->type; //設定變量值
 
}
  return
phptemplate_node($node, $teaser, $page); //呼叫phptmeplate.engine 內的函數
}
?>

(記得要將[joe2]改為你的theme 的名字)

上面的一小段代碼只是定義, 賦值一個全局變量
然後使用原本的phptemplate engine 的代碼
所以 joe2_comment() 可以使用 $nodetype 了

然後, 要令drupal 找出comment-[$nodetype].tpl.php (就像node-[$nodetype].tpl.php 一樣)
就要使用前一篇已經介紹過的 _phptemplate_callback() 函數

這一次使用到第三個參數:

<?php
function joe2_comment($comment, $links = 0){
  global
$nodetype; //使用全局變量
 
return _phptemplate_callback('comment', //第一個參數是預設template 檔, comment.tpl.php
   
array(  //第二個參數是一個陣列, 傳給template 檔(*.tpl.php)的
   
'author'    => theme('username', $comment),
   
'comment'   => $comment,
   
'content'   => $comment->comment,
   
'date'      => format_date($comment->timestamp),
   
'links'     => isset($links) ? theme('links', $links) : '',
   
'new'       => $comment->new ? t('new') : '',
   
'picture'   => theme_get_setting('toggle_comment_user_picture') ? theme('user_picture', $comment) : '',
   
'submitted' => t('Submitted by !a on @b.',
                      array(
'!a' => theme('username', $comment),
                           
'@b' => format_date($comment->timestamp))),
   
'title'     => l($comment->subject, $_GET['q'], NULL, NULL, "comment-$comment->cid")
  ),array(
'comment-'.$nodetype) //第三個參數是建議的template 檔, 所以傳 'comment-'.$nodetype
);
}
?>

這樣, 如果有一個 comment-book.tpl.php 檔存在,
而你正在訪問的node 的node-type又是 book 的話,
drupal 就會使用comment-bookk.tpl.php, 而不使用comment.tpl.php 了

Comments

A very nice informative

A very nice informative article / post. I have been interested in this topic and found your comments spot on. I points in the second paragraph were of particular interest to me.

有點費力氣看玩了,

有點費力氣看玩了,沒看懂。
繼續看第二遍。

While I agree that this

While I agree that this article was very informative and well written, there were a number of question marks...

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <img> <h4> <h3>
  • Lines and paragraphs break automatically.
  • You may post code using <code>...</code> (generic) or <?php ... ?> (highlighted PHP) tags.

More information about formatting options