天天看點

drupal7表單

轉自:http://blog.sina.com.cn/s/blog_5a8b8eb80100ra1l.html

表單屬性: 

     #access該布爾值屬性決定表單元素對于使用者是否可見。如果表單元素有子表單元素的話,如果父表單元素的#access屬性為FALSE的話,那麼子表單元素将不被顯示出來。例如,如果表單元素是一個字段集的話,如果它的#access為FALSE的話,那麼字段集裡面的所有的字段都不被顯示。

‘#access’=> FALSE,  // 表單是否可見
   '#collapsible' => TRUE, // 顯示為可折疊菜單
   '#collapsed' => FALSE,  //收縮狀态,false:折疊,true:展開
   '#required' => TRUE,   //必填項    
   '#default_value' => "F", //預設值
   '#description' => "",    //描述
   '#size' => 20,          //控件大小
   '#maxlength' => 20,     //可輸入文字的長度
           

 Drupal提供了一個應用程式接口(API),用來生成、驗證和處理HTML表單。表單API将表單抽象為一個嵌套數組,裡面包含了屬性和值。在生成頁面時,表單呈現引擎會在适當的時候将數組呈現出來。這種方式包含多層含義:

我們沒有直接輸出HTML,而是建立了一個數組并讓引擎生成HTML。

由于我們将表單的表示作為結構化的資料進行處理,是以我們可以添加、删除、重新排序、和修改表單。當你想用一種幹淨利索的方式對其它子產品建立的表單進行修改時,這會特别友善。

任意的表單元素可以映射到任意的主題函數上。

可以将額外的表單驗證或處理函數添加到任意表單上。

對表單操作進行了保護,進而防止表單注入攻擊,比如當使用者修改了表單并接着試圖送出它時。

使用表單的學習曲線有點高.

drupal7表單

了解表單處理流程:

Drupal的表單引擎負責為要顯示的表單生成HTML,并使用三個階段來安全的處理送出了的表單:驗證、送出、重定向。

流程初始化

在處理表單時,有3個變量非常重要。第一個就是$form_id,它包含了一個辨別表單的字元串。第二個就是$form,它是一個描述表單的結構化數組。 而第三個就是$form_state,它包含了表單的相關資訊,比如表單的值以及當表單處理完成時應該發生什麼。drupal_get_form()在開 始時,首先會初始化$form_state。

設定一個令牌(token)

表單系統的一個優點是,它盡力的去保證被送出的表單就是Drupal實際建立的,這主要是為了安全性和防止垃圾資訊或潛在的站點攻擊者。為了實作這一 點,Drupal為每個Drupal安裝都設定了一個私鑰。這個私鑰是在安裝流程期間随機生成的,它能将這個特定的Drupal安裝與其它的Drupal 差別開來。一旦私鑰生成後,它将作為drupal_private_key存儲在variables表中。Drupal将基于私鑰生成一個随機的令牌,而 該令牌将作為隐藏域發送到表單中。當表單送出時,會對令牌進行測試。相關背景資訊請參看drupal.org/node/28420。令牌僅用于登入用 戶,因為匿名使用者的頁面通常會被緩存起來,這樣它們就沒有唯一的令牌了。

設定一個ID

一個包含了目前表單ID的隐藏域,将作為表單的一部分被發送給浏覽器。該ID一般對應于定義表單的函數,它将作為drupal_get_form()的第一個參數傳遞過來。例如函數user_register()定義了使用者系統資料庫單,它的調用方式如下:

$output = drupal_get_form('user_register');

收集所有可能的表單元素定義:

接着,調用element_info()。它将調用所有實作了hook_elements()的子產品上的這個鈎子函數。在Drupal核心中,标準的元 素,比如單選按鈕和複選框,都定義在modules/system/system.module中的hook_elements()實作中(參看 system_elements())。如果子產品需要定義它們自己的元素類型,那麼就需要實作這個鈎子。在以下幾種情況中,你可能需要在你的子產品中實作 hook_elements():你想要一個特殊類型的表單元素時,比如一個圖像上傳按鈕,在節點預覽期間可用來顯示縮略圖;或者,你想通過定義更多的屬 性來擴充已有的表單元素時。

鈎子element_info()為所有的表單元素收集所有的預設屬性,并将其儲存到一個本地緩存中。在進入下一步----為表單尋找一個驗證器----以前,對于那些在表單定義中尚未出現的任何預設屬性,都将在這裡被添加進來。

尋找一個驗證函數:

通過将表單的屬性#validate設定為一個數組,其中函數名為為值,進而為表單配置設定一個驗證函數。在調用驗證函數時,後面的數組中的任何資料都将被傳遞給驗證函數。可以使用下面的方式來定義多個驗證器:

// We want foo_validate() and bar_validate() to be called during form validation.

$form['#validate'][] = 'foo_validate';

$form['#validate'][] = 'bar_validate';

如果表單中沒有定義屬性#validate,那麼接下來就要尋找名為“表單ID”+“_validate”的函數。是以,如果表單ID為user_register,那麼表單的#validate屬性将被設定為user_register_validate。

尋找一個送出函數:

通過将表單的#submit屬性設定為一個數組,其中以函數名為鍵/值,這裡的函數名就是用來處理表單送出的函數的名字,進而為表單配置設定一個送出函數:

// Call my_special_submit_function() on form submission.

$form['#submit'][] = 'my_special_submit_function';

// Also call my_second_submit_function().

$form['#submit'][] = 'my_second_submit_function';

如果表單沒有名為#submit的屬性,那麼接下來就要尋找名為“表單ID”+“_submit”的函數。是以,如果表單ID為 user_register,那麼Drupal将把#submit屬性設定為它所找到的表單處理器函數;也就是 user_register_submit。

允許子產品在表單建構以前修改表單

在建構表單以前,子產品有兩個可以修改表單的機會。子產品可以實作一個名字源于form_id + _alter的函數,或者可以簡單的實作hook_form_alter()。任何子產品,隻要實作了這兩個鈎子中的任意一個,那麼就可以修改表單中的任何東西。對于由第3方子產品建立的表單,我們主要可以使用這種方式對其進行修改、覆寫、混合。

建構表單

現在表單被傳遞給了form_builder(),這個函數将對表單樹進行遞歸處理,并為其添加标準的必須值。這個函數還将檢查每個元素的#access鍵,如果該元素的#access為FALSE,那麼将拒絕對該表單元素及其子元素的通路。

允許函數在表單建構後修改表單

函數form_builder()每次遇到$form樹中的一個新分支時(例如,一個新的字段集或表單元素),它都尋找一個名為#after_build 的可選屬性。這是一個可選的數組,裡面包含了目前表單元素被建構後會立即調用的函數。當整個表單被建構後,最後将調用可選屬性$form[‘#after_build’] 中定義的函數。$form和$form_state将作為參數傳遞給所有的#after_build函數。Drupal核心中有一個實際例子,那就是在 “管理➤站點配置➤檔案系統”中,檔案系統路徑的顯示。這裡使用了一個#after_build函數(在這裡就是 system_check_directory()),用來判定目錄是否存在或者是否可寫,如果不存在或不可寫,那麼将為該表單元素設定一個錯誤消息。

檢查表單是否已被送出

如果你是按照流程往下走的話,那麼你将看到我們現在來到了一個分叉點。如果表單是初次顯示的話,那麼Drupal将會為其建立HTML。如果表單正被送出 的話,那麼Drupal将處理在表單中所輸入的資料;我們稍後将會讨論這一點(參看後面的“驗證表單”一節)。現在,我們将假定表單是初次顯示。有一點非 常重要,那就是不管表單是初次顯示,還是正被送出,在此以前,它所走過的流程是一樣的。

為表單查找一個主題函數

如果$form['#theme']已被設定為了一個已有函數,那麼Drupal将簡單的使用該函數來負責表單的主題化。如果沒有設定,那麼主題系統資料庫将 查找一個對應于這個表單的表單ID的條目。如果存在這樣的一個條目,那麼就會将表單ID配置設定給$form['#theme'],在後面,當Drupal呈 現表單時,它将基于表單ID來尋找主題函數。例如,如果表單ID為taxonomy_overview_terms,那麼Drupal将調用對應的主題函 數theme_taxonomy_overview_terms()。當然,可以在自定義主題中,使用主題函數或者模闆檔案來覆寫這個主題函數。

允許子產品在表單呈現以前修改表單

最後剩下的一件事,就是将表單從結構化的資料轉化為HTML。但是在這以前,子產品還有最後一個機會來調整表單。對于跨頁面表單向導,或者需要在最後時刻修 改表單的其它方式,這将會非常有用。此時将會調用$form['#pre_render']屬性定義的任何函數,并将正被呈現的表單傳遞給這些函數。

呈現表單:

為了将表單樹從一個嵌套數組轉化為HTML代碼,表單建構器調用drupal_render()。這個遞歸函數将會周遊表單樹的每個層次,對于每個層次,它将執行以下動作:

1. 判定是否定義了#children屬性(這句話就是說,是否已經為該元素生成内容了);如果沒有,那麼按照以下步驟來呈現這個樹節點的孩子:

• 判定是否為這個元素定義了一個#theme函數。

• 如果定義了,那麼将這個元素的#type臨時設定為markup(辨別字型)。接着,将這個元素傳遞給主題函數,并将該元素重置為原來的樣子。

• 如果沒有生成内容(可能是因為沒有為這個元素定義#theme函數,或者因為調用的#theme函數在主題系統資料庫中不存在,或者因為調用的#theme函數沒有傳回東西),那麼逐個呈現這個元素的子元素(也就是,将子元素傳遞給drupal_render())。

• 另一方面,如果#theme函數生成了内容,那麼将内容存儲在這個元素的#children屬性中。

2. 如果表單元素本身還沒有被呈現出來,那麼調用這個元素所屬類型的預設主題函數。例如,如果這個元素是表單中的一個文本字段(也就是說,在表單定義中,它 的#type屬性被設定為了textfield),那麼預設主題函數就是theme_textfield()。如果沒有為這個元素設定#type屬性,那 麼預設為markup。核心元素(比如文本字段)的預設主題函數位于includes/form.inc中。

3. 如果為這個元素生成了内容,并且在#post_render屬性中找到了一個或多個函數名字,那麼将分别調用這些函數,并将内容和該元素傳遞過去。

4. 在内容前面添#prefix,在後面追加#suffix,并将它從函數中傳回。

這個遞歸疊代的作用就是為表單樹的每個層次生成HTML。例如,一個表單了包含一個字段集,而字段集裡面又包含兩個字段,那麼該字段集 的#children屬性将包含兩個字段的HTML,而表單的#children屬性将包含整個表單的HTML(其中包括字段集的HTML)。

生成的HTML将會傳回給drupal_get_form()的調用者。這就是呈現表單所要做的全部工作!我們到達了流程中中的終點“傳回HTML”。

驗證表單:

我們在“檢查表單是否已被送出”一節中所提到的分叉點。現在讓我們假定表單已被送出并包含了一些資料;這樣我們将沿着另一分支前進,看看這種情況是怎麼樣 的。使用以下兩點來判定一個表單已被送出:$_POST不為空,$_POST['form_id']中的字元串比對剛被建構的表單定義中的ID。如果這兩 點都滿足了,那麼Drupal 将開始驗證表單。

驗證的目的是為了檢查證被送出的資料的合理性。驗證或者通過,或者失敗。如果驗證在某一點上失敗了,那麼将為使用者重新顯示這個表單,并帶有錯誤消息。如果所有的驗證都通過了,那麼Drupal将對送出的資料進行實際的處理。

令牌驗證

在驗證中首先檢查的是,該表單是否使用了Drupal的令牌機制。使用令牌的所有Drupal表單,都會有一個唯一的令牌,它和表單一起被發送給浏覽器, 并且應該和其它表單值一同被送出。如果送出的資料中的令牌與表單建構時設定的令牌不比對,或者令牌不存在,那麼驗證将會失敗(盡管驗證的其餘部分也會繼續 執行,這樣其它驗證錯誤也會被辨別出來)。

内置驗證

接着,檢查必填字段,看使用者有沒有漏填的。檢查帶有#maxlength屬性的字段,確定它沒有超過最大字元數。檢查帶有選項的元素(複選框、單選按鈕、下拉選擇框),看所選的值是否是位于建構表單時所生成的原始選項清單中。

特定元素的驗證

如果為單個表單元素定義了一個#validate屬性,那麼将會調用這個屬性所定義的函數,并将$form_state和$element作為參數傳遞過去。

驗證回調

最後,表單ID和表單值将被傳遞到表單的驗證器函數中(函數名一般為:“表單ID”+ “_validate”)。

送出表單:

如果驗證通過了,那麼現在就應該把表單和它的值傳遞到一個函數中,該函數将做些實際的處理,以作為表單送出的結果。實際上,由于#submit屬性可以包 含一個數組,裡面包含多個函數名字,是以可以使用多個函數來處理表單。調用數組中的每個函數,并向其傳遞參數$form和$form_state。

重定向:

用來處理表單的函數,應該把$form_state['redirect']設定為一個Drupal路徑,比如node/1234,這樣就可以将使用者重定 向到這個頁面了。如果#submit屬性中有多個函數,那麼将會使用最後一個函數設定的$form_state['redirect']。如果沒有函數 把$form_state['redirect']設定為一個Drupal路徑,那麼使用者将傳回原來的頁面(也就是,$_GET['q']的值)。在最後 一個送出函數中傳回FALSE,将會阻止重定向

通過在表單中定義#redirect屬性,就可以覆寫在送出函數中$form_state['redirect']設定的重定向了,比如

$form['#redirect'] = 'node/1'或$form['#redirect'] = array('node/1', $query_string, $named_anchor)

如果使用drupal_goto()中所用的參數術語,那麼最後的一個例子将被改寫為

$form['#redirect'] = array('node/1', $query, $fragment)

表單重定向的判定,是由includes/form.inc中的drupal_redirect_form()完成的。而實際的重定向則由drupal_goto()實作,它為Web伺服器傳回一個Location頭部。 drupal_goto()的參數與後一個例子中的參數一緻:drupal_goto($path = '', $query = NULL, $fragment = NULL)。

建立基本的表單: ....

表單屬性:

屬性和元素有哪些差別呢?最基本的差別就是,屬性沒有屬性,而元素可以有屬性。送出按鈕就是一個元素的例子,而送出按鈕的#type屬性就是一個屬性的例 子。你一眼便可以認出屬性,這是因為屬性擁有字首“#”。我們有時把屬性稱為鍵,因為它們擁有一個值,為了得到該值,你必須知道相應的鍵。一個初學者常見 的錯誤就是忘記了字首“#”,此時,無論是Drupal還是你自己,都會感到非常困惑。如果你看到了錯誤消息“Cannot use string offset as an array in form.inc”,那麼十有八九就是你忘記了字元“#”。

屬性是通用的,而有些則特定于一個元素,比如一個按鈕。 例:

$form['#method'] = 'post';

$form['#action'] = 'http://example.com/?q=foo/bar';

$form['#attributes'] = array(

'enctype' => 'multipart/form-data',

'target' => 'name_of_target_frame'

);

$form['#prefix'] = '<div class="my-form-class">';

$form['#suffix'] = '</div>';

#method屬性的預設值為post,它可以被忽略。表單API不支援get方法,該方法在Drupal中也不常用,這是因為通過Drupal的菜單路 由機制可以很容易的自動解析路徑中的參數。#action屬性定義在system_elements(),預設值為函數request_uri()的結 果。通常與顯示表單的URL相同。

表單IDs:

drupal_get_form()的調用中,所用的就是ID.對于大多數表單,其ID的命名規則為:子產品名字+一個表述該表單做什麼的辨別。

Drupal使用表單ID來決定表單的驗證、送出、主題函數的預設名字.另外,Drupal使用表單ID作為基礎來為該特定表單生成一個<form>标簽中的HTML ID屬性,這樣在Drupal中所有的表單都有一個唯一的ID。通過設定#id屬性,你可以覆寫該ID:

$form['#id'] = 'my-special-css-identifier';

生成的HTML标簽将會是這樣的:

<form action="/path" "accept-charset="UTF-8" method="post"

id="my-special-css-identifier">

字段集:

屬性#collapsible和#collapsed來使用Javascript讓它可以伸縮。

屬性#tree設為TRUE,你将得到一個嵌套的表單值數組。将屬性#tree設為FALSE(預設情況),你将得到一個未嵌套的表單值數組。

主題化表單:

使用主題函數:

主題化表單的最靈活的方式,就是為表單或者表單元素使用一個特定的主題函數。首先,Drupal需要知道我們的子產品将實作哪些主題函數。這可以通過 hook_theme()來完成。擁有我們自己的主題函數的好處是,我們可以按照我們的意願對變量$output進行解析、混合、添加等操作。

告訴Drupal使用哪個主題函數:

通過為一個表單聲明#theme屬性,你可以指令Drupal使用一個不比對“‘theme_’+表單ID名字”格式的主題函數:

// Now our form will be themed by the function

// theme_formexample_alternate_nameform().

$form['#theme'] = 'formexample_alternate_nameform';

或者,你也可以讓Drupal為一個表單元素使用一個專門的主題函數:

// Theme this fieldset element with theme_formexample_coloredfieldset().

$form['color'] = array(

'#title' => t('Color'),

'#type' => 'fieldset',

'#theme' => 'formexample_coloredfieldset'

);

注意,在前面的兩種情況中,你在#theme屬性中定義的函數必須是主題系統資料庫中注冊過的;也就是說,必須在一個hook_theme()實作中對其進行了聲明。

使用hook_forms()聲明驗證和送出函數:

你想讓許多不同的表單共用一個驗證或者送出函數。這叫做代碼複用,可以用hook_forms()将多個表單ID映射到驗證和送出函數上。在Drupal 取回表單時,它首先查找基于表單ID定義表單的函數(正因為這樣,在我們的代碼中,我們使用函數formexample_nameform())。如果找 不到該函數,它将觸發hook_forms(),該鈎子函數在所有的子產品中查找比對的表單ID以進行回調。

主題、驗證、送出函數的調用次序:

對于一個主題函數,假定你使用基于PHPTemplate的名為bluemarine的主題,并且你正在調用drupal_get_form('formexample_nameform')。然而,這還取決于你的hook_theme()實作。

首先,如果在表單定義中将$form['#theme']設定為了'foo':

1. themes/bluemarine/foo.tpl.php // Template file provided by theme.

2. formexample/foo.tpl.php // Template file provided by module.

3. bluemarine_foo() // Function provided theme.

4. phptemplate_foo() // Theme function provided by theme engine.

5. theme_foo() // 'theme_' plus the value of $form['#theme'].

然而,如果在表單定義中沒有設定$form['#theme']:

1. themes/bluemarine/formexample-nameform.tpl.php // Template provided by theme.

2. formexample/formexample-nameform.tpl.php // Template file provided by module.

3. bluemarine_formexample_nameform() // Theme function provided by theme.

4. phptemplate_formexample_nameform() // Theme function provided by theme engine.

5. theme_formexample_nameform() // 'theme_' plus the form ID.

在驗證期間,表單驗證器的設定次序如下:

1. A function defined by $form['#validate']

2. formexample_nameform_validate // Form ID plus 'validate'.

當需要查找處理表單送出的函數時,查找的次序如下:

1. A function defined by $form['#submit']

2. formexample_nameform_submit // Form ID plus 'submit'.

編寫一個驗證函數:

從驗證函數中傳遞資料:

如果你的驗證函數做了大量的處理,而你又想把結果儲存下來以供送出函數使用,那麼有兩種不同的方式。你可以使用form_set_value()或者使用$form_state。

針對表單元素的驗證:

一般情況下,一個表單使用一個驗證函數。但是也可以為單個表單元素設定一個驗證函數,這和整個表單的驗證函數一樣。為了實作這一點,我們需要将元素的屬 性#element_validate設定為一個數組,其中包含了驗證函數的名字。表單資料結構中該元素分支的一份完整拷貝,将被作為驗證函數的第一個參 數。在調用完所有表單元素的驗證函數以後,仍需調用表單驗證函數。提示 在你的表單元素未通過驗證,你希望為它顯示一條錯誤消息時,如果你知道表單元素的名字,那麼使用form_set_error(),如果你擁有表單元素本 身,那麼使用form_error()。後者對前者做了簡單封裝。

表單重新建構:

在驗證期間,你可能判定你沒有從使用者那裡擷取足夠的資訊。例如,你可能将表單數值放到一個文本分析引擎中進行檢查,然後判定這一内容很有可能是垃圾資訊。 最後,你想重新顯示表單(裡面包含使用者已輸入的值),不過這次添加了一個CAPTCHA,用來證明這個使用者不是一個機器人。通過在你的驗證函數中設 置$form_state['rebuild'],你就可以通知Drupal需要進行一次重構了.

編寫送出函數:

送出函數是表單通過驗證後負責實際的表單處理的函數。隻有在表單驗證完全通過,并且表單沒有被标記為重新建構時,它才會執行。送出函數通常需要修改$form_state['redirect']。 如果你有多個函數用來處理表單送出,隻有最後一個設定$form_state['redirect']的函數返才擁有最後的發言權。可以通過在表單中定義#redirect屬性來覆寫送出函數的重定向。通常使用hook_form_alter()來實作這一點。

使用hook_form_alter()修改表單:

使用drupal_execute()通過程式來送出表單:

drupal_execute($form_id, $form_state);

修改一個特定的表單:

如果有很多子產品來修改表單,而每個表單都傳遞給所有的hook_form_alter()實作.然而可以通過根據表單ID構造一個函數并調用它。

函數的名字是這樣構造的:modulename + 'form' + form ID + 'alter'

例如'formexample' + 'form' + 'user_login' + 'alter' 将生成 formexample_form_user_login_alter

添加到所有表單元素上的屬性:

當表單建構器使用表單定義建構表單時,它需要保證每一個表單元素都要有一些預設設定。這些預設值在includes/form.inc的函數_element_info()中設定,但是可以被hook_elements()中的表單元素定義所覆寫。

#description

該字元串屬性将添加到所有表單元素上,預設為NULL。通過表單元素的主題函數來呈現它。例如,一個文本字段的描述呈現在textfield的下面。

#required

該布爾值屬性将被添加到所有表單元素上,預設為FALSE。将它設為TRUE,如果表單被送出以後而字段未被完成時,Drupal内置的表單驗證将抛出一 個錯誤消息。還有,如果将它設為TRUE,那麼就會為這個元素設定一個CSS類(參看includes/form.inc中的 theme_form_element())

#tree

該布爾值屬性将被添加到所有表單元素上,預設為FALSE。如果将它設為TRUE,表單送出後的$form_state['values']數組将會是嵌套的(而不是平坦的)。這将影響你通路送出資料的方式。(參看本章中的“字段集”部分)。

#post

該數組屬性是原始$_POST資料的一個拷貝,它将被表單建構器添加到所有的表單元素上。這樣,在#process 和 #after_build中定義的函數就可以基于#post的内容做出聰明的決定。

#parents

該數組屬性将被添加到所有表單元素上,預設為一個空數組。它在表單建構器的内部使用,以辨別表單樹中的父元素。更多資訊,參看http://drupal.org/node/48643。

#attributes

該數組屬性将被添加到所有表單元素上,預設為一個空數組,但是主題函數一般會填充該數組。該數組中的成員将被作為HTML屬性添加進來。例如$form['#attributes'] = array('enctype' => 'multipart/form-data')。

表單API屬性:

當在你的表單建構函數中建構一個表單定義時,數組中的鍵用來聲明表單的資訊。在下面部分中列出了最常用的鍵。表單建構器可以自動添加一些鍵。

表單根部的屬性

下面所列的屬性是特定于表單根部的。換句話說,你可以設定$form['#programmed'] = TRUE,但是如果你設定$form['myfieldset']['mytextfield'] [#programmed'] = TRUE那麼對表單建構器來說沒有任何意義。

#parameters

該屬性是一個數組,包含了傳遞給drupal_get_form()的原始參數。通過drupal_retrieve_form()可添加該屬性。

#programmed

這是一個布爾值屬性,用來訓示一個表單是以程式的方式來送出的, 比如通過drupal_execute()。如果在表單處理前設定了屬性#post,那麼可以使用drupal_prepare_form()來設定該屬性。

#build_id

該屬性是一個字元串(MD5哈希)。#build_id用來辨別一個特定的表單執行個體。它作為一個隐藏域放在表單中,通過使用drupal_prepare_form()來設定這個表單元素,如下所示:

$form['form_build_id'] = array(

'#type' => 'hidden',

'#value' => $form['#build_id'],

'#id' => $form['#build_id'],

'#name' => 'form_build_id',

);

#token

這個字元串(MD5哈希)是一個唯一的令牌,每個表單中都帶有它,通過該令牌Drupal能夠判定一個表單是一個實際的Drupal表單,而不是一個惡意使用者修改後的。

#id

這個屬性是一個由form_clean_id($form_id)生成的字元串,并且它是一個HTML ID屬性。$form_id中的任何背對的括号對“][”,下劃線“_”,或者空格’’都将被連字元替換,以生成一緻的CSS ID。在Drupal的同一個頁面中,該ID是唯一的.如果同一個ID出現兩次(例如,同一個表單在一個頁面顯示了兩次),那麼就會在後面添加一個連字元和一個自增的整數,例如foo-form, foo-form-1, 和foo-form-2。

#action

這個字元串屬性是HTML表單标簽的動作屬性。預設情況,它是request_uri()的傳回值。

#method

這個字元串屬性指的是表單的送出方法---通常為post。表單API是基于post方法建構的,它将不會處理使用GET方法送出的表單。關于GET 和POST的差別,可參看HTML規範。如果在某種情況下,你想嘗試使用GET方法,那麼你真正需要可能是Drupal的菜單API,而不是表單API。

#redirect

該屬性可以是一個字元串或者一個數組。如果是一個字元串,那麼它是在表單送出以後使用者想要重定向到的Drupal路徑。如果是一個數組,該數組将作為參數 被傳遞給drupal_goto(),其中數組中的第一個元素應該是目标路徑(這将允許向drupal_goto()傳遞額外的參數,比如一個查詢字元 串)。

#pre_render

該屬性是一個數組,它包含了在表單呈現以前所要調用的函數。每個函數都被調用,并且#pre_render所在的元素将被作為參數傳遞過來。例如,設 置$form['#pre_render'] = array('foo', 'bar') 将使Drupal先調用函數foo(&$form),然後調用bar(&$form)。如果#pre_render是設定在一個表單元素 上的話,比如$form['mytextfield']['#pre_render'] = array('foo'),那麼Drupal将調用foo(&$element),其中$element就 是$form['mytextfield']。當你想在表單驗證運作以後,呈現以前,使用鈎子修改表單結構時,這個屬性非常有用。如果想在驗證以前修改表 單,那麼使用hook_form_alter()。

#post_render

該屬性是一個數組,它包含了一組函數,這些函數可對剛被呈現的内容進行修改。如果你設定了$form['mytextfield']['#post_render'] = array('bar'),那麼你可以這樣修改剛建立的内容:

function bar($content, $element) {

$new_content = t('This element (ID %id) has the following content:',

array('%id' => $element['#id'])) . $content;

return $new_content;

}

#cache

該屬性控制着表單是否可被Drupal的一般緩存系統所緩存。對表單進行緩存意味着,在表單被送出時,它不需要再被重新建構。如果你想每次都重新建構表單的話,那麼你可以設定$form['#cache'] = FALSE。

表單元素:

Textfield(文本字段)

Password(密碼)

Password with Confirmation(帶确認的密碼)

Textarea(文本域)

Select(下拉選擇框)

Radio Buttons(單選按鈕)

Check Boxes(複選框)

Value(值)

Hidden(隐藏域)

Date(日期)

Weight(重量)

File Upload(檔案上傳)

Fieldset(字段集)

Submit(送出按鈕)

Button(按鈕)

Image Button(圖檔按鈕)

Markup(辨別文本)

Item(項目)

#ahah屬性

跨頁面表單:

通用的表單元素屬性:

#type

該字元串聲明了一個表單元素的類型。例如,#type = 'textfield'。表單根部必須包含聲明#type = 'form'。

#access

該布爾值屬性用來判定是否将該表單元素顯示給使用者。如果表單元素有子表單元素的話,如果父表單元素的#access屬性為FALSE的話,那麼子表單元素将不顯示。例如,如果表單元素是一個字段集,并且它的#access為FALSE,那麼字段集裡面的所有字段都不顯示。

#access屬性可被直接設定為TRUE或FALSE,也可以設定為執行時傳回TRUE或FALSE的函數。當表單定義被取回時,将會執行該函數。下面這個例子來自于Drupal的預設節點表單:

$form['revision_information']['revision'] = array(

'#access' => user_access('administer nodes'),

'#type' => 'checkbox',

'#title' => t('Create new revision'),

'#default_value' => $node->revision,

);

#process

該屬性是一個關聯數組。在數組的每個條目中,函數名作為鍵,傳遞給函數的任何參數作為值。當建構表單元素時将調用這些函數,進而允許在建構表單元素時對該 元素進行額外的操作。例如,在modules/system/system.module定義了checkboxes類型,在建構表單期間,将調用 includes/form.inc裡面的函數expand_checkboxes():

$type['checkboxes'] = array(

'#input' => TRUE,

'#process' => array('expand_checkboxes'),

'#tree' => TRUE

);

還可參看本章中“收集所有可能的表單元素定義”部分中的例子。當#process數組中的所有的函數都被調用以後,将為每個表單元素添加一個#processed屬性。

#after_build

該屬性是一個函數數組,在建構完表單元素以後它們将被立即調用。每個要被調用的函數都有兩個參數:$form 和 $form_state。例如,如果$form['#after_build'] = array('foo', 'bar'),那麼Drupal在表單元素建構完以後,分别調用foo($form, $form_state)和bar($form, $form_state)。一旦這些函數都被調用以後,Drupal在内部将為每個表單元素添加一個#after_build_done屬性。

#theme

該可選屬性定義了一個字元串,當Drupal為該表單元素尋找主題函數時使用。例如,設定#theme = 'foo',Drupal将會在主題系統資料庫中查找對應于foo的條目。參看本章前面的“為表單尋找主題函數”一節。

#prefix

該屬性是一個字元串,在表單元素呈現時,它将被添加到表單元素的前面。

#suffix

該屬性是一個字元串,在表單元素呈現時,它将被添加到表單元素的後面。

#title

該字元串是表單元素的标題。

#weight

該屬性可以是一個整數或者小數。當呈現表單元素時,将根據它們的重量進行排序。重量小的元素将被放到前面,重量大的元素将被放到後面。

#default_value

該屬性的類型取決于表單元素的類型。對于輸入表單元素,如果表單還沒有被送出,那麼它就是在該字段中所用的值。不要将它與表單元素#value混淆了。表 單元素#value定義了一個内部表單值,盡管使用者看不到它,但是它卻定義在表單中,并出現在$form_state['values']中。