Manual:Hooks/zh



钩子可以让自定义的代码在某些特定事件发生时运行(例如保存页面或者用户登录). 例如，下列代码段将会在 钩子触发时调用函数，并将特定的参数传入.

可以通过将钩子的名称映射到-{zh-hans:扩展; zh-hant:擴充功能;}-的文件中的回调函数来注册钩子：

MediaWiki提供许多像這個一樣的钩子来扩展MediaWiki軟體的功能. 将一个函数（称为钩子handler）分配给一个钩子，将导致该函数在MediaWiki主代码的适当位置被调用，以执行开发人员认为在该位置有用的任何额外任务. 每个钩子可以有多个分配给它的handler，在这种情况下它将按照分配的顺序调用函数，并将先一个功能所做的修改传递给后面的功能.

在的「末尾」或你自己的扩展文件中的文件范围（「不是」在的函数或的钩子中），将函数分配给钩子. 对于扩展来说，如果钩子函数的行为是以LocalSettings.php中的设置为条件的，那么钩子应该被分配，如果条件没有被满足，函数应该提前终止.

你也可以在你自己的扩展中创建一些新的钩子. 它被在extension.json中注册，如同是你注册一个内置的MediaWiki钩子在你的扩展中使用一样. 然后你可以通过调用在你的扩展內运行你的钩子. 最后，別忘了把它们添加进.

背景
钩子是由对HookContainer::run的调用触发的，通常是通过HookRunner中的一个方法. HookContainer将會找到要运行的钩子handler，并用给HookContainer::run的参数调用它们. 钩子handler通过注册.

参见.

在这个例子中，从中的 函数，doPurge调用HookRunner::onArticlePurge来运行的钩子，传递 作为参数.

调用许多钩子，但也可以调用钩子



撰寫钩子handler
钩子handler是一个你注册的函数，它将在無論何時上述的钩子运行时被调用.

对于扩展，在 中注册你的钩子handler.

钩子handler也可以通过全域的阵列注册. 这最常用于中的特定站点定制，或在 之前的传统扩展中. 以下都是为EventName钩子定义钩子handler的有效方式，有两个参数传递：

注意，当一个物件被分配，而你没有指定一个方法时，所调用的方法是「onEventName」. 例如，「onArticleSave」、「onUserLogin」等等.

如果你想将同一个函数或物件用于不同的目的，可选的数据是很有用的. 比如说：

这段代码将导致在保存页面时， 被运行两次：一次是因为'TimStarling'，另一次是因为'brion'.



钩子handler的返回值
钩子handler可以返回三种可能的值之一.


 * （无返回值，或为空）--钩子handler已成功操作. （在MediaWiki 1.23版之前，返回是必须的）.
 * 「some string」 - 发生了一个错误；应该停止处理，并向用户显示错误.
 * - 钩子handler已经完成了所有必要的工作，或取代了正常的处理. 这将阻止进一步的handlers的运行，在某些情况下，告诉调用函数跳过正常处理.

Returning false makes less sense for hooks that run after an action is already completed. In those cases, the return value is often ignored.

Handling hooks in MediaWiki 1.35 and later
MediaWiki 1.35 introduces the HookHandlers system. This includes per-hook interfaces for improved static validation and discovery of parameter documentation. It also enables dependency injection by introducing an intermediary class instance that accepts a number of specified services (instead of static callbacks that explicitly access services from global state).

The approach from MediaWiki 1.34 and earlier, of registering hook handlers directly as static methods, remains supported and is not deprecated. Extension authors may opt-in to the new system are welcome to do so. To learn more, see the MediaWiki core: Hook specification and the announcement on wikitech-l.

Changes to hook names

Prior to MediaWiki 1.35, hooks sometimes included characters that could not be used in a class or method name, such as colons and dashes. With the introduction of per-hook interfaces, the canonical names of these hooks have been changed to use underscores instead. For example, the interface for ApiFeedContributions::feedItem is. Hook handlers that are registered with the old names remain supported.

Registering hooks using HookHandlers

To adopt the new system, change your Hooks class to have regular methods instead of static methods and to be constructible. This class is then registered once, via the HookHandlers attribute in extension.json, using the  option as part of an ObjectFactory description where you can use the   option.

For example, to register the BeforePageDisplay hook:

Handling hooks using interfaces

To use hook interfaces, extensions should define a Hooks class in their namespace and implement one or more hook interfaces. Hook interfaces are named with the hook name followed by the word "Hook".

Convert an extension to the new hook system:

Follow these steps for each hook handling method:
 * identify the hook handler interface, and make the Hooks class implement this interface.
 * update the method name and signature to be exactly the same as in the interface.
 * change the "Hooks" section of extension.json to refer to the handler you specified in the "HookHandlers" section.

The process was demonstrated at the Wikimedia Hackathon 2021:
 * Example patch for an extension
 * Recording on YouTube

Hook behavior before MediaWiki 1.22 vs after
Extracted from: change 500542: for non-abortable hooks (most hooks) returning true has been redundant since MediaWiki 1.22 (in 2015). This was done to reduce chances of accidental failure because we had experienced several outages and broken features due to silent failures where e.g. one hook callback somewhere accidentally returned a non-bool or false instead of true/void and thus short-circuits the whole system.

(Returning non-true/non-void in a MediaWiki Hook is equivalent to  and   in JavaScript events, it kills other listeners for the same event).

For example, if  hook were to return false in MobileFrontend, it would mean Popups stops because its callback would no longer run. 假定钩子为 ，请参见下面的区别.

MediaWiki 1.22前：

或

MediaWiki 1.22+

文档
Currently, hooks in MediaWiki core have to be documented both in hook interface (in the source code repository) and here on MediaWiki.org. In some cases, one of these steps may not yet have been completed, so if a hook appears undocumented, check both.

Each hook provided by MediaWiki Core is defined in a hook interface. Typically, hook interfaces are located in a "Hook" sub-namespace inside the caller namespace. For example,. You can find a list of hook interfaces in the generated MediaWiki PHP documentation.

To document a hook on-wiki, use MediaWikiHook.

 Hook interface doc template 

In hook interfaces, doc comments specify the status, purpose, parameters, and behavior of the hook.



可用的钩子


以功能分类的钩子
Some of these hooks can be grouped into multiple functions.
 * Sections: Article Management  -  Edit Page  -  Page Rendering  -  User Interface  -  File Management  -  Special Pages  -  User Management  -  Logging  -  Skinning Templates  -  API  -  Import/Export  -  Diffs  -  Miscellaneous

Alphabetical list of hooks
For a complete list of hooks, use the, which should be kept more up to date.

參見

 * — specification of the hooks system
 * List of hook interfaces in MediaWiki Core
 * — contains examples of hooks
 * — the JavaScript/front-end system of hooks
 * — specification of the hooks system
 * List of hook interfaces in MediaWiki Core
 * — contains examples of hooks
 * — the JavaScript/front-end system of hooks