Manual:Tag extensions/zh

对于个人项目来说，扩展内嵌的wiki标签以提升wiki的功能是非常有用的，无论是简单的字符串处理，还是成熟的信息检索. 标签扩展允许用户建立新的自定义标签用以实现上述功能. 举例来说，一个人可能使用标签扩展来推行一个简单的 (捐赠)标签，来在页面中插入捐赠表格. 擴展，以及解析器功能和鉤是更改或增強MediaWiki功能的最有效方法. 在開始擴展工作之前，您應該始終檢查矩陣，以確保其他人沒有完全按照您的嘗試進行操作.

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

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


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

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

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

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

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

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

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

另請參見發布擴展程序.

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

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

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

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

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

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

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

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

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

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

關於此的一些重要說明：


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

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

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

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


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

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

對preSaveTransform的原始調用故意在所有擴展標記內跳過此類轉換. 如果您需要執行預保存轉換，則應考慮使用 parser function. 所有標記擴展也可以使用 作為解析器函數調用，它將應用預保存轉換.
 * 您现有的签名 (, ~ ,  )
 * 擴展鏈接標籤，也稱為“管道技巧”（例如，將 Help:Contents 更改為 Contents ）.  如果沒有此步驟， Help:Contents 之類的速記鏈接將被視為無效，並在解析時保留為wiki文本格式.
 * 擴展 模板.

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

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


 * 替換strip marker. 條帶標記是在處理wikitext的各個階段插入的某些項目，以作為標記在以後重新插入刪除的內容.  這不是擴展通常需要擔心的事情.
 * $ 1將*轉換為列表，並將從前導空格開始的任何行轉換為＆lt; pre＆gt; 除其他事項外. 在某些擴展中，這有時可能是一個問題.

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

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

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

示例擴展信用是：

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


 * 'specialpage'&mdash;reserved for additions to MediaWiki Special Pages;
 * 'parserhook'&mdash;used if your extension modifies, complements, or replaces the parser functions in MediaWiki;
 * 'variable'&mdash;extension that add multiple functionality to MediaWiki;
 * 'media'&mdash;used if your extension is a media handler of some sort
 * 'other'&mdash;all other extensions.

The  is the name of an interface/i18n message that describes your extension that will need to be defined in your extension's i18n.php file. If you omit this field, the  field will be used instead.

Retrieving the tag name inside of the callback
Suppose you have several tags  and   that share the same callback, and inside the callback function, you want to obtain the name of the tag that invoked the callback.

The short answer is: the tag name ( or  ) is not present in any of the callback's arguments. But you can work around this by dynamically constructing a separate callback for each tag:

参见

 * – List of special tag/variables like,  , ...
 * – List of parser tags in use on Wikimedia wikis.
 * Project:Extension requests
 * Project:Extension requests
 * Project:Extension requests
 * Project:Extension requests
 * Project:Extension requests