Drupal 系統設計的事前企劃要注意事項

當你選用了drupal, 一個CMS,
作為你的網頁的系統
我想你的網頁應該是預計有一個定量的更新, 新增元件等等
所以, 在你設計你的系統的時候
記得一定是以"可持續發展"大前提

例如教學中的templates 部份,
因為可以改動的地方, 改動的方法等等都層出不窮
加一定量的注解是不可或缺的
而且, 注解是要在頁面的源碼中看到
即使用html 的注解方式,
使用<!--注解...-> 內嵌到template
令打開一個頁面, 查看源碼的時候
可以立即看到杓成這個頁面的元件, 使用過的template 等等
方便修改

而且, 同類的修改記使用同樣的方法作修改
網站一旦大起來, 維護的時間絕對會比開發的時間還長

這就是這三個星期沒有時間更新這裡換來的一個教訓
特此留字, 引以為鑑

使用templates 自定user 頁

終於來到預定的templates 最後一章
這次只是給多一個例子給大家參考
並沒有新的技術, 函數要認識, 使用

在一個用戶登入之後,
預設會到逹 user/[uid] 頁面
今次的目的就是改動這個頁面
例如:

  • 令登入都立即看到自己建立的nodes ( 配合使用views )
  • 不同的登入id 使用不同的頁面
  • 不同的roles 使用不同的頁面
  • 不同的profile fields(例如"城市")到不同的頁面

等等
建立社區主導的網站應該會使用到這個教學

因為url 為 user/[uid]
很有機會相關的輸出都是來自user/module
打開user/module, 到 user_menu() 函數
line 810 的 'path' 為 user/arg(1)
callback 到 user_view() 函數

line 1504 user_view(), 最後的一句:

<?php
 
return theme('user_profile', $account, $fields);
?>

找到了

到 user.module 內的 line 654, theme_user_profile()
將內裏的內容放到新建的 user_profile.tpl.php
'return' 改為 'print'
template 文件(user_profile.tpl.php) 放到你的theme 的目錄之下
user.module 的部份完成

到template.php 了, 打開你的theme 之下的template.php
新建一個函數, [theme_name]_user_profile()

<?php
function joe2_user_profile($account, $fields) {
  return
_phptemplate_callback( //此函數令drupal 找*.tpl.php
   
'user_profile', //找user_profile.tpl.php 文件來使用
   
array( 'account'=>$account , 'fields'=>$fields ), //傳給 user_profile.tpl.php
   
array( 'user_profile_'.$account->uid ) //根據你的特別要求, 使用不同的template, 注(一)
 
);
}
?>


注一:
這個例子建議使用user_profile_[uid].tpl.php (如有)
你也可以使用:
<?php
   
array( 'user_profile_'.$account->role )
?>

建議使用user_profile_[role].tpl.php (如有)

可以再配合template redirect, 轉到views 頁面等等,
就看你的創意了

以後要自定user 頁,
只要修改user_profile.tpl.php 就可以了

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 了

Regions

update2: Druapl 6.x regions
D6 update: Region 的定義在 .info 之內, 以下內容只適用於 D5 (2010-03-10)

新的模版有一個比較特別的地方,
就是自定了三個位於頁尾的regions,
而沒有使用panels.

當然, 第一是效能的考慮,
二來, 因為每一頁都會有這三個頁尾區
製作眾多panels 只費時失事

增加regions是theme 的管轄範圍
初初我也感到意外, 但為了保持彈性和可定製性
留在theme 的層面也是相當的合理
定製也只需要初階的編程能力
一般的模版開發者是可以應付得來的

在template.php 之內, 定義一個函數:

<?php
function mytheme_regions(){
  return array(
   
'right' => t('right sidebar'),
   
'content' => t('content'),
   
'header' => t('header'),
   
'footer' => t('footer'),
   
'bottom_left' => t('bottom left'),
   
'bottom_center' => t('bottom center'),
   
'bottom_right' => t('bottom right'),
  );
}
?>

mytheme 是這個theme的名字,
那樣, $bottom_right, $bottom_left, $bottom_center 等的變數就會出現在page.tpl.php 之內
你可以將它們放到自定的位置, div 之內
//page.tpl.php
<?php if ( $bottom_left || $bottom_center || $bottom_right || $feed_icons ):?>
......

到 admin->site building->blocks 就會看到有'bottom left' 等等的選項了

2007-8-3 新樣式正式開通

在我自己試用了差不多一個星期之後
新樣式的開發終於可以告一段落
可以繼續專心做我手上的freelance 了..

AttachmentSize
Image icon new-style-1.gif5.84 KB
Image icon new-style-2.gif7.06 KB
Image icon new-style-3.gif13 KB
Image icon new-style-4.gif7.18 KB

Pages

Google