2007 Drupal Summer Course @ Taiwan
0. 說明
0.0 本文件的對象?
- 可以自行安裝好drupal和server
- 可以自行安裝新模組沒有問題,最好安裝過cck和views
- 會基礎的php
- 會基礎的css
=> 滿足以上條件的使用者,將可以輕鬆閱讀本文件
0.1 如何使用本文件?
Drupal Summer Course包含三個部份的內容,第一部份為cck和views的設定,第二部份為theme開發的小技巧,第三部份為module開發技巧,內容大部分為大綱式,可能有許多圖片缺乏文字說明,或許多條列式的綱要缺乏文字。在瀏覽本文件的過程中,可以隨時點右上角的「2007 drupal summer course」圖樣,便可看到下拉式目錄。
在整個資料夾中,除了此文件所用到的檔案之外,在example資料夾中另有課程中使用到的範例(cck, views, theme, module),cck和views的範例需要透過該模組的import,將文字檔的內容貼入。theme和module的範例,則按照drupal安裝新theme和module方式安裝即可啟用。
0.2 授權條款
本文件以創用CC-姓名標示-非商業性-相同方式分享方式授權,也表示歡迎大家共筆修改此份文件,有任何筆記能夠填入回應,將會對所有本文件的使用者都能受益。
所有本文見中原始碼,附加檔案的範例原始碼,皆以GNU GPL Version 2方式授權。
1. Drupal無限可能的原因:CCK + Views
1.1 CCK設定詳解
1.1.1 content types設定(詳看範例 examples/cck_examples/test_type.txt )
- type: unique name,資料庫的table名稱、url名稱、盡量不要隨意更改
- body: 需要body欄位和不需要body欄位,不需要就把此清空
- 字數:中文目前仍有問題,請不要使用
- promote和sticky:重要好用的兩個mark
1.1.2 建立、設定群組 (add group)
- label:值先填英文,submit後再填中文
- help: 送出時畫面的說明文字
- descriptions: 呈現文章時的說明文字
1.1.3 建立、設定欄位: (add field)
- label值先填英文,submit後再填中文
- 文章包含各種元素,基本text,integer,decimal,進階email, url, video, image, audio...
- 元素可用不同的表單形式呈現:
- Text Field、Autocomplete Text Field
- Select list、Check boxes/radio buttons
- Single on/off checkbox
1.1.4 排列、管理欄位:(manage fields)
title、body、taxonomy是定義死的,其他可以隨著group的定義隨意更動
1.1.5 顯示設定:(display fields)
p.s. 文章發表後的設定,非欄位呈現設定
- label: 可以與呈現值在同一行(inline)、在上面(Above)、隱藏(hidden)
- 摘要和全文可用不同的方式呈現
- 不同格式的欄位會有對應的format,數字、日期等等(如摘要和全文)
- group可以設定成既定的fieldset或不需要style
- 亦可以隱藏值不顯示,做系統用途(如e-mail欄位)
1.2 Views設定詳解
1.2.1 基礎設定,新增一個view
page基本設定流程(增加一個頁面)
- basic: 填上view的unique name,設定權限和簡易描述
- page: provide page view打勾表示啟用,寫一個url如test,選view type如teaser,設定title留白就沒有,勾選分頁與否,勾選nodes一頁幾個0表示全顯示
- Save後就去該url看看,如http://xxx.org/test
block基本設定流程(增加一個區塊)
- basic: 同上面page
- block: provide block打勾表示啟用,block跟page幾乎一樣,除了不能分頁,另more的選項只有在同一個view也有page view時出現的read more連結才會有效
- save後多一個步驟,得去admin/build/block啟用,就可以看到名字為view設定name的新區塊
1.2.2 基礎應用(範例 examples/views_examples/views_ex_simple1-4.txt )
- fields:提供table、list這些view type需要呈現的欄位,也廣於被第三方模組使用、亦是進階theme wizard要更改views呈現版型的基礎(詳版型)
- arguments: 提供利用網址為篩選條件的功能,可以大量創造views,如test/jimmy呈現只有jimmy的文章,jimmy可為任何使用者的user name
- filters: 根據各種條件篩選既有的nodes,如顯示某文章類型的nodes,某分類的nodes,最常使用到的進階功能。
- exposed filters: 由上面設定的filter延伸出來的,並可給瀏覽者自行選擇篩選要看的文章
- sort criteria: 提供非table view type時的排列,如置頂文章(sticky)最先顯示,亦可依日期排列。
1.2.3 進階應用(範例 examples/views_examples/views_ex_adv1-4.txt )
- views進階應用1: 根據argument顯示對應的block:ex. 相關檔案
- 原理:利用arguments的進階Argument Handling Code功能,傳回自訂的id給定義好的arguments篩選,範例傳回網址中node/nid的數字給既有的node reference argument篩選
if (arg(0) == 'node' && is_numeric(arg(1))) {
return array(arg(1));
}
- 原理:利用arguments的進階Argument Handling Code功能,傳回自訂的id給定義好的arguments篩選,範例傳回網址中node/nid的數字給既有的node reference argument篩選
- views進階應用2: 多層次的arguments設定:ex. 時間篩選
- 原理:利用多個arguments達到產生大量頁面的功能,並自動給予標題
- 原理:利用多個arguments達到產生大量頁面的功能,並自動給予標題
- views進階應用3: argument的進階應用:ex. 使用者文章頁面(取代tracker)
- 原理:將views的argument結合既有的模組網址,提供大量user/*/post的頁面
- 原理:將views的argument結合既有的模組網址,提供大量user/*/post的頁面
- views進階應用4: menu範例:ex. 產品一覽
- 原理:定義page view中的menu,再加以與既有的menu模組應用,快速產生網站頁面
- 原理:定義page view中的menu,再加以與既有的menu模組應用,快速產生網站頁面
1.3 瞭解content type、nodes、views、和taxonomy的定位
- content type: 就是一種文件的形式、內容。譬如說,卡片的格式和書信的格式不同,公文的格式跟相片集的格式不同。
- node: 就是每一個單一的文件,在drupal被視為節點,每一個單一文件是依據不同的形式發表出來。
- taxonomy terms: 就是為該文件標注分類,跟文件的「形式」不同。分類的重要任務,是為了將不同形式的文件串連在一起整合運用,或對文件做歸檔整理以供日後用途,並且可以定義樹狀結構表現出不同類別的父子關係。他的範疇可能包含每一個node(如tag),也可能是針對某幾種文件的形式來做分類。如公文裡頭可以分成不同年度,書信可以分成札記和散文,相片文件可以分成不同的相簿...等。
- views: views如名,就是專門管理呈現的部份。因為一個站可能有上萬個nodes,views可以用各種交叉條件篩選出畫面中想呈現的nodes(通常是文件)。可能是不同分類(taxonomy)不同文章形式(content type)還是不同的欄位(年度)的交集。views也提供呈現的方式的設定,如地圖的方式、表格的方式、摘要文的方式、全文的方式、清單的方式...等。
p.s. 在drupal裡頭,分類、content type的field、和content type常常會有重疊使用、混用的情形,如文件的年度可能當成分類或是一個文章類型的欄位皆可以,釐清每個的用途不同來設計架構因此很重要。
1.4 Case study:建立報名表單
- 呈現的樣稿(多篇文章樣稿 ex 摘要列表,單篇文章樣稿 ex. 搭配縮圖)
- 欄位的細部規劃(email、姓名、年齡、類型、縣市、blog url、內容文)
- 模組的選擇(email、url、captcha、image field、image cache)
- content type 和 taxonomy 區分與先期規劃(類型用cck的field,縣市用taxonomy)
- 著手建立欄位 => admin/content/types/add
- 設定views(摘要呈現列表搭配縮圖1、單篇文章搭配縮圖2)
p.s. 事前確切的規劃,事後省力
1.5 以CCK + Views出發,有各種網站的解決方案
彈性的目的,就是為了讓你展現創意!
- 活動報名表:cck + views + email + captcha + form store
- 各種行事曆:cck + views + calendar + date
- time base calendar:cck + views + timeline
- 地圖日誌:cck + views + gmap
- 公文流程:cck + views + workflow + actions + CCK Field Permissions
- 討論區:cck + views + taxonomy + taxonomy access control lite + user points
- xxx review:cck + views + fivestar + review
- 電子報:cck + views + simple news + mime mail + calendar
- audio、video review:cck + views + five star + flash video + ....
- social network:og group + private message
- wiki like:cck + wikitools + tinymce + freelinking + ...
2. 超彈性版型~調整drupal版型一點也不難
2.1 PHPTemplate架構及概念介紹
2.1.1 theme engin、theme與loading流程
2.1.2 由page.tpl.php開始出發的結構
2.1.3 框架(html tag - div)、內容(變數)、樣式(style)分離的template
2.2 PHPTemplate的版型開發小技巧
詳細請安裝範例版型 examples/theme_examples
tips1: 子版型
新增 yourtheme/subtheme_name/style.css
tips2: 不同content type的版型node-type.tpl.php
新增 yourtheme/node-typename.tpl.php
如bluemarine/node-story.tpl.php
tips3: 首頁版型page-front.tpl.php
新增 yourtheme/page-front.tpl.php
tips4: 自定義regions
在yourtheme/template.php 檔案中增加yourtheme_regions()函數
tips5: 自定義版型變數
在yourtheme/template.php 檔案中增加_phptemplate_variables()函數
tips6: 複寫預設theme
- 拷貝module既有的function theme_foobar() 至 template.php
- 改名為 phptemplate_foobar(),並調整裡頭原始程式
- 完成!之後系統便會直接呼叫phptemplate_foobar,而不會經過function theme_foobar
2.3 Case Study:以Region實現Drupal超彈性版型
2.3.1 為何使用regions?
- 既有block管理結合,提供網站管理者一個好的後台
- 保留未來無痛升級的可能性
- theme based
2.3.2 如何實現?
- 畫出layout,規劃regions
- 到template.php實現function theme_region() - 同2.2 tip4
- 找到page.tpl.php,將定義的region print出來,加上class和id
- 到style.css定義region的樣式
這個範例很遜嗎?看看進階苦勞網首頁的region規劃
2.4 如何使用Drupal與美工合作實戰分享
2.4.1 你跟什麼樣的伙伴合作?
- 很純的美工
以美工軟體提供三面基本版型美工稿(首頁、摘要文章列、內頁+回應串) +
psd檔完整的page切好圖用透明圖層(icon、logo、背景分層),並能給定css的色碼 + - 網頁美工設計者
除了第一種人的能力之外
能過將三面的美工稿,轉換成html頁面 +++
能夠做出像open web design好的html + css layout,結構化網頁的元素 ++++ - 有美工設計能力的程式設計師
能夠做出wordpress的版型 http://themes.wordpress.net/ ++++
能夠做出css zen garden的版型 +++++
drupal的版型就是小case,theme就可以交給對方
2.4.2 與伙伴的分工與溝通
-
以css為主的版型設計工作項目
- 各種背景圖片、logo圖片。
- 進階css與基本html元素配置,也就是排版(layout)
- php程式撰寫,也就是進階的功能
- 可以溝通的方向
- 溝通1-大處著眼:全站統一的風格,乃至於元素。如header、footer、logo...等
- 溝通2-小處著手:單篇node、單一block的風格,首頁區域功能規劃,及需要特殊的美工,如mission的區域
- 溝通3-程式的工作:程式得讓美工得瞭解region、block和page、node和comment的定義,依據這些不同區域來設計並組合
- 溝通4-美工的工作:切圖與畫版為美工的職責,背景、圓角、清單及小icon的切圖製作...等等,才不至於讓程式搞到沒力
- *溝通5-模糊範疇:css誰做?class、id命名誰做?html的tag排列?端看誰有能力執行layout的部份
3. 超快速開發,開發drupal模組實戰指引
3.1 Drupal模組開發前:hook,form API,database API原理簡介
3.1.1 Database API
reference: http://api.drupal.org/api/5/group/database
3.1.2 FROM API
reference: http://api.drupal.org/api/5/file/developer/topics/forms_api.html
http://api.drupal.org/api/5/file/developer/topics/forms_api_reference.html
3.1.3 hook system
- hook_xxx運作原理
- hook_nodeapi的流程:
node -> blog_nodeapi -> forum_nodeapi -> comment_nodeapi -> ..
-
comment.module 範例程式碼
reference: http://api.drupal.org/api/5/function/hook_nodeapi
function comment_nodeapi(&$node, $op, $arg = 0) { switch ($op) { case 'load': return db_fetch_array(db_query("SELECT last_comment_timestamp,last_comment_name, comment_count FROM {node_comment_statistics} WHERE nid = %d", $node->nid)); break; // bala bala... - drupal hook system的重要性
- 讓模組可以個別獨立,又協同運作,擁有模組概念中良好的獨立,但不會因此就失去了重複利用code的機會
- 不需要更該、熟知其他模組的code(API的特性)
- 讓開發者可節省時間,直接用既有的範例和source張貼下手,僅做小幅度更改就可達到完整功能,事半功倍
- 在程式中如何使用hook?
- // 這段程式碼會呼叫到function taxonomy_get_term()函數,從database中載入一個分類的所有資訊
$value = module_invoke('taxonomy', 'get_term', $value); // from node.module - // 這段程式碼呼叫所有的 function hook_link,將所有與node相關的連結傳回來,comment_link()就是其中之一
$node->links = module_invoke_all('link', 'node', $node, !$page);
3.2 一個最簡單的模組範例
詳細請安裝範例模組 examples/module_examples
/* */ //====================================================================== ; module_name.info: test.info name = test description = Just a test module package = testing package version = VERSION
/* */ //====================================================================== // module name: test // $maycache是看看是否要從database裡頭傳回該user的menu cache // 通常與使用者id變換無關的menu皆可以視情況cache起來,增加menu loading的效能 function test_menu($maycache){ $items = array(); if($maycache){ $items[] = array( 'path' => 'simple_test', 'title' => t('Test page'), 'callback' => 'test_page', // just naming yourself 'callback arguments' => array('123','abc'), 'access' => user_access('access content'), 'type' => MENU_CALLBACK ); } else{ // !$maycache
} return $items; }
function test_page($arg1, $arg2){ $output = 'test'.$arg1.$arg2; return $output; // test123abc //print $output; }
3.3 快速開發的撇步
- 開發前
- 花功夫review及整理現存模組(對同類型模組的比較review,何不丟上drupal taiwan呢?)
- 花1小時看相關模組的code,勝過3小時埋頭苦幹
- drupal taiwan社群討論~增長及累積資源,互利彼此
- 規劃、架構你的模組(用圖畫出來,menu、page、admin、hook、theme)
- 架構盡量不要與node、taxonomy、user、block幾個核心的模組脫離,好處多多
- 開發中
- 善用既有資源,模組的issue、他人模組的code(注意授權)、drupal.org、api
- 善用核心提供的hook,與既有系統合作無間(_taxonomy、_block、_link、_nodeapi)
- 開發後
- open已經開發的source,讓open source社群幫忙debug
- 寫下文件和對程式的註解,以幫助自己和他人後續的維護使用
3.4 進階模組範例(+ form)
function test_menu($maycache){ $items = array(); if($maycache){ $items[] = array( 'path' => 'simple_test', 'title' => t('Test page'), 'callback' => 'test_page', // just naming yourself 'callback arguments' => array('123','abc'), 'access' => user_access('access content'), 'type' => MENU_CALLBACK ); $items[] = array( 'path' => 'simple_test2', 'title' => t('Test page2'), 'callback' => 'test_page2', // just naming yourself 'access' => user_access('access content'), 'type' => MENU_CALLBACK ); } else{ // !$maycache
} return $items; } function test_page2(){ // edit this form global $user; $edit['form_name'] = $user->created; $output = drupal_get_form('test_form', $edit); return $output; }
function test_form($edit, $title = NULL) { $form = array(); $form['new_name'] = array( '#type' => 'fieldset', '#title' => t('field set title'), '#collapsible' => TRUE, '#collapsed' => FALSE, ); $form['new_name']['form_name'] = array( '#type' => 'textfield', '#title' => t('text form title'), '#default_value' => $edit['form_name'], '#description' => t('text form test sample'), ); $form['submit'] = array('#type' => 'submit', '#value' => t('Save')); return $form; }
function test_form_validate($form_id, $form_values) { if (!is_numeric($form_values['form_name'])) { form_set_error('', t('You must fill a digits number from 0 to 9')); } }
function test_form_submit($form_id, $form_values) { global $user; db_query("UPDATE {users} SET created = %d WHERE uid = %d", $form_values['form_name'], $user->uid); drupal_set_message(t('Your form has been saved.')); }
3.5 debug指引
- devel module
- php: print和drp(若有裝devel)
- drupal_set_message(), session和換頁的debug
- 只要有網址就有menu,從hook_menu開始下手尋找問題
- 找尋user路徑下的撰寫方式:user_menu => user_login
- jquery, javascript => firefox + firebug
- ......
3.6 還有什麼不知道?
- 怎麼為自己的module做hook?難度:*****
- 如何開發與cck相關的模組?難度:******
- 如何開發與views的模組?難度:*******
- jquery,AJAX,難度:*******