Manual:Tag extensions/zh



对于个人项目来说，扩展内嵌的wiki标签以提升wiki的功能是非常有用的，无论是简单的字符串处理，还是成熟的信息检索. 标签扩展允许用户建立新的自定义标签用以实现上述功能. 举例来说，一个人可能使用标签扩展来推行一个简单的 (捐赠)标签，来在页面中插入捐赠表格. 擴展，以及解析器功能和鉤是更改或增強MediaWiki功能的最有效方法. 在开发擴展之前，您應該始終檢查整个互联网，避免重写别人写过的东西.

一個簡單的標籤擴展包含一個回调函数，它钩到解析器，這樣當解析器運行時，它會找到並替換所有特定標記的實例，調用相應的回调函数來呈現實際的HTML.

例子
In extension.json, set up the hooks:

And add the hook into a PHP file

此示例為 標記註冊回調函數. 當用戶將標記： 添加到頁面時，解析器將調用 函數，傳入四個參數：


 * $input : 和 標記之間輸入，如果標記是“關閉”則輸入'null，即
 * $args : 標記參數，像超文本標記語言標記屬性一樣輸入; 這是一個以屬性名稱作键的關聯數組（键-值对）.
 * $parser : 父解析器（一個解析器對象）; 更高級的擴展使用它來獲取上下文標題，解析維基文本，擴展大括號，註冊鏈接關係和依賴關係等.
 * $frame : 父框架（PPFrame對象）.  它與$parser一起使用，為解析器提供有關調用擴展的上下文的更完整信息.

有關更詳細的示例，請參閱Tag擴展示例

属性
讓我們看另一個例子：

此示例轉儲傳遞給標記的屬性及其值. 很明顯，這允許靈活地指定新的自定義標籤. 例如，您可以定義一個標籤擴展，允許用戶在其用戶頁面上註入聯繫表單，使用類似.

MediaWiki有一個名副其實的標籤擴展名，其中一些在本網站列出; 其他人可以通過快速網絡搜索找到. 雖然其中一些對於它們的使用案例非常專業，但是有許多廣受歡迎且使用良好的擴展提供不同程度的功能.

約定
有關擴展的一般佈局和設置，請參閱.

發布您的擴展程序
在擴展代碼中創建新鉤的#Extensions應該在extension hook registry上註冊它們.
 * 1) 在此Wiki上創建一個名為Extension:的新頁面，其中包含有關您的擴展程序的信息，如何安裝它以及正在使用的屏幕截圖. 已創建一個方便的模板來保存名為的信息.  请参阅Help:指南了解更多信息.  您還應該盡可能多地向頁面正文添加詳細信息，並且明智地定期檢查以回復相關聯談話頁面上的用戶問題.  另外，請確保該頁面屬於.
 * 1) Notify mediawiki-l郵件列表.

另請參見發布擴展程序.

报告关注
您將注意到上面的示例中的輸入在返回之前使用 進行轉義. 在將所有用戶輸入回送給客戶端之前，以這種方式處理所有用戶輸入是至關重要的，以避免引入任意超文本標記語言注入的向量，這可能導致跨站點腳本漏洞.

加載模塊
為擴展程序添加模塊的正確方法是將它們附加到ParserOutput而不是$wgOut. 然後，模塊列表將自動從ParserOutput對像中獲取，並且即使在預先緩存頁面呈現時也會添加到$wgOut. 如果您直接將模塊添加到$wgOut，它們可能不會緩存在解析器輸出中.

附带扩展
如果您更改擴展程序的代碼，理論上，使用該擴展程序的所有頁面都會立即反映新代碼的結果. 從技術上講，這意味著每次呈現包含擴展名的頁面時都會執行代碼.

實際上，由於頁面緩存（通過MediaWiki軟件，瀏覽器或中間代理或防火牆）通常不是這種情況.

要繞過MediaWiki的解析器緩存並確保生成新版本的頁面，請單擊編輯，將“action=purge”替換為瀏覽器地址欄中顯示的網址中的“action=edit”並提交新網址. 將重新生成頁面及其引用的所有模板，忽略所有緩存的數據. 如果主頁面本身未被修改，則需要清除操作，但必須更改它的方式（擴展已被修改，或僅修改了引用的模板）.

如果這不足以為您提供頁面的新副本，則通常可以通過在上述URL的末尾添加“&rand=somerandomtext”來繞過中間緩存. 確保'somerandomtext'每次都不同.

如何使用我的擴展程序禁用頁面緩存？
從MediaWiki 1.5開始，解析器作為第三個參數傳遞給擴展. 此解析器可用於使緩存無效，如下所示：

在編輯其他頁面時重新生成頁面
也許您不想完全禁用緩存，只需要在編輯其他頁面時重新生成頁面，類似於處理模板轉換的方式. 這可以使用傳遞給鉤子函數的解析器對象來完成. 以下方法取自並且似乎可以用於此目的.

緩存行為的細粒度調整
您可以使用緩存鍵來區分不同版本的擴展輸出，從而為擴展使用細粒度緩存. 渲染時，您可以通過向鉤子函數添加addExtraKey方法為每個特徵添加緩存鍵，例如：

但是，在解析期間修改$parser->getOptions意味著在嘗試獲取緩存頁面時不包括額外的選項鍵，只有在渲染頁面進入緩存時，才能使用PageRenderingHash鉤子來設置額外的選項. PageRenderingHash在將頁面放入緩存並將其取出時都會運行，因此如果它們尚未存在，則僅向哈希添加新密鑰非常重要. 例如:

關於此的一些重要說明：


 * 在confstr中使用“!setting1=$value”而不僅僅是“!$value”可確保如果安裝了不同的擴展或其加載順序更改，則解析器緩存不會變得混亂. !用作不同渲染選項的分隔符
 * 有些人使用 而不是 . 請注意，addExtraKey不會告訴解析器緩存額外的密鑰正在使用中，因此如果您不小心，很容易導致破壞緩存.

自版本1.16起
解析器鉤子函數傳遞對解析器對象和幀對象的引用; 這些應該用於解析wiki文本.

自1.8版本開始出現. 它的優點包括簡單（它只需要一個參數並返回一個字符串）以及它解析 中的擴展標記這一事實，因此您可以嵌套擴展標記.

recursiveTagParse的第二個參數， 是MW 1.16 alpha (r55682)中引入的可選參數.


 * 如果提供 （使用傳遞給您的擴展名的 的值），那麼 中的任何模板參數都將被擴展.  換句話說， 等內容將被識別並轉換為適當的值.
 * 如果未提供 （例如， ），或者 設置為false ，然後模板參數不會被擴展; 不會被更改.  雖然這不太可能是理想的行為，但這是MW 1.16之前唯一可用的選擇.

但是，即使使用recursiveTagParse，仍然會跳過標記的一步解析，即Parser::preSaveTransform. preSaveTransform是解析的第一步，負責對即將保存的wiki文本進行永久性更改，例如：


 * 您现有的签名 (, ~ ,  )
 * 擴展鏈接標籤，也稱為“管道技巧”（例如，將 Help:Contents 更改為 Contents ）.  如果沒有此步驟， Help:Contents 之類的速記鏈接將被視為無效，並在解析時保留為wiki文本格式.
 * 擴展 模板.

對preSaveTransform的原始調用故意在所有擴展標記內跳過此類轉換. 如果您需要執行預保存轉換，則應考慮使用parser function. 所有標記擴展也可以使用 作為解析器函數調用，它將應用預保存轉換.

自版本1.5起
從MediaWiki 1.5開始，支持XML樣式參數（標記屬性）. 參數作為第二個參數傳遞給鉤子函數，作為關聯數組. 值字符串已經為您解碼了HTML字符實體，因此如果將它們發送回HTML，請不要忘記使用 ，以避免HTML注入的風險.

如何避免修改擴展程序的超文本標記語言輸出？
標籤擴展的返回值被認為是“幾乎”解析的文本，這意味著它不被視為純超文本標記語言，但仍然略有修改. 對標籤擴展的輸出做了兩件主要的事情（以及其他一些小事）：


 * 替換strip marker. 條帶標記是在處理wikitext的各個階段插入的某些項目，以作為標記在以後重新插入刪除的內容.  這不是擴展通常需要擔心的事情.
 * 会将*转换为无序列表，并将以空格符为开始的一行转换为&lt;pre&gt;. 在某些擴展中，這有時可能是一個問題.

標記擴展還支持返回數組而不僅僅是字符串（很像解析器函數），以便更改返回值的解釋方式. 數組的第0個值必須是html. “markerType”鍵可以設置為 ，以便停止進一步解析. 執行類似 將確保$html值不會被進一步修改並視為純超文本標記語言.

如何讓我的擴展程序出現在Special:Version？
要使您的擴展程序顯示在MediaWikiSpecial:Version頁面上，您必須在PHP代碼中指定擴展名.

為此，請在鉤子線或函數定義之前添加 變量作為第一個可執行代碼行.

示例擴展信用是：

將 替換為以下之一（除非您的擴展屬於多個類＆mdash;然後為each類創建一個信用）：


 * 'specialpage'＆mdash;保留用於添加MediaWiki特殊頁面;
 * 'parserhook'＆mdash;如果你的擴展修改，補充或替換MediaWiki中的解析器函數，則使用它;
 * 'variable'＆mdash;為MediaWiki添加多項功能的擴展程序;
 * 'media'＆mdash;如果您的擴展程序是某種媒體處理程序，則使用它
 * '其他'＆mdash;所有其他擴展.

是接口/i18n消息的名稱，它描述了您的擴展，需要在擴展的i18n.php文件中定義. 如果省略此字段，則將使用 字段.

在回調中檢索標記名稱
假設你有幾個共享相同回調的標籤 和 ，並且在回調函數中，你想獲得調用回調的標籤名.

簡短的回答是：標記名稱（ 或 ）不存在於任何回調的參數中. 但您可以通過為每個標記動態構建單獨的回調來解決此問題：

参见

 * – 特殊標籤/變量列表，如 ，  ，……
 * – 維基媒體wiki上使用的解析器標籤列表.