Drupal6.x 自定form template

AttachmentSize
Image icon 96-1.png10.04 KB

重寫版: http://www.joetsuihk.com/node/119

這一篇可真是費盡了心神, 開發時間估計有十小時以上...
請多多支持.....

一切事, 源於要修改 node/add 的form
因為太多摺了的選項, 想摺成一個"advanced options" 之內
(圖為最後成果)

這個Drupal5.x 之中已經可以實現的一個中等難度的修改
萬估不到需要這麼多的時間, 究其原因,
主要是Drupal6.x 的手冊, 工具(devel)等等都不是很成熟
太過倚賴的話反而可能會招致反效果
但隨著時間的推進, 情況應該會慢慢的改善

註: 以下內容假設你已經可以熟練地使用 *.tpl.php

好, 一堆廢話後正式開始,
第一個挫折出現在story-node-form.tpl.php
devel 說 node/add/story 可以使用 story-node-form.tpl.php
但我一直都不可以順利地使用, 找狂了一陣子,
追到node.module, node.pages.inc, theme.inc......等等
都發現不到問題.....
但node-form.tpl.php 可以正常使用....
但 [node-type]-node-form.tpl.php 一直使用不能
最後一怒之下試試自己提供template 檔名,
根據http://drupal.org/node/223440 (Working with template suggestions)的代碼
在template.php 中: phptemplate_preprocess_node_form()
使用 $vars['template_suggestions'][] = arg(2)."-node-form";
但都沒有反應, 使用回node-form.tpl.php.....
可真是火大了......node-form.tpl.php 的使用次序要比自定義的template 檔高.....
.....
....
...
..
.

還好, 後來幾乎反轉全個 Drupal6.x 的 theming guide 之後,
又回到http://drupal.org/node/223440 (Working with template suggestions)
看到使用 $vars['template_files'][] = arg(2)."-node-form";
一試之下.....成功了....

所以我懷疑template_suggestions 是錯的, 也留了言, 也很快地,
handbook 團隊己經修改了錯誤,留言都刪了... (可以在revision 中看到罪證!!)
但devel 中提示不需要修改, 新增代碼就可以使用story-node-form.tpl.php 的問題還沒有解決..
結論就是.....要當第一便要比別人多花很多苦工.......><

正當以為工作己經完成, 又發覺 node/1/edit 的form 竟然沒有使用[node-type]-node-form.tpl.php
又用回node-form.tpl.php.......
又要改template.php,: phptemplate_preprocess_edit_node_form()
但這個hook 一樣是被遺棄(不明原因)
完全是萬念俱灰.....
最後,修改phptemplate_preprocess_node_form():

<?php
//template.php
function phptemplate_preprocess_node_form(&$vars) {
 
//處理 node/add/[node-type]
 
if( arg(1)== "add"){
   
$vars['template_files'][] = arg(2)."-node-form";
  }elseif(
arg(2) == "edit" ){
   
//處理 node/[nid]/edit
   
$vars['template_files'][] = $vars['form']['#node']->type . "-node-form";
  }

 
$vars['form']['advanced']['revision_information'] = $vars['form']['revision_information'];
  unset(
$vars['form']['revision_information']);
 
$vars['form']['advanced']['comment_settings'] = $vars['form']['comment_settings'];
  unset(
$vars['form']['comment_settings']);
}
?>

//[node-type]-node-form.tpl.php

<?php

  $output
= "\n<div class="node-form">\n";

 
// Admin form fields and submit buttons must be rendered first, because
  // they need to go to the bottom of the form, and so should not be part of
  // the catch-all call to drupal_render().
 
$admin = '';
  if (isset(
$form['author'])) {
   
$admin .= "    <div class="authored">\n";
   
$admin .= drupal_render($form['author']);
   
$admin .= "    </div>\n";
  }
  if (isset(
$form['options'])) {
   
$admin .= "    <div class="options">\n";
   
$admin .= drupal_render($form['options']);
   
$admin .= "    </div>\n";
  }
 
$buttons = drupal_render($form['buttons']);

  if (isset(
$form['advanced'])) {
   
$advanced .= "    <div class="advanced">\n";
   
$advanced .= drupal_render($form['advanced']);
   
$advanced .= "    </div>\n";
  }

 
// Everything else gets rendered here, and is displayed before the admin form
  // field and the submit buttons.
 
$output .= "  <div class="standard">\n";
 
$output .= drupal_render($form);
 
$output .= "  </div>\n";

  if (!empty(
$advanced)) {
   
$output .= advanced;
  }

  if (!empty(
$admin)) {
   
$output .= "  <div class="admin">\n";
   
$output .= $admin;
   
$output .= "  </div>\n";
  }
 
$output .= $buttons;
 
$output .= "</div>\n";

  print
$output;

?>

終於完成了......

當然, 除了comment settings 和 revision information,
其他的都可以放到自定的advanced options 之內.

最後最後,
還有一個奇怪的地方,
就是, _preprocess_[hook] 的變數只可以在 *.tpl.php 中使用
template.php 內的函數就不可以.......

註: Drupal5.x 的版本: http://www.joetsuihk.com/form_templates

Drupal6.0 theming 模版初探(二)

繼續鑽研
先弄清上一篇的一些疑問, 關於"需要重新載入theme, 令theme 可以使用新增的 *.tpl.php"
主站有一個官方的說明:(翻譯)

現在所有的theme 都需要註冊到資料庫(是之為theme registry). 在5.x 的環境, theme 是即場更新的. 但在6.x, theme 的每一個輸出都會經過hook_theme() 但不需要擔心, phptemplate 會幫你註冊新的theme 到hook_theme()

但有一個例外, forms表格不需要, 也不會註冊(往後的Drupal版本可以會改變做法)
更多的資源你可以參考theming 手冊

重要! 當你新增一個新的theme 函數或者新的 *.tpl.php, 你必須清空重制theme registry

你可以使用 devel module 中的 development block 來幫助你. Clear cache 連結會重制theme registry 或者使用 drupal_rebuild_theme_registry()函數(可以在themplate.php 中使用)

說明得很清楚...只是昨日找不到相關連結...

這次要修改的是原本沒有 .tpl.php 檔的一個theme 函數 theme_status_messages() theme.inc

用devel module 點擊一下任何的系統信息框
發現是來自theme_status_messages()
將theme.inc 內的 theme_status_messages() 抄到 /sites/all/garland2/status-messages.tpl.php
return 改為print:

<?php
 
global $user;
 
 
$output = '';
  foreach (
drupal_get_messages($display) as $type => $messages) {
   
$output .= "<div class="messages $type">\n";
    if (
count($messages) > 1) {
     
$output .= " <ul>\n";
      foreach (
$messages as $message) {
       
$output .= '  <li>'.$user->name.", ". $message ."</li>\n";
      }
     
$output .= " </ul>\n";
    }
    else {
     
$output .= $user->name.", ".$messages[0];
    }
   
$output .= "</div>\n";
  }
  print
$output;
?>

clear cache, 便可以看到訊息前面多了一個用戶名了
可以看到, 修改, 新增的工作都簡單了許多, 免卻了修改template.php 的麻煩

參考自:
6.x theming guide
http://drupal.org/node/171179
Converting 5.x themes to 6.x
http://drupal.org/node/132442

Drupal6.0 theming 模版初探

AttachmentSize
Image icon 94-1.gif17.34 KB
Image icon 94-2.gif1.42 KB
Image icon 94-3.gif13.18 KB

上一次的更新已經是....九月!?!?
吐血中, 讀者們...不要走.....^^
留言的....多謝你們~無言以報

入正題
從freelance 的血海之中抽身,
花了些許時間研究Drupal6.x 的theming system (模版系統)
一句說話, 驚為天人

前言
http://drupal.org/node/171188
講得很清楚, Drupal6.x 和5.x 一樣,
所有個人化, 修改代碼的工作都應該發生在 /sites 資料夾之內
這次的目標是在 /user/* 的頁面,
用戶名之後加代碼 (這次是簡單的加一個"a")

準備
Druapl6.x 的theming 修改都是屬於某一theme 的
即是說, 修改garland 之後, 用戶轉到其他theme 便看不到修改了
(當然, 有其他方法"強行"用到全部theme...)
先將 /themes/garland 抄到 /sites/themes/garland (需要自建資料夾)
雖然Drupal6.x 不會再用theme 資料夾名決定theme 名稱,
但為了分別, 還是改: /sites/themes/garland -> /sites/themes/garland2
真正的修改theme 的名稱, 就要修改garland.info -> garland2.info
theme 資料夾內的 *.info 決定theme 的名稱
當然, 順手改一下 garland2.info 內的 name 參數
先不要到administer 改theme 成garland2

另外, theme 的開發者在6.x 之後得到一個極強力的幫手,
devel module
內裏的theme developer 便是"drupal 內的 firebug"
下載devel, 解壓到 /sites/modules/devel (需要自建資料夾)
到URL: /admin/build/modules 啟用模組
你就會看到

代表安裝成功了

正題
到目標URL: /user/1
點擊theme developer 以啟用
然後你只要指到你想要修改的element 之上, theme developer 就會告訴你要修改那裏:

/modules/user/user-profile.tpl.php (你指的可能是 user_profile_category.tpl.php 但這 tpl 是包在user-profile.tpl.php 之內的)
將/modules/user/user-profile.tpl.php 抄到 /sites/themes/garland2/user-profile.tpl.php
打開 /sites/themes/garland2/user-profile.tpl.php, 改成:

<div class="profile">
a
  <?php print $user_profile; ?>
</div>

儲存, 完成.
到URL: /admin/build/themes 改用garland2 作為預設theme

結語
有了devel module, 開發快了很多很多, 免除了追蹤xhtml 來自那裏個檔案的麻煩
修改的門檻低了很多, 只要安裝了devel module, 一般人只要些少訓練就可以改theme 了
現時關於Drupal6.x theming 的資料只是剛好足夠明白基本原理
主站的 handbook 還需要很多很多教學, 例子才可以令人看得懂....
最後一點, 有點奇怪的是, theme 只可以在安裝的時候找一次theme 內的 *.tpl.php(修正1)
即是說, 轉到新的theme 之前要決定好theme 內有那些 tpl.php
只是這點比較麻煩

連結
Overriding themable output - 這次的主要參考
http://drupal.org/node/173880

修正

  1. 2008-02-20: 這是因為theme registry

作網站不只是外包廠商的事

作網站不只是外包廠商的事

令人反省的一章文章.
對外, 作為一個自由職業者, 收尾的部份總是不如意, 少有非常完滿的
因為委託人不是做技術的, 一直用"這是很少的修改"看待後續的"加一個按鈕, 加一條link" 之類的要求
用"這是維護!!"的理由要求將修改都看成維護的一部份, 必須免費
究其原因, 都因為委託人不懂一點點技術的, 不知道修改的幅度比他們想象的多得多
又因為要壓低成本, 利潤原本已經很低的外包商不願意做修改
沒完沒了

對內, 作為一個相對獨自工作的內部網站開發者
經常面對一個又一個從不知什麼地方, 什麼來頭的人的電話,
"這邊錯了, 有bug"
"那邊的資料過期了"
修改bug, 更新資料的工作一直比不上電話的速度
沒完沒了
最後麻煩只會轉到你上司的頭上
最後又是網站開發者承受

最後一句,
很認同"既然這網站已經是營銷的最大通路, 為什麼預算裡只願意花這麼小的金錢?"
內聯網既然這麼重要, 為什麼只放一個人, 而且同時兼任開發新功能, 維護, 更新等等的工作?
外人看"開發網站"真的只是連小朋友都懂的小技術??

Theming 模版雜燴

Theming 的其中一個難題一定是多瀏覽器支援的問題
巿佔最高的品牌不跟足標準, 幾乎每一個瀏覽器都"think different"
難倒, 抓狂不少開發者
但既然每一個開發者都面對這樣的問題,
在這個web2.0 的時代就自然有解決的方法

下面是一些CSS 的 framework
這些framwork 就像drupal 內建的jquery 一樣
集合一些難纏的CSS, 變作一個框
你再將你自己的內容放到裏面就可以了
用作開發新的主題應該很合用

YAML builder
一個實用的WYSIWYG framework
可以自定一些常用的元素進去
http://builder.yaml.de/

Yahoo 大廠的出品
使用不簡單, 英文說明為主
http://developer.yahoo.com/yui/grids/#available-templates

Intensivstaion
一些已經建好的常用layout
http://www.intensivstation.ch/en/templates/

Pages

Google