幫助:對話
對話功能允許構建互動式、動態的維基頁面。該功能包含兩個主要部分:一組用於指定維基頁面上互動式元素的模板,以及一組可以由這些互動式元素控制的通用“操作”。
使用這些功能意味著只需要編寫維基標記,因此互動式頁面可以由維基社群進行開發和維護。
從使用者的角度來看,互動式頁面允許透過對話方塊和類似的輸入元素輸入資料,並允許這些資料流向其他頁面的輸入元素、模板引數和操作。
在內部,這些功能的核心是使用 JavaScript 實現的,旨在透過使用 JavaScript 的其他操作擴充套件,而一些補充功能則在 Lua 中實現(參見 {{evalx}})。
更高級別的 互動式助手 基於這些功能。
互動式維基頁面使用許多模板進行排列,這些模板收集在 Category:Dialog 格式化模板 中。
支援四種類型的輸入欄位:文字、textarea、選擇和複選框。它們分別使用模板 {{dialog/text}}、{{dialog/textarea}}、{{dialog/select}} 和 {{dialog/checkbox}} 指定。
每個模板都需要一個引數 id=name,指定欄位的名稱。理論上,每個 ID 在該頁面上的輸入欄位中必須是唯一的,如果同一頁面上的兩個輸入欄位具有相同的 ID,可能會發生糟糕的事情。在實踐中,有時沒有好方法來保證唯一性;但有一種技術可以防止在最常見的情況下發生糟糕的事情,下面在 按鈕 部分解釋。
文字欄位是一個單行文字輸入框。可選引數 size=width 指定框的寬度,這會影響框的顯示方式,但不會影響其內容的大小。可選地,一個未命名引數指定文字框的初始內容;預設情況下,框最初為空。
textarea 欄位是一個多行文字輸入框。可選引數 cols=width 和 rows=length 指定框的寬度和高度,這會影響框的顯示方式,但不會影響其內容的大小。在某些 Web 瀏覽器上,無論指定什麼寬度,框始終保持相同的寬度。可選地,一個未命名引數指定 textarea 框的初始內容;預設情況下,框最初為空。
選擇欄位是一個供選擇的選項選單。未命名引數指定選項。未命名引數成對出現:一個引數指定選單上出現的選項,下一個引數指定該選單項選擇的內部值。最初,第一個選項被選中。
複選框欄位是一個可以切換的開/關值。它的內部值是“yes”或“”(空白)。可選引數 checked=非空白 使複選框最初處於開啟狀態;否則,它最初處於關閉狀態。
按鈕通常使用模板 {{dialog/button}} 指定。為建立特定型別的按鈕提供了更專業的模板,並且可以在適合預期用途的情況下使用。
按鈕在點選時的功能是將資料傳送到一個操作。模板引數 action=name 指定操作的名稱。可選模板引數 label=text 指定按鈕上顯示的文字;預設情況下,按鈕的標籤為操作的名稱。未命名模板引數指定要傳遞給操作的對話方塊引數。
每個對話方塊引數都以三種方式之一指定。首先,模板引數可以僅僅是頁面上對話方塊欄位的 ID,在這種情況下,當按鈕被點選時,該欄位的內容將作為對話方塊引數傳遞給操作,該引數的名稱為該欄位的 ID。其次,欄位的內容可以在不同的名稱下傳遞給操作,方法是指定不同的名稱、冒號和欄位的 ID。第三,要傳遞給操作的對話方塊引數的名稱後面可以是兩個冒號,然後是一個要傳遞給該名稱的值,就像該值已作為 {{dialog/textarea}} 的初始值指定一樣,然後從中獲取該值(這就是在內部發生的)。如果指定的值包含冒號,則假定它是頁面的名稱,並透過 {{隱藏使用}} 進行連結;如果已知該值是頁面名稱,但可能不包含冒號,請使用 {{dialog/page}} 來保證冒號的存在。為某些型別的按鈕提供了專用模板;截至撰寫本文時,{{dialog/view}} 和 {{dialog/edit}},在下面的 檢視 和 編輯 動詞部分進行了描述。
有時模板需要生成一個對話方塊欄位僅僅是為了儲存要由生成的按鈕使用的一個值——儘管你可能不必自己設定它,因為 {{dialog/button}} 已經以這種方式處理了值。為了防止持有者欄位混淆頁面,請使用 {{dialog/textarea}} 引數 hidden=非空白。但是,在這種情況下,可能沒有好方法來保證整個頁面上的欄位 ID 是唯一的。為了確保按鈕即使在可能重複的欄位 ID 下也能找到正確的欄位,請將欄位放在按鈕的後面;當一個按鈕查詢具有給定 ID 的對話方塊欄位的值時,它從頁面上按鈕出現的位置開始查詢,並獲取它找到的第一個具有正確 ID 的欄位,只有在它在按鈕之後沒有找到任何這樣的欄位時,才會檢視頁面的開頭。
可選模板引數 delegable=no 阻止按鈕將其操作委託給目標——否則它會嘗試這樣做。按鈕的委託只有在當前頁面是透過操作檢視時才有可能;目前,這個操作必須是 do。委託按鈕不會將其目標操作傳遞給它指定的那些對話方塊引數,而是修改傳遞給當前檢視的對話方塊引數,並將此修改後的對話方塊引數集傳遞給它的目標操作。
- 即使在技術上可能進行委託並且
delegable模板引數允許委託的情況下,按鈕也只有在目標操作與當前頁面正在檢視的操作相同的情況下,才需要嘗試進行委託。 do 操作只在此必要的情況下進行委託。 - 噹噹前操作和目標操作相同時,委託可以避免進行新的操作頁面訪問,這既可以節省時間和伺服器負載,又可以避免在顯示目標檢視之前,用“請稍候”訊息破壞性地替換當前檢視。
- 傳遞給當前檢視的對話方塊引數,但未由按鈕指定,將在委託期間傳遞給目標。當委託使這些額外的對話方塊引數可用時,目標檢視可能能夠利用這些引數。
- 委託的一個潛在缺點是,由於委託會破壞性地更新接收到的對話方塊引數,因此當前檢視無法透過單擊 Web 瀏覽器上的“後退”導航按鈕來恢復;“後退”通常會將您帶到最近一個沒有委託給其後繼檢視的頁面檢視。
可選的模板引數echo=非空會導致在主按鈕旁邊出現第二個按鈕,與第一個按鈕相同,但其目標操作是操作echo;這有助於除錯對話方塊,透過允許對話方塊撰寫者檢視按鈕傳遞的資料以及傳出的操作請求是否已驗證。
當請求某個操作執行具有重大後果的操作時,該操作可能需要一些證明請求是合法的證據。這透過對話方塊軟體提供的操作請求驗證來完成。經過驗證的操作請求來自頁面上的按鈕點選,該頁面滿足以下所有四個條件
- 源頁面必須是操作頁面,或者由操作頁面顯示。目前,唯一支援顯示另一個頁面的操作是do。
- 源頁面必須得到完全保護。
- 源頁面必須包含一個或多個模板呼叫,指定對導致顯示源頁面的傳入操作請求需要驗證什麼(如果有)。這些模板將在下面解釋。
- 負責顯示源頁面的操作必須在內部呼叫驗證。此內部呼叫既是操作如何確定其傳入的操作請求是否滿足頁面的要求,也是操作如何提供其傳出操作請求的驗證的方式。
對傳入操作請求的要求透過模板{{dialog/null requirement}} 和 {{dialog/require origin}}指定。
- {{dialog/null requirement}} 不需要對傳入的操作請求進行任何驗證。
- {{dialog/require origin}} 需要來自固定允許來源列表中的一個的已驗證傳入操作請求;這些允許來源由未命名的模板引數命名。可選的模板引數
proxy=名稱表示源頁面由命名操作頁面顯示,而不是源頁面本身是一個操作頁面。
如果在單個頁面上使用多個傳入驗證模板呼叫,則為了驗證傳入的操作請求,所有這些模板呼叫都必須得到滿足。特別是,如果{{dialog/require origin}}在沒有未命名模板引數的情況下呼叫,則無論頁面上發生了什麼其他呼叫,傳入的操作請求都無法驗證。
請仔細注意,驗證的是操作請求;任何特定操作頁面檢視都可能與兩個獨立的請求相關聯 - 一個傳入請求,其來源是當前請求之前檢視的頁面,以及一個可能存在的傳出請求,其來源是當前頁面。傳入請求的驗證完全取決於之前檢視的頁面;傳出請求的驗證取決於當前頁面,包括它對上述模板{{dialog/null requirement}} 和 {{dialog/require origin}}的使用。
如果頁面使用對話方塊功能,通常需要設計頁面,使其在使用者的瀏覽器不支援對話方塊功能的情況下合理地執行。這透過模板{{dialog/ifsupported}}來完成。模板接受兩個未命名引數。如果對話方塊功能可用,則第一個模板引數可見,而第二個模板引數隱藏。如果對話方塊功能不可用,則第一個模板引數隱藏,而第二個模板引數可見。
按鈕執行的操作體現為名稱格式為Wikibooks:Dialog/action的頁面,其中action是按鈕呼叫操作的名稱。這些操作被收集在一起,在Category:Dialog actions中。
do 操作執行幾種不同的功能,這些功能由傳入的對話方塊引數verb選擇。將所有這些功能放在單個操作下,可以從一個功能委託到另一個功能,節省大量時間(可能是每次按鈕點選一到兩秒)並避免重複地使用“請稍候”訊息中斷頁面顯示。
view 動詞在正在進行的對話方塊序列中顯示一個頁面,允許顯示的內容取決於之前的對話方塊。
傳入的對話方塊引數page命名要顯示的頁面,傳入的對話方塊引數替換了顯示頁面上的模板引數;如果顯示的頁面包含任何與傳入的對話方塊引數具有相同名稱的對話方塊欄位,則傳入的值將成為對話方塊欄位的初始值。
傳入的對話方塊引數值通常不被解釋為維基標記。模板{{dialog/preview}}將傳入的對話方塊引數preview的值解釋為維基標記。
view 動詞專門處理傳入的對話方塊引數REQUESTING-PAGE、INCOMING-AUTHENTICATED、USERNAME、USER-GROUPS、SUBJECT-EXISTS、SUBJECT-CONTENT、SUBJECT-TIMESTAMP、SUBJECT-CATEGORIES 和 SUBJECT-FLAGGED。REQUESTING-PAGE 命名操作請求來自的頁面;INCOMING-AUTHENTICATED 為非空,當且僅當傳入的操作請求已驗證。USER-GROUPS 命名檢視使用者所屬的所有使用者組,由雙引號分隔,並用空格隔開。SUBJECT-* 提供有關傳入對話方塊引數subject命名的頁面的資訊。
view 要求進行傳出的驗證,但指定驗證要求(透過{{dialog/null requirement}} 或 {{dialog/require origin}}) 是顯示頁面的責任,無論驗證是否成功,view 都將繼續進行。
在使用 do/view 指定按鈕和要顯示的固定頁面時,可以使用模板{{dialog/view}},而不是使用通用模板{{dialog/button}}。專門的模板負責操作和動詞,如果未提供模板引數page,則會發出警告。
顯示的頁面可能要求 view 動詞改為顯示錯誤處理頁面;這通常是在傳入的對話方塊引數未透過某些驗證檢查時進行的。錯誤處理頁面將/error 附加到顯示頁面的名稱。僅當請求頁面名稱不以“error”結尾且錯誤處理頁面存在時才會遵守重定向請求。重定向請求透過使用{{dialog/init}} 將對話方塊欄位local-error 設定為非空值來實現;遵循區域性引數的標準處理,錯誤處理頁面可以訪問保留的傳入對話方塊引數INCOMING-LOCAL-ERROR。有關subject命名的頁面的修訂歷史資訊可以透過以SUBJECT-HISTORY- 開頭的保留引數來請求;有關category命名的類別的成員可以透過以CATEGORY-MEMBERS- 開頭的保留引數來請求;有關file命名的檔案元資料可以透過以FILE-INFO- 開頭的保留引數來請求;維基標記可以透過保留引數EXPANDED-TEXT 來模板擴充套件;所有這些高階查詢都透過使用{{dialog/init}} 指定的區域性引數來進行管理。
當透過 do/view 檢視頁面時,頁面頂部顯示的頁面名稱是顯示頁面的名稱,選項卡引用檢視的頁面(歷史記錄、編輯等);標題右側的小括號內的維基連結提供對操作頁面的訪問。在撰寫本文時,側邊欄上的相關連結(如“WhatLinksHere”)仍然引用操作頁面而不是顯示頁面。
如果您透過除委託以外的方式從檢視頁面導航離開,則 do 操作會將對話方塊欄位的值儲存在顯示中。如果您後退以返回到顯示的檢視,則對話方塊欄位的值將自動恢復到您離開時的狀態。只儲存一定數量的這些頁面狀態,因此如果您在返回之前執行了許多其他操作,則資料可能已被丟棄;但例如,如果顯示的頁面包含{{dialog/button}},您可以單擊 echo 按鈕以檢視正在傳遞的值,然後後退以單擊主按鈕,而無需重新輸入顯示頁面上的所有欄位值。(但是,如果{{dialog/button}}位於直接檢視而不是透過 do/view 檢視的頁面上,則此方法將不起作用。)
對話方塊頁面可能要求使用者在透過 view 動詞檢視頁面之前透過模板{{dialog/confirm view}}確認一個確認問題(取消/確定)。
如果檢視請求的目標頁面完全受保護,它可以請求儲存請求對話方塊狀態以供稍後恢復,或者使用透過 {{dialog/init}} 指定的欄位(參見 此處)來恢復以這種方式儲存的對話方塊狀態。
編輯動詞基於一箇中介表單來修改或建立頁面,該表單確定操作是否允許,以及如果允許,編輯頁面後的新內容是什麼。要修改或建立的頁面由傳入的對話方塊引數 subject 指定,而中介頁面由傳入的對話方塊引數 form 指定;這些傳入的對話方塊引數必須由請求者提供。
只有在傳入的請求滿足作為獨立頁面在表單上指定的傳出身份驗證要求時,操作才允許(因此,包括 <noinclude> 塊但不包括 <includeonly> 塊)。因此,表單通常應包含一個呼叫 {{dialog/require origin}} 或 {{dialog/null requirement}} 的 noinclude 塊;編輯操作的許可權可能會被條件性地包含 {{dialog/require origin}} 拒絕,而沒有任何引數(無論包含任何其他條件,都禁止身份驗證)。如果目標頁面的狀態(存在和時間戳,如果存在)與傳入的對話方塊引數 local-basetimestamp 和 local-creation 不一致,操作也會被阻止,其中一個必須透過 {{dialog/init}} 提供。
主題頁面的新內容是透過與 view 動詞一樣的方式替換模板引數來確定的,將表單解釋為如果在主題頁面上包含(因此,省略 noincluded 塊)並擴充套件模板。實際上,因此表單計算主題的新內容。
在完成或失敗時,編輯動詞可能會將傳入的操作請求重定向到其他地方。
- 在完成時,可以透過傳入的對話方塊引數
local-summary提供自定義編輯摘要。如果提供了傳入的對話方塊引數page,則請求將轉發給動詞 view;因此,view 會接收與 edit 提供的相同的對話方塊引數,這些引數會根據表單上的任何 {{dialog/init}} 呼叫進行修改。在沒有引數page的情況下完成時,使用者只會停留在目標頁面上。 - 由於表單未經身份驗證而失敗時,可以透過傳入的對話方塊引數
local-error提供自定義錯誤訊息。如果表單具有完全受保護的子頁面/error,則傳入的請求將轉發到該子頁面;遵循對本地引數的標準處理,子頁面可以在保留的傳入對話方塊引數INCOMING-LOCAL-ERROR中訪問自定義錯誤訊息。 - 在其他失敗情況下,會向用戶報告錯誤訊息,並且如果可能,使用者將返回到發出編輯請求的對話方塊狀態。如果無法恢復之前的對話方塊狀態,則會提供一個選項列表,指導使用者下一步該怎麼做。
在指定具有 do/edit 和固定中介表單的按鈕時,可以使用模板 {{dialog/edit}} 代替通用模板 {{dialog/button}}。專用模板負責操作和動詞,並且如果未提供模板引數 form,則會強烈反對。
回聲操作顯示傳遞給它的對話方塊引數,以及傳入的操作請求的源頁面和代理頁面的經過身份驗證的名稱(如果有)。這可能有助於除錯對話方塊,例如 {{dialog/edit}} 或 {{dialog/view}}; 參見 上面。
可以設定對話方塊以響應單個按鈕點選執行一系列操作。這種能力是嚴格限制的,在訴諸於它之前,應仔細考慮其他替代方案。
當用戶手動單擊按鈕時,會在操作序列的長度上設定一個上限,該上限可以在另一個手動單擊之前執行;截至目前,這個上限最初為 10 個操作。在檢視頁面時,如果此序列上限大於零,並且頁面被適當地標記,並且頁面上有一個專用於序列使用的按鈕,則該按鈕會自動觸發,並且序列長度上限會遞減。有關詳細資訊,請參見 Wikibooks:Dialog/do/doc#Action sequences。
操作請求可以編碼為 URL,因此在瀏覽器中載入 URL 會發出對操作的請求。url 由帶有附加查詢引數的頁面連結組成。頁面連結可以是 Wikibooks:Dialog/do 或是 Wikibooks:Dialog;使用 Wikibooks:Dialog/do 速度更快,通常大約快兩秒,並且可以模擬一些委託按鈕的行為,儘管 Wikibooks:Dialog 涵蓋了 Wikibooks:Dialog/do 未處理的一些邊緣情況。
對於頁面 Wikibooks:Dialog/do,查詢引數 verb=verb 是必需的,用於命名請求的動詞。其他查詢引數指定要傳遞給操作的其他對話方塊引數。不要使用引數名稱 action,因為維基軟體會嘗試解釋它。查詢引數附加到 url,第一個引數前加 ?,連續引數之間加 &。例如
或者,您也可以使用 {{fullurl:...}} 魔術詞來組裝這樣的 url,如果您不介意這種技術還會傳遞一個虛假的引數 title=Wikibooks:Dialog/do
基於 Wikibooks:Dialog/do 的查詢 url 是“不穩定”的,因為如果您從維基頁面外部或直接檢視的維基頁面(而不是透過操作 do)訪問了這樣的 url,然後從該 url 導航離開並返回,查詢將轉換為新的操作請求;之前與頁面檢視相關聯的任何對話方塊資料都將丟失。另一方面,當這些 url 從透過 Wikibooks:Dialog/do 動詞 view 檢視的頁面內部使用時,單擊 url 會自動轉換為委託操作請求(儘管截至目前,它不會 驗證 委託請求)。在以這種方式委託時,保留的查詢引數 FIELDS 可以指定頁面上的欄位,以類似於按鈕的方式透過操作請求傳遞(參見 此處)。
對於頁面 Wikibooks:Dialog,查詢引數 dialog-action=action 是必需的,用於命名請求的操作。 Wikibooks:Dialog 偽操作將 url 轉換為操作請求(在內部,它實際上構建了一個非委託按鈕並自動單擊它)。例如
通常,生成的 action-request 不會被驗證。對於頁面 Wikibooks:Dialog,指定一個查詢引數 dialog-confirm=non-blank 會改變 url 的行為,因此它不會立即發出未經身份驗證的請求,而是會向用戶顯示一個按鈕供使用者點選,在按鈕下方顯示提議的對話方塊引數,並且當用戶點選按鈕時,會發出經過身份驗證的操作請求(源為 Wikibooks:Dialog)。
在任何給定時間,您的本地客戶端可能儲存著多個對話方塊資料組,因此,如果您導航回(不遠)到對話方塊頁面,您離開時在那裡存在的資料在您返回時仍將存在。提供了一個 診斷面板,使您可以瀏覽所有這些資料組的內容。該面板還具有專家模式,允許訪問有關這些資料集的更多內部元資料,並在某些情況下允許訪問尚未完全提交到中央系統的暫定對話方塊資料組。
管理員可以建立新的操作。這在開發現有操作的升級時最為常見(幾乎可以肯定的是操作 do)。這些功能旨在提供一組功能強大且用途廣泛的小型操作,並透過安全檢查(例如完全受保護的頁面和操作請求身份驗證)進行嚴格限制;建立新操作的人員強烈建議保持此策略。
操作由兩個頁面定義。
- 操作的公共介面是頁面
Wikibooks:Dialog/action,其中 action 是用於指定操作的名稱 {{dialog/button}}。此頁面應包含對 {{dialog/action page}} 的呼叫,包含在允許在呼叫操作時方便地替換“請稍候”訊息的 html div 元素中,並在 Category:Dialog actions 中分類,並使用合適的排序鍵。有關規範示例,請參見 Wikibooks:Dialog/do。
- 操作頁面上的模板 {{dialog/action page}} 提供了一個連結,用於建立操作文件頁面,以描述操作的行為。
- 操作行為的 JavaScript 實現是頁面
MediaWiki:Common.js/w/Wikibooks:Dialog/action。(該專案在 MediaWiki:Common.js 中配置,因此在載入任何頁面 page 時,會執行 JavaScriptMediaWiki:Common.js/w/page。)操作的 JavaScript 基本框架以及在 JavaScript 中呼叫各種對話方塊功能的說明,在 MediaWiki talk:Dialog/receive 中提供。負責編寫新操作的管理員應該研究現有操作的 JavaScript。
新操作的開發應在使用者空間進行。普通使用者無法在使用者空間中呼叫操作,但管理員可以。如果按鈕在使用者空間中指定操作頁面,則不會新增字首 Wikibooks:Dialog/,並且只有管理員才能單擊該按鈕(嘗試單擊的非管理員會收到錯誤提示資訊)。每個對話方塊操作可能都有一組測試頁面選單,管理員可以使用這些選單來測試使用者空間中操作的替代方法。一旦操作準備就緒,就可以在專案空間中重新建立它。