<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xml:base="http://www.joetsuihk.com" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
 <title>Tabbed Block</title>
 <link>http://www.joetsuihk.com/free_tags/tabbed_block</link>
 <description>The taxonomy view with a depth of 0.</description>
 <language>en</language>
<item>
 <title>Tabbed Block</title>
 <link>http://www.joetsuihk.com/node/84</link>
 <description>&lt;p&gt;This is a module that you can embed different blocks into one with tabs.&lt;br /&gt;
Those tabs switch with javascript based on jquery, shorten your sidebars without reducing the content of your page.&lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;
The offical homepage on drupal.org is opened:&lt;br /&gt;
&lt;a href=&quot;http://drupal.org/project/tabbed_block&quot; title=&quot;http://drupal.org/project/tabbed_block&quot;&gt;http://drupal.org/project/tabbed_block&lt;/a&gt;&lt;br /&gt;
The below svn is outdated, please use files on Drupal.org, and svn will dropout from the site soon.&lt;br /&gt;
&lt;/strong&gt;&lt;br /&gt;
svn address: &lt;a href=&quot;http://www.joetsuihk.com/svn/drupal_modules/tabbed_block/trunk&quot; title=&quot;http://www.joetsuihk.com/svn/drupal_modules/tabbed_block/trunk&quot;&gt;http://www.joetsuihk.com/svn/drupal_modules/tabbed_block/trunk&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;這個模組可以將多個區塊整合到一個之中,&lt;br /&gt;
並使用jquery 這個javascript 庫來幫助使用者瀏覽&lt;br /&gt;
令你的左右兩邊的導航條縮短但又不用放棄某些內容&lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;
這模組已經放到 Druapl 主站上的模組專頁:&lt;br /&gt;
&lt;a href=&quot;http://drupal.org/project/tabbed_block&quot; title=&quot;http://drupal.org/project/tabbed_block&quot;&gt;http://drupal.org/project/tabbed_block&lt;/a&gt;&lt;br /&gt;
下面的svn 已經不會再更新, 請到drupal.org 內查看更新&lt;br /&gt;
&lt;/strong&gt;&lt;br /&gt;
svn 地址: &lt;a href=&quot;http://www.joetsuihk.com/svn/drupal_modules/tabbed_block/trunk&quot; title=&quot;http://www.joetsuihk.com/svn/drupal_modules/tabbed_block/trunk&quot;&gt;http://www.joetsuihk.com/svn/drupal_modules/tabbed_block/trunk&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://www.joetsuihk.com/files/tabbed_block1.png&quot; /&gt;&lt;br /&gt;
&lt;img src=&quot;http://www.joetsuihk.com/files/tabbed_block2.png&quot; /&gt;&lt;/p&gt;
</description>
 <comments>http://www.joetsuihk.com/node/84#comments</comments>
 <category domain="http://www.joetsuihk.com/free_tags/drupal">Drupal</category>
 <category domain="http://www.joetsuihk.com/free_tags/tabbed_block">Tabbed Block</category>
 <pubDate>Fri, 13 Apr 2007 09:12:17 -0700</pubDate>
 <dc:creator>JOE</dc:creator>
 <guid isPermaLink="false">84 at http://www.joetsuihk.com</guid>
</item>
<item>
 <title>Tabbed Block 1.0.0</title>
 <link>http://www.joetsuihk.com/tabbed_block_1_0_0</link>
 <description>&lt;p&gt;這是第一個正式發佈版Tabbed Block&lt;/p&gt;
&lt;p&gt;這個模組可以將多個區塊整合到一個之中,&lt;br /&gt;
並使用jquery 這個javascript 庫來幫助使用者瀏覽&lt;br /&gt;
令你的左右兩邊的導航條縮短但又不用放棄某些內容&lt;/p&gt;
&lt;p&gt;和v0.6a1 的分別主要為臭蟲修正.&lt;/p&gt;
&lt;p&gt;First Official release of Tabbed Block.&lt;/p&gt;
&lt;p&gt;This is a module that you can embed different blocks into one with tabs.&lt;br /&gt;
Those tabs switch with javascript based on jquery, shorten your sidebars without reducing the content of your page.&lt;/p&gt;
&lt;p&gt;Mainly bugs fix between 0.6a1.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://www.joetsuihk.com/files/tabbed_block1.png&quot; /&gt;&lt;br /&gt;
&lt;img src=&quot;http://www.joetsuihk.com/files/tabbed_block2.png&quot; /&gt;&lt;/p&gt;
</description>
 <comments>http://www.joetsuihk.com/tabbed_block_1_0_0#comments</comments>
 <category domain="http://www.joetsuihk.com/free_tags/drupal">Drupal</category>
 <category domain="http://www.joetsuihk.com/free_tags/tabbed_block">Tabbed Block</category>
 <pubDate>Sun, 13 May 2007 01:04:06 -0700</pubDate>
 <dc:creator>JOE</dc:creator>
 <guid isPermaLink="false">54 at http://www.joetsuihk.com</guid>
</item>
<item>
 <title>Tabbed Block 0.6.0-alpha1</title>
 <link>http://www.joetsuihk.com/tabbed_block_0_6_0_alpha1</link>
 <description>&lt;p&gt;V0.6 中終於提供多block 的環境&lt;br /&gt;
用戶可以新增不限數量的 tabbed block&lt;br /&gt;
設定介面也隨之改變&lt;br /&gt;
留意, 此為alpha 版, 只應使用於測試後(雖然已經花多了時間除蟲)&lt;br /&gt;
每一 tabbed_block 對應AJAX 刷新, IE, FF 設定可能等等&lt;/p&gt;
&lt;p&gt;請先移除v0.5 tabbed block, 覆蓋v0.6, 安裝&lt;/p&gt;
&lt;p&gt;v0.6 finally present with multi tabbed-block!&lt;br /&gt;
administer can add blocks without limit.&lt;br /&gt;
because of this, setting UI changes a little.&lt;br /&gt;
warning that this is a alpha release, only apply on test sites please.&lt;br /&gt;
every tabbed block with AJAX refresh, on IE, FF etc etc.....&lt;/p&gt;
&lt;p&gt;Please uninstall v0.5 first, overwrite with v0.6, install.&lt;/p&gt;
</description>
 <comments>http://www.joetsuihk.com/tabbed_block_0_6_0_alpha1#comments</comments>
 <category domain="http://www.joetsuihk.com/free_tags/development">Development</category>
 <category domain="http://www.joetsuihk.com/free_tags/drupal">Drupal</category>
 <category domain="http://www.joetsuihk.com/free_tags/tabbed_block">Tabbed Block</category>
 <pubDate>Wed, 02 May 2007 07:38:50 -0700</pubDate>
 <dc:creator>JOE</dc:creator>
 <guid isPermaLink="false">44 at http://www.joetsuihk.com</guid>
</item>
<item>
 <title>2007-04-26 Tutorial on Drupal form API, Drupal 表單使用教學</title>
 <link>http://www.joetsuihk.com/2007_04_26_tutorial_on_drupal_form_api</link>
 <description>&lt;p&gt;原本打算先寫一個cck 的教學&lt;br /&gt;
但因為工作上的需要, 急需對Drupal form API 有深一點的認知&lt;br /&gt;
所以就埋頭苦幹, 翻讀又翻讀Drupal 主站的手冊&lt;br /&gt;
定要打好form 處理的根基&lt;/p&gt;
&lt;p&gt;本文既翻譯官方手冊關於form API的一些部分&lt;br /&gt;
再加上自己的一點研發而成&lt;/p&gt;
&lt;p&gt;表單乃任何應用系統的中心&lt;br /&gt;
令使用者和系統之間的交流具體化&lt;br /&gt;
確實請求, 遞交的介面, 公用接口等&lt;br /&gt;
如果沒有表單, 用戶只可被動的接受系統的一切&lt;br /&gt;
用戶的要求並不能傳到系統中,&lt;br /&gt;
像啞巴, 不能表達自己的訴求&lt;br /&gt;
用了表單, 用戶可以在系統允許的情況之下要求&lt;br /&gt;
如排序, 提交等等&lt;br /&gt;
所以一個小型的模組很可能已經需要使用表單,&lt;br /&gt;
作了解用戶的設定, 請求之用&lt;br /&gt;
可惜, Drupal 的 form API 使用概念上和html form 有頗大差異&lt;br /&gt;
但的確簡化了傳統上 顯示, 處理, 儲存 三個部分的處理&lt;/p&gt;
&lt;p&gt;用form API 生成表單, 大概有三個地方可放代碼&lt;br /&gt;
*.module 文件, template 文件, block boxes.(hook_form_alter() 只用作修改, 而非建設表單)&lt;/p&gt;
&lt;p&gt;*.module 文件中放代碼這方法為主流, 也正統, 又萬能&lt;br /&gt;
官網的教學全都集中在這個地方.&lt;br /&gt;
主要目的多是開發一個新的模組, 要設定模組的各參數而使用表格&lt;br /&gt;
學習上, 因為有很多現成模組的例子, 算是簡單&lt;br /&gt;
生成方法要從hook_menu 說起&lt;br /&gt;
user.module 為例:&lt;br /&gt;
&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;$items&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[] = array(&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;path&#039; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;gt; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;user&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;title&#039; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;gt; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;t&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;User account&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;),&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;callback&#039; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;gt; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;drupal_get_form&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;callback arguments&#039; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;gt; array(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;user_login&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;),&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;access&#039; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;gt; !&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$user&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;uid&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;type&#039; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;gt; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;MENU_CALLBACK&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;&lt;br /&gt;
設定:&lt;br /&gt;
路徑(path)                             /%DRUPAL%/user&lt;br /&gt;
頁面標題(title)                        t(&#039;User account&#039;) (t()為可以翻譯)&lt;br /&gt;
存取時轉到函數(callback)           drupal_get_form()&lt;br /&gt;
函數參數(callback arguments)    array(&#039;user_login&#039;)&lt;br /&gt;
權限(access)                          !$user-&amp;gt;uid (指已經登入者)&lt;/p&gt;
&lt;p&gt;實際上呼叫函數drupal_get_form(&#039;user_login&#039;)&lt;br /&gt;
drupal_get_form(&#039;user_login&#039;) 呼叫 user_login(),&lt;br /&gt;
&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;user_login&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(){&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;略&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;...&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;name&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;] = array(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;#type&#039; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;gt; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;textfield&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;#title&#039; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;gt; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;t&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;Username&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;#size&#039; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;gt; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;60&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;#maxlength&#039; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;gt; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;USERNAME_MAX_LENGTH&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;#required&#039; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;gt; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;TRUE&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;#attributes&#039; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;gt; array(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;tabindex&#039; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;gt; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;1&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;),&lt;br /&gt;&amp;nbsp; );&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;略&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;...&lt;br /&gt;&amp;nbsp; return &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;&lt;br /&gt;
例子中定義了一個textfield (#type)&lt;br /&gt;
field 的題目(類似說明)為t(&#039;Username&#039;) (t()為可以翻譯)&lt;br /&gt;
等等, 詳細參數表請參考API &lt;a href=&quot;http://api.drupal.org/api/5/file/developer/topics/forms_api_reference.html&quot; title=&quot;http://api.drupal.org/api/5/file/developer/topics/forms_api_reference.html&quot;&gt;http://api.drupal.org/api/5/file/developer/topics/forms_api_reference.ht...&lt;/a&gt;&lt;br /&gt;
user_login() 最後返回變數$form, 給drupal_get_form()&lt;br /&gt;
表單顯示輸出部份到此完成&lt;br /&gt;
只要設定好 user_login, hook_menu,&lt;br /&gt;
其餘的部分(action, method, form_id, form tags)由Drupal 負責&lt;/p&gt;
&lt;p&gt;接著是確認表單有效的步驟: ( 按了submit, button type 後 )&lt;br /&gt;
續用user_login 為例,&lt;br /&gt;
定義一個函數: 函數名_validate()&lt;br /&gt;
&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;user_login_validate&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form_id&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form_values&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;) {&lt;br /&gt;&amp;nbsp; if (&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form_values&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;name&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;]) {&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #FF8000&quot;&gt;//略&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;&lt;br /&gt;
$form_id 為 函數名&lt;br /&gt;
$form_values 為array, 像一般的$_POST 般使用&lt;br /&gt;
_validate() 認證錯誤的話, 使用form_set_error(&#039;login&#039; , $message);&lt;br /&gt;
Drupal 自動跳回表單&lt;br /&gt;
否則不用返回, Drupal 跳到儲存函數&lt;/p&gt;
&lt;p&gt;儲存函數: 函數名_submit&lt;br /&gt;
(按下type 為 submit 的元素後)&lt;br /&gt;
&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;user_login_submit&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form_id&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form_values&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;) {&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #FF8000&quot;&gt;/**&lt;br /&gt;*&amp;nbsp; 數據庫處理等等&lt;br /&gt;*/&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$message &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;= &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;submit complete&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&amp;nbsp; return &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&quot;/user&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$user&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;uid&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;&lt;br /&gt;
$form_id 為 函數名&lt;br /&gt;
$form_values 為array, 像一般的$_POST 般使用&lt;br /&gt;
返回值為路徑, Drupal 會跳到該路徑&lt;br /&gt;
並顯示$message&lt;/p&gt;
&lt;p&gt;到此, 基本, 主要, 一般使用form API 的方法完成&lt;/p&gt;
&lt;p&gt;Template 文件上使用form API 實際上違反了MVC 的概念&lt;br /&gt;
但卻能快速的實現表單, 添加和修改頁面隨意&lt;br /&gt;
如 &quot;加一個表單到關於我們, 填電話吧&quot; 之類的請求&lt;br /&gt;
用一個模組加上hook_form_alter, hook_node_api 會令模組管理混亂&lt;br /&gt;
系統效能下降的問題&lt;br /&gt;
而更麻煩的是開發時間長&lt;br /&gt;
使用template 能減輕一定程度的工作量,&lt;br /&gt;
特別當改動少, 但又不得不改代碼, CSS 不能代勞時.&lt;/p&gt;
&lt;p&gt;使用概念跟使用druapl_get_form() 大致相約&lt;br /&gt;
template 中一樣要定義三個函數, 如&lt;br /&gt;
&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;user_login2&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(){&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[]=array(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ..........................&lt;br /&gt;&amp;nbsp; );&lt;br /&gt;&amp;nbsp; return &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;}&lt;br /&gt;&lt;br /&gt;function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;user_login2_submit&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form_id&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form_values&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;){&lt;br /&gt;&amp;nbsp; .............&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;user_login2_validate&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form_id&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form_values&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;){&lt;br /&gt;&amp;nbsp; .............&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;print_r &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;drupal_get_form&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;user_login2&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;));&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;最後用一句 print_r 就可以了,&lt;br /&gt;
Drupal 會顯示表單.&lt;br /&gt;
也使用 user_login2_validate() 確認&lt;br /&gt;
user_login2_submit() 提交&lt;/p&gt;
&lt;p&gt;但留意, 切忌過份使用, 否則只會做成維護的困難&lt;br /&gt;
又,&lt;br /&gt;
如果只改動現有模組, 可先作處理, 再呼叫原模組:&lt;br /&gt;
&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;user_login2&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(){&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[] = &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;user_login&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;();&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[] = array(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ....&lt;br /&gt;&amp;nbsp; );&lt;br /&gt;}&lt;br /&gt;function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;user_login2_submit&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form_id&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form_values&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;){&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #FF8000&quot;&gt;//more operation here&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;user_login&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form_id&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form_values&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;至於block boxes,&lt;br /&gt;
block 可以自己定制, 可以使用php code內建到block&lt;br /&gt;
在site build-&amp;gt;block 內有add block 選項&lt;br /&gt;
code 的使用和template 使用form API 的方法一樣&lt;br /&gt;
不再重覆, 主要使用print_r(drupal_get_form())&lt;br /&gt;
但值得一提的是block 的擺放位置, 如加上panels&lt;br /&gt;
幾乎可以放到任何位置, block 又可以設定何時顯示, 何時隐藏&lt;br /&gt;
又開發快速&lt;br /&gt;
唯一缺點, 如果php 代碼有錯, 將會做成修改不能的錯誤&lt;br /&gt;
要手動到資料庫修改, 故只適用於對php 非常熟悉的人使用&lt;/p&gt;
&lt;p&gt;Originally want to write a tutorial about cck first.&lt;br /&gt;
However, because of my job, there is an emergency that i need to have a deeper knowledge about Drupal&#039;s form API.&lt;br /&gt;
So here comes hours ad hours study, rushing through drupal&#039;s handbook,&lt;br /&gt;
build up so solid base about form.&lt;/p&gt;
&lt;p&gt;form system is a concrete base of any application.&lt;br /&gt;
it makes the communication between user and  system become practical, applicatable,&lt;br /&gt;
include confirm requests, submit interface, public sockets etc etc.&lt;br /&gt;
if there is no forms at all, users can only accept the information from server passively.&lt;br /&gt;
user&#039;s request cannot be sent to server,&lt;br /&gt;
like mute, who cannot present themselves.&lt;br /&gt;
under forms, users can submit request upon their needs,&lt;br /&gt;
for example sorting or submit etc etc.&lt;br /&gt;
as a result, there may be already a need for forms even inside a small module.&lt;br /&gt;
but unluckily, the concept between Drupal&#039;s form API and HTML form is very different,&lt;br /&gt;
in terms of three core part of form: presentation, process, save.&lt;/p&gt;
&lt;p&gt;To use from API to generate forms, there are three places that your code may place&lt;br /&gt;
*.module file, templates, boxes block. ( hook_form_alter() can only edit a form, but not create one )&lt;/p&gt;
&lt;p&gt;form API inside *.module is the most popular method, Drupal style, and also powerful.&lt;br /&gt;
the tutorial inside drupal.org is mainly focus in this scoop.&lt;br /&gt;
This method is mainly used to configure the parameters of the module, during development a new module.&lt;br /&gt;
This method ie relatively easy to learn as there is many existing modules that you can refer to.&lt;br /&gt;
the start point is hook_menu():&lt;br /&gt;
use user.module as an example,&lt;br /&gt;
&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;$items&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[] = array(&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;path&#039; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;gt; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;user&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;title&#039; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;gt; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;t&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;User account&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;),&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;callback&#039; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;gt; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;drupal_get_form&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;callback arguments&#039; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;gt; array(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;user_login&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;),&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;access&#039; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;gt; !&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$user&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;uid&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;type&#039; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;gt; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;MENU_CALLBACK&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;&lt;br /&gt;
details:&lt;br /&gt;
path                       /%DRUPAL%/user&lt;br /&gt;
title                        t(&#039;User account&#039;)    (t()means translatable)&lt;br /&gt;
callback                   drupal_get_form()&lt;br /&gt;
callback arguments    array(&#039;user_login&#039;)&lt;br /&gt;
access                    !$user-&amp;gt;uid           (means logged-in user)&lt;/p&gt;
&lt;p&gt;in practical, this will have call a function drupal_get_form(&#039;user_login&#039;)&lt;br /&gt;
drupal_get_form calls user_login():&lt;br /&gt;
&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;user_login&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(){&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #FF8000&quot;&gt;//...some code before...&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;name&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;] = array(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;#type&#039; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;gt; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;textfield&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;#title&#039; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;gt; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;t&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;Username&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;#size&#039; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;gt; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;60&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;#maxlength&#039; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;gt; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;USERNAME_MAX_LENGTH&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;#required&#039; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;gt; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;TRUE&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;#attributes&#039; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;gt; array(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;tabindex&#039; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;gt; &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;1&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;),&lt;br /&gt;&amp;nbsp; );&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #FF8000&quot;&gt;//...some more code...&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;return &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;&lt;br /&gt;
In this example, it defines a textfield by #type,&lt;br /&gt;
the title of this field is Username (t()means translatable)&lt;br /&gt;
etc etc. and the parameters reference: &lt;a href=&quot;http://api.drupal.org/api/5/file/developer/topics/forms_api_reference.html&quot; title=&quot;http://api.drupal.org/api/5/file/developer/topics/forms_api_reference.html&quot;&gt;http://api.drupal.org/api/5/file/developer/topics/forms_api_reference.ht...&lt;/a&gt;&lt;br /&gt;
finally, user_login() return the $form variable, back to drupal_get_form()&lt;br /&gt;
the output part of form finished.&lt;br /&gt;
you only have to setup user_login, hook_menu, the elements inside the form,&lt;br /&gt;
the rest part( action, method, form_id, form tags ) will left to Drupal.&lt;/p&gt;
&lt;p&gt;next is the validation of form( by pressing any button, submit type ):&lt;br /&gt;
user_login() as example again,&lt;br /&gt;
define a new function inside *.module, named function _name_validate()&lt;br /&gt;
&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;user_login_validate&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form_id&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form_values&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;) {&lt;br /&gt;&amp;nbsp; if (&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form_values&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;name&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;]) {&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #FF8000&quot;&gt;// some code&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;&lt;br /&gt;
$form_id is the name of the form function,&lt;br /&gt;
$form_values is an array, like normal $_POST,&lt;br /&gt;
if validation fails, you may use form_set_error(&#039;login&#039; , $message);&lt;br /&gt;
Drupal will jump back to the form&lt;br /&gt;
otherwise, drupal will jump to save process.&lt;/p&gt;
&lt;p&gt;save function: function_name_submit()&lt;br /&gt;
(when press element that is &#039;submit&#039; type)&lt;br /&gt;
&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;user_login_submit&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form_id&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form_values&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;) {&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #FF8000&quot;&gt;/**&lt;br /&gt;*&amp;nbsp; database process&lt;br /&gt;*/&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$message &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;= &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;submit complete&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&amp;nbsp; return &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&quot;/user&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$user&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;uid&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;&lt;br /&gt;
$form_id is the name of the form function,&lt;br /&gt;
$form_values is an array, like normal $_POST,&lt;br /&gt;
return the path that will be redirected,&lt;br /&gt;
and display $message&lt;/p&gt;
&lt;p&gt;up to this point, the basic use of form API finish.&lt;/p&gt;
&lt;p&gt;The use of form API inside template file actually contradict the MVC concept,&lt;br /&gt;
but this method can build up form quickly, edit them quickly.&lt;br /&gt;
for example, a need of &quot;add a form to about us, user may enter their phone number&quot;&lt;br /&gt;
this kind of need is not worth to open a new module because of performance, long develop time&lt;br /&gt;
using template can reduce some workload,&lt;br /&gt;
especially when changes is small, but CSS cannot help.&lt;/p&gt;
&lt;p&gt;the basic concept is the same, also use drupal_get_form(),&lt;br /&gt;
define three function inside the template file:&lt;br /&gt;
&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;user_login2&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(){&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[]=array(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ..........................&lt;br /&gt;&amp;nbsp; );&lt;br /&gt;&amp;nbsp; return &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;}&lt;br /&gt;&lt;br /&gt;function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;user_login2_submit&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form_id&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form_values&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;){&lt;br /&gt;&amp;nbsp; .............&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;user_login2_validate&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form_id&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$form_values&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;){&lt;br /&gt;&amp;nbsp; .............&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;print_r &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;drupal_get_form&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;user_login2&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;));&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;finally use print_r, drupal will display the form.&lt;br /&gt;
user_login2_validate to process validation the form&lt;br /&gt;
user_login2_submit to save to database,&lt;/p&gt;
&lt;p&gt;but keep in mind, do not use it frequently, which will increase the difficulties to maintain&lt;/p&gt;
&lt;p&gt;finally, about from API inside block boxes,&lt;br /&gt;
as blocks can embed php code inside,&lt;br /&gt;
form can also embedded inside blocks.&lt;br /&gt;
the use of code is just like the use inside template,&lt;br /&gt;
use print_r(drupal_get_form()) again,&lt;br /&gt;
define three function....&lt;br /&gt;
one more to note, in combination with panels modules,&lt;br /&gt;
blocks can be placed everywhere, in specific page, specific place,&lt;br /&gt;
with fast development&lt;br /&gt;
the only disadvantage is, if there is php code error inside block,&lt;br /&gt;
you may face down site, which can only be repair from database.&lt;br /&gt;
so it is only advice to advance php users&lt;/p&gt;
</description>
 <comments>http://www.joetsuihk.com/2007_04_26_tutorial_on_drupal_form_api#comments</comments>
 <category domain="http://www.joetsuihk.com/free_tags/development">Development</category>
 <category domain="http://www.joetsuihk.com/free_tags/drupal">Drupal</category>
 <category domain="http://www.joetsuihk.com/free_tags/php">PHP</category>
 <category domain="http://www.joetsuihk.com/free_tags/tabbed_block">Tabbed Block</category>
 <pubDate>Sun, 29 Apr 2007 00:35:54 -0700</pubDate>
 <dc:creator>JOE</dc:creator>
 <guid isPermaLink="false">43 at http://www.joetsuihk.com</guid>
</item>
<item>
 <title>Tabbed Block 0.5</title>
 <link>http://www.joetsuihk.com/tabbed_block_0_5</link>
 <description>&lt;p&gt;Originally want to patch v0.4, but to solve the problems of image button in IE, huge code restructure is performed. so v0.5 is the version number.&lt;br /&gt;
Also, this version fixed the bug that self-defined block cannot show their correct title.&lt;br /&gt;
There is no change in database, so to install, just place all the files into %drupal%/module/tabbed_block&lt;/p&gt;
&lt;p&gt;原本打算只補丁v0.4, 但因為在IE 上的image 按鈕出現問題, 整個處理表單的流程完全改變, 所以命名為v0.5&lt;br /&gt;
這版本同時修正: 自定義的block 標題錯誤&lt;br /&gt;
這版本升級只需要將zip 內的檔案放到%drupal%/module/tabbed_block 就可以了, 並沒有資料庫上的變更&lt;/p&gt;
</description>
 <comments>http://www.joetsuihk.com/tabbed_block_0_5#comments</comments>
 <category domain="http://www.joetsuihk.com/free_tags/tabbed_block">Tabbed Block</category>
 <pubDate>Fri, 27 Apr 2007 05:05:16 -0700</pubDate>
 <dc:creator>JOE</dc:creator>
 <guid isPermaLink="false">42 at http://www.joetsuihk.com</guid>
</item>
<item>
 <title>2007-04-25 Tabbed Block v0.4 development (continue)</title>
 <link>http://www.joetsuihk.com/2007_04_25_tabbed_block_v0_4_development_continue</link>
 <description>&lt;p&gt;連日的開發, 修改了幾個問題&lt;br /&gt;
包括AJAX errors, IE 相容問題&lt;br /&gt;
改變發生錯誤時的顯示方式等等&lt;/p&gt;
&lt;p&gt;AJAX 錯誤發生在tabbed_block.js 內,&lt;br /&gt;
如果用戶沒有使用jstools 模組就會發生問題&lt;br /&gt;
主要因為AJAX 的請求路徑(request url)使用了jstools 的一個add-on, Drupal.url()&lt;br /&gt;
原本錯誤地假定Drupal.url 為Drupal 內建(.....名字上的誤會, 但Drupal 的確內建了 Drupal 對象, 只是jstools 加強了Drupal 對象)&lt;br /&gt;
及後發覺來自jstools&lt;br /&gt;
改用tabbed_block.module 內&lt;br /&gt;
&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php &lt;br /&gt;drupal_add_js&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&quot;var base_path = &quot;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;drupal_to_js&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;base_path&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;()).&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&quot;;&quot; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&quot;inline&quot; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;&lt;br /&gt;
將base_path 傳到js 內使用&lt;/p&gt;
&lt;p&gt;IE href 屬性:&lt;br /&gt;
IE 相容問題, 除了CSS 上, tabs 更是使用不能&lt;br /&gt;
問題出自tabbed_block.js 一段jquery:&lt;br /&gt;
....略, 38行&lt;br /&gt;
&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;$(this).click(function(){&lt;br /&gt;&amp;nbsp; click = $(this).children(&amp;quot;a&amp;quot;).attr(&amp;quot;href&amp;quot;);&lt;br /&gt;&amp;nbsp; $(click).siblings(&amp;quot;div&amp;quot;).each(function(){&lt;/code&gt;&lt;/div&gt;&lt;br /&gt;
39行的變數 click, 目的在取出a 的href&lt;br /&gt;
用作找回相應的div content&lt;br /&gt;
在firefox 上, 值為source code 內的值&lt;br /&gt;
但在IE 上, 值為一個絕對路徑(&lt;a href=&quot;http://example.com/drupal/#fragment-1&quot; title=&quot;http://example.com/drupal/#fragment-1&quot;&gt;http://example.com/drupal/#fragment-1&lt;/a&gt;)&lt;br /&gt;
令40行找不到一個 &lt;a href=&quot;http://example.com&quot; title=&quot;http://example.com&quot;&gt;http://example.com&lt;/a&gt; 的div&lt;br /&gt;
做成錯誤&lt;br /&gt;
用javascript 的字符函數取出解決&lt;/p&gt;
&lt;p&gt;另, 停用IE anchor:&lt;br /&gt;
IE 的anchor 不可以在jquery內用 return false 停用(停止自動滾動)&lt;br /&gt;
改用inline 的方式&lt;br /&gt;
&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;a href=&amp;quot;#frag1&amp;quot; onclick=&amp;quot;return false;&amp;quot;&amp;gt;tab head1&amp;lt;/a&amp;gt;&lt;/code&gt;&lt;/div&gt;&lt;br /&gt;
在Drupal 內顯示錯誤:&lt;br /&gt;
原本為了方便開發&lt;br /&gt;
某些可以預計的錯誤使用print_r + exit() 處理&lt;br /&gt;
方便分析&lt;br /&gt;
但為了一般使用者方便, 及一體性&lt;br /&gt;
轉為使用drupal 內建的錯誤顯示方式:&lt;br /&gt;
&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php &lt;br /&gt;druapl_set_message&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;( &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;print_r $_POST &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&quot;error&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;加上注解等等之後&lt;br /&gt;
patched 的v0.41 待測試後發佈&lt;/p&gt;
&lt;p&gt;下一個將增加的功能有非常多的用戶反映&lt;br /&gt;
「tabbed block module 可以使用多於一block」&lt;br /&gt;
類似adsense module&lt;br /&gt;
但改code 將會頗多, 會待v0.41 穩定下來再開發&lt;/p&gt;
&lt;p&gt;After days of development, Tabbed Block module had fixed a couples of bugs,&lt;br /&gt;
include AJAX errors, incompatible in IE,&lt;br /&gt;
changes in UI when there is error....... etc etc&lt;/p&gt;
&lt;p&gt;AJAX error happens inside file tabbed_block.js&lt;br /&gt;
If the user do not install jstools modules, problems happen.&lt;br /&gt;
It is because AJAX request path use a jstools add-on function call, Drupal.url()&lt;br /&gt;
which I assume the function is build-in Drupal (...misunderstand in naming. but Drupal did really have a build-in Drupal object, but jstools expanded it.)&lt;br /&gt;
It is solved by tabbed_block.module, a line&lt;br /&gt;
&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php &lt;br /&gt;drupal_add_js&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&quot;var base_path = &quot;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;drupal_to_js&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;base_path&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;()).&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&quot;;&quot; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&quot;inline&quot; &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;&lt;br /&gt;
using it to pass the base path(request path) to js&lt;/p&gt;
&lt;p&gt;IE href properties:&lt;br /&gt;
incompatible in IE, other than CSS, more important is failure in using tabs.&lt;br /&gt;
the bug is a line from jquery from file tabbed_block.js, line 39:&lt;br /&gt;
....etc etc, line 38:&lt;br /&gt;
&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;$(this).click(function(){&lt;br /&gt;&amp;nbsp; click = $(this).children(&amp;quot;a&amp;quot;).attr(&amp;quot;href&amp;quot;);&lt;br /&gt;&amp;nbsp; $(click).siblings(&amp;quot;div&amp;quot;).each(function(){&lt;/code&gt;&lt;/div&gt;&lt;br /&gt;
line 39 variable click, aim to get the attribute href,&lt;br /&gt;
finding the corresponding div&lt;br /&gt;
in FF, it returns the value in source code,&lt;br /&gt;
while in IE, it return absolute path: (&lt;a href=&quot;http://example.com/drupal/#fragment-1&quot; title=&quot;http://example.com/drupal/#fragment-1&quot;&gt;http://example.com/drupal/#fragment-1&lt;/a&gt;)&lt;br /&gt;
causing line 40 cannot find a div with id &lt;a href=&quot;http://example.com&quot; title=&quot;http://example.com&quot;&gt;http://example.com&lt;/a&gt;&lt;br /&gt;
it is solved by parsing the return string by string methods in js.&lt;/p&gt;
&lt;p&gt;Also, disable IE anchor:&lt;br /&gt;
the anchor cannot be disabled by returning false from jquery&lt;br /&gt;
but a inline method works:&lt;br /&gt;
&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;a href=&amp;quot;#frag1&amp;quot; onclick=&amp;quot;return false;&amp;quot;&amp;gt;tab head1&amp;lt;/a&amp;gt;&lt;/code&gt;&lt;/div&gt;&lt;br /&gt;
Display errors inside Drupal:&lt;br /&gt;
originally, becoz of the convience for development,&lt;br /&gt;
some predictable errors use print_r + exit() to catch&lt;br /&gt;
but as release goes, more focus is put on end-user,&lt;br /&gt;
so it changed to Drupal-style:&lt;br /&gt;
&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;druapl_set_message&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;( &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;print_r $_POST &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&quot;error&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;&lt;br /&gt;
And some other addings in comments,&lt;br /&gt;
patched v0.41 will be release after test&lt;/p&gt;
&lt;p&gt;The coming feature that will be added is &quot;multi-block&quot;,&lt;br /&gt;
like adsense module.&lt;br /&gt;
And it is required by many users,&lt;br /&gt;
but the change in code will be huge,&lt;br /&gt;
so it will start after v0.41 is stable.&lt;/p&gt;
</description>
 <comments>http://www.joetsuihk.com/2007_04_25_tabbed_block_v0_4_development_continue#comments</comments>
 <category domain="http://www.joetsuihk.com/free_tags/development">Development</category>
 <category domain="http://www.joetsuihk.com/free_tags/drupal">Drupal</category>
 <category domain="http://www.joetsuihk.com/free_tags/tabbed_block">Tabbed Block</category>
 <pubDate>Wed, 25 Apr 2007 04:27:00 -0700</pubDate>
 <dc:creator>JOE</dc:creator>
 <guid isPermaLink="false">37 at http://www.joetsuihk.com</guid>
</item>
<item>
 <title>Tabbed Block 0.4.0</title>
 <link>http://www.joetsuihk.com/tabbed_block_0_4_0</link>
 <description>&lt;p&gt;Bugs fixed: localizer error&lt;br /&gt;
臭蟲修正: 本地化時錯誤&lt;/p&gt;
&lt;p&gt;In this release, other than bug fixed,&lt;br /&gt;
this version no longer needs tabs plugin,&lt;br /&gt;
but use a self-contained javascript to provide tabs&lt;br /&gt;
which means no more place of jquery1.1.2 is needed&lt;/p&gt;
&lt;p&gt;這個v0.4, 除了除蟲之外,&lt;br /&gt;
也放棄了jquery 的 tabs-plugi,&lt;br /&gt;
而用一個自帶的function 實現tabs 的效果&lt;br /&gt;
即是說, jquery1.1.2 己經不再需要了&lt;/p&gt;
</description>
 <comments>http://www.joetsuihk.com/tabbed_block_0_4_0#comments</comments>
 <category domain="http://www.joetsuihk.com/free_tags/development">Development</category>
 <category domain="http://www.joetsuihk.com/free_tags/drupal">Drupal</category>
 <category domain="http://www.joetsuihk.com/free_tags/release">Release</category>
 <category domain="http://www.joetsuihk.com/free_tags/tabbed_block">Tabbed Block</category>
 <pubDate>Sat, 21 Apr 2007 01:13:19 -0700</pubDate>
 <dc:creator>JOE</dc:creator>
 <guid isPermaLink="false">10 at http://www.joetsuihk.com</guid>
</item>
<item>
 <title>Tabbed Block v0.4 Release</title>
 <link>http://www.joetsuihk.com/tabbed_block_v0_4_release</link>
 <description>&lt;p&gt;Bugs fixed: &lt;a href=&quot;http://www.joetsuihk.com/node/3&quot;&gt;localizer error&lt;/a&gt;&lt;br /&gt;
臭蟲修正: &lt;a href=&quot;http://www.joetsuihk.com/node/3&quot;&gt;本地化時錯誤&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In this release, other than bug fixed,&lt;br /&gt;
this version no longer needs tabs plugin,&lt;br /&gt;
but use a self-contained javascript to provide tabs&lt;br /&gt;
which means no more place of jquery1.1.2 is needed&lt;/p&gt;
&lt;p&gt;這個v0.4, 除了除蟲之外,&lt;br /&gt;
也放棄了jquery 的 tabs-plugi,&lt;br /&gt;
而用一個自帶的function 實現tabs 的效果&lt;br /&gt;
即是說, jquery1.1.2 己經不再需要了&lt;/p&gt;
&lt;p&gt;svn: &lt;a href=&quot;http://www.joetsuihk.com/svn/drupal_modules/tabbed_block/tags/Revision%200.4/&quot;&gt;Revision 0.4&lt;/a&gt;&lt;/p&gt;
</description>
 <comments>http://www.joetsuihk.com/tabbed_block_v0_4_release#comments</comments>
 <category domain="http://www.joetsuihk.com/free_tags/drupal">Drupal</category>
 <category domain="http://www.joetsuihk.com/free_tags/release">Release</category>
 <category domain="http://www.joetsuihk.com/free_tags/tabbed_block">Tabbed Block</category>
 <enclosure url="http://www.joetsuihk.com/files/tabbed_block v0.4_0.zip" length="12514" type="application/zip" />
 <pubDate>Sat, 21 Apr 2007 00:49:10 -0700</pubDate>
 <dc:creator>JOE</dc:creator>
 <guid isPermaLink="false">5 at http://www.joetsuihk.com</guid>
</item>
<item>
 <title>2007-04-20 Tabbed Block 開發要點</title>
 <link>http://www.joetsuihk.com/2007_04_20_tabbed_block_0</link>
 <description>&lt;p&gt;很開心第一個實用的模組終於都算是「可以測試」&lt;br /&gt;
續上一回, 分享一下開發模組的小小心得&lt;br /&gt;
待同好可以互相交流, 提點一下這個初生之犢&lt;/p&gt;
&lt;p&gt;入正題, 這個模組取自上一回的簡單的測試源碼&lt;br /&gt;
主要加入一個可以選擇模組的功能&lt;br /&gt;
雖然事前已經知道這個簡單功能牽連甚廣&lt;br /&gt;
但做著做著才知道這個功能牽連:&lt;br /&gt;
資料庫讀, 存&lt;br /&gt;
表格&lt;/p&gt;
&lt;p&gt;資料庫的讀寫因為只需要記下模組的次序和名字&lt;br /&gt;
用內建的variable 表就可以了( 一個儲什麼也可以的地方 )&lt;br /&gt;
drupal 自己也有api 提供讀寫刪操作&lt;br /&gt;
variable_set( &#039;&#039;tabbed_block_settings&#039;&#039; , &#039;&#039;blog-0&#039;&#039; );&lt;br /&gt;
就可以將blog-0 放到 資料庫&lt;br /&gt;
你也可以將array 直接放到 arg2 中,&lt;br /&gt;
drupal core 會幫你處理, 而模組中就是將&lt;br /&gt;
0=&amp;gt;blog-0&lt;br /&gt;
1=&amp;gt;user-2&lt;br /&gt;
之類的順序放到tabbed_block_settings 中&lt;br /&gt;
而讀的代碼為&lt;br /&gt;
$block_list = variable_get( &#039;&#039;tabbed_block_settings&#039;&#039; , array() );&lt;br /&gt;
如果arg1的值找不到 則返回arg2&lt;/p&gt;
&lt;p&gt;當然, hook_block() 的代碼也改變甚多&lt;br /&gt;
因為不再是hardcode, 而是要從資料庫中取出資料&lt;br /&gt;
再輸出相關html code&lt;br /&gt;
輸出html code 的部份用了views 模組的代碼&lt;br /&gt;
其他部份改動不是太大&lt;br /&gt;
只設定一個好用, 效率高的data structure 傳到輸出代碼的function 就可以了&lt;/p&gt;
&lt;p&gt;頭大的是表單的處理&lt;br /&gt;
drupal 內建了一個form api&lt;br /&gt;
高度的abstraction 讓開發者可以簡單的寫出表單和作表單的處理&lt;br /&gt;
但abstraction 的程度太深, 反而要重新適應寫form 的方法&lt;br /&gt;
而且Tabbed Block 的表單處理方法中, 只有用戶按了save 才會儲存&lt;br /&gt;
令表單要記住每一個改變, 每一個add, delete, moves&lt;br /&gt;
這有別於一般的表單為這模組的開發帶來了不少的麻煩&lt;br /&gt;
參考views 模組也不得要領&lt;br /&gt;
最後唯有用了一個自創的方法tabbed_block_admin_setting()來實現&lt;br /&gt;
這function 同時處理add, delete, move, save&lt;br /&gt;
有點擁腫, 也用了$_POST 這類傳統的方法處理表單, 為節衷的方法&lt;/p&gt;
&lt;p&gt;講一下form 的組成&lt;br /&gt;
drupal 主站有很多的方法&lt;br /&gt;
api.drupal.org 也有form quick start guide&lt;br /&gt;
這裡用的是quickguide 的方法&lt;br /&gt;
function form_build(){&lt;br /&gt;
$form[]=array(.......);&lt;br /&gt;
}&lt;br /&gt;
//hook_menu 內的callback:&lt;br /&gt;
&#039;&#039;#callback&#039;&#039;=&amp;gt;drupal_get_form(&#039;&#039;form_build&#039;&#039;),&lt;/p&gt;
&lt;p&gt;這是最直接, 簡單的方法&lt;br /&gt;
特別適合全頁只有一張大表格&lt;br /&gt;
而且不會用到table 的地方&lt;br /&gt;
但如果大家留意到, move up, delete 的位置有一個類似table的&lt;br /&gt;
但直實只是視覺上似table, 實際是用了空格來排版&lt;br /&gt;
做到類似views, cck 的方式做設定&lt;/p&gt;
&lt;p&gt;這模組設定的部份原理上已經跟cck, views 一類巨大的模組看齊&lt;br /&gt;
可以說是一個非常成功的, 練習用, 測試用的模組.&lt;/p&gt;
&lt;p&gt;p.s. Tabbed Block v0.4 即將發佈&lt;br /&gt;
解決一定要使用jquery1.1.3 的問題&lt;br /&gt;
和中文化之後的error 問題&lt;/p&gt;
&lt;p&gt;p.s.s. 一個新的模組也將會於近日發佈&lt;br /&gt;
請留意最新消息&lt;/p&gt;
</description>
 <comments>http://www.joetsuihk.com/2007_04_20_tabbed_block_0#comments</comments>
 <category domain="http://www.joetsuihk.com/free_tags/development">Development</category>
 <category domain="http://www.joetsuihk.com/free_tags/drupal">Drupal</category>
 <category domain="http://www.joetsuihk.com/free_tags/tabbed_block">Tabbed Block</category>
 <pubDate>Thu, 19 Apr 2007 17:45:01 -0700</pubDate>
 <dc:creator>JOE</dc:creator>
 <guid isPermaLink="false">6 at http://www.joetsuihk.com</guid>
</item>
<item>
 <title>2007-04-13 新地址</title>
 <link>http://www.joetsuihk.com/2007_04_13</link>
 <description>&lt;p&gt;恭喜你&lt;br /&gt;如果你見到這個post,&lt;br /&gt;代表我的blog 已經搬好家囉!&lt;br /&gt;新的地址為 &lt;a href=&quot;http://www.joetsuihk.com&quot; title=&quot;http://www.joetsuihk.com&quot;&gt;http://www.joetsuihk.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;為了迎接新的地址,&lt;br /&gt;Tabbed block for Drupal 將會release 一個alpha 版&lt;br /&gt;並用 Drupal 來trace issues, bugs.&lt;br /&gt;但請等一下.......&lt;/p&gt;
&lt;p&gt;這個module 可以將任何一, 數個block 放到tabbed block 內&lt;br /&gt;並且用tab 的表現方式展示.&lt;/p&gt;
</description>
 <comments>http://www.joetsuihk.com/2007_04_13#comments</comments>
 <category domain="http://www.joetsuihk.com/free_tags/drupal">Drupal</category>
 <category domain="http://www.joetsuihk.com/free_tags/tabbed_block">Tabbed Block</category>
 <pubDate>Thu, 12 Apr 2007 09:12:17 -0700</pubDate>
 <dc:creator>JOE</dc:creator>
 <guid isPermaLink="false">12 at http://www.joetsuihk.com</guid>
</item>
</channel>
</rss>
