Manual:魔术字

From mediawiki.org
This page is a translated version of the page Manual:Magic words and the translation is 90% complete.
Outdated translations are marked like this.
MediaWiki扩展

魔术字是一种将各种wiki文本字符串映射到与函数关联的单个ID的技术。 变量解析器函数使用这种技术。 映射到该ID的所有文本都将替换为函数的返回值。 文本字符串和ID之间的映射存储在变量$magicWords中的文件中,该文件可以使用$wgExtensionMessagesFiles[] 加载。

默认魔术字在CoreParserFunctions.php 中实现。

魔术字是怎样工作的

每当MediaWiki在两个花括号间寻找文本时({{XXX ...}}),它必须确定是变量解释器功能又或者是模板。因此,它会出现一系列的问题:

  1. 它是否有关联的魔术字ID?作为解决{{XXX...}}形式标记的第一步,MediaWiki尝试将XXX翻译成魔术字ID。翻译表由$magicWords定义。
    • 如果没有魔术单词ID与“XXX”相关联,则“XXX”被假定为模板

  2. 它是变量吗?如果魔术字ID找到,MediaWiki接下来会检查它是否有任何参数。
    • 如果没有找到参数,MediaWiki会检查魔术单词ID是否已被声明为可变ID。‎ 为了检查这一点,它通过调用MagicWord::getVariableIDs()来检索魔术单词列表。 这个方法从一个硬编码的变量id列表(参见Help:Variables )和钩子MagicWordwgVariableIDs 所附带的所有函数所提供的自定义变量id列表中获取变量id列表。

  3. 它是解析器函数吗?如果这个魔术字包含任意参数,或者变量魔术字ID列表中缺少对应的魔术字ID,则MediaWiki假定该魔术字是解析器函数模板。如果在通过调用$wgParser->setFunctionHook($magicWordId, $renderingFunctionName)声明的解析器函数列表中找到其魔术字ID,则将其视为解析器函数,并使用名为$renderingFunctionName的函数呈现。否则,它被判断为模板。 If the magic word ID is found in the list of parser functions declared via a call to $wgParser->setFunctionHook($magicWordId, $renderingFunctionName), it is treated as a parser function and rendered using the function named $renderingFunctionName. Otherwise, it is presumed to be a template.
按照惯例:
  • 称为魔术字的变量都是大写的,区分大小写,并且没有空格。
  • 解析器函数以哈希符号(#)为前缀,不区分大小写,并且不包含空格。

然而,这只是一个惯例,没有始终如一地适用(由于历史原因)。

  • 变量不包含空格,但其他语言中变量的某些翻译确实有空格
  • 变量通常大写且区分大小写,但某些解析器函数也符合此惯例。
  • 某些解析器函数以哈希符号开头,但有些则不然。

在定义或翻译魔术字时应尽可能遵循惯例。 魔术字的优先级高于模板,因此定义的任何魔术字都将阻止将该定义的名称用作模板。

遵循惯例可以避免造成越来越多的潜在冲突。

定义魔术字

为了让魔术字起到它的作用,我们必须做到以下事情:

Wiki文本与魔术字ID互相映射 魔术字ID与相关的php设置映射

将wiki文本映射到魔术字ID

变量$magicWords用来将每个魔术词语ID与一个依赖语言的数组关联在一起,该数组描述了所有映射到魔术词语ID的所有文本字符串。 重要:这仅设置了后端i18n映射,你仍然需要继续编写其他代码来让MediaWiki在其他地方使用该魔术字。 此外,请确保在添加特定于语言的值之前将$magicWords初始化为空数组,否则在尝试加载魔术字时会遇到错误,并且需要重建本地化缓存才能正常工作。

此数组的第一个元素是一个整数标志,指示魔术字是否区分大小写。其余元素是应该与魔术字ID相关联的文本列表。如果区分大小写标志为0,则数组中名称的任何大小写变体都将匹配。如果区分大小写标志为1,则只有大小写完全匹配的项才会与魔术字ID相关联。 因此格式为$magicWords['en'] = [ 'InternalName' => [ 0, 'NameUserTypes', 'AdditionalAliasUserCanType' ] ];

此关联由$magicWords使用$wgExtensionMessagesFiles[] 注册的文件中创建。

在下面的示例中,安装西班牙语MediaWiki会将魔术字ID ‘MAG_CUSTOM’与“personalizado”、“custom”、“PERSONALIZADO”、“CUSTOM”和所有其他大小写变体相关联。 在英文MediaWiki中,只有各种大小写组合中的“custom”才会映射到“MAG_CUSTOM”:

文件Example.i18n.magic.php

<?php

$magicWords = [];

$magicWords['en'] = [
	'MAG_CUSTOM' => [ 0, 'custom' ],
];

$magicWords['es'] = [
	'MAG_CUSTOM' => [ 0, 'personalizado' ],
];

在extension.json文件的一部分:

"ExtensionMessagesFiles": {
	"ExampleMagic": "Example.i18n.magic.php"
}

请注意,“ExampleMagic”与用于普通国际化文件的键值不同(通常只是扩展名的标题,即“Example”)。“Magic”是故意附加的,因此不会导致键值覆盖。

内联PHP

您可以在 PHP 中内置关联的魔术词,而不是通过 i18n 文件。 这在在LocalSettings.php中定义钩子时很有用,但不应在扩展中完成。

MediaWiki\MediaWikiServices::getInstance()->getContentLanguage()->mMagicExtensions['wikicodeToHtml'] = ['MAG_CUSTOM', 'custom'];

将魔术字ID与PHP函数关联

将魔术字ID与呈现函数关联的机制取决于魔术字是用作解析器函数还是变量。有关更多信息,请参阅:

本地化

参见 Help:魔术字#位置来寻求帮助。

您可以在手册:消息API手册:语言#命名空间中阅读有关用于本地化的魔术字的定义和用法的更多信息,避免在消息中使用{{SITENAME}}

行为开关(双下划线魔术字)

行为开关是一种特殊类型的魔术字。可以通过使用双下划线(而不是双花括号)来辨别它们。 例如: __NOTOC__

这些魔术字通常不输出任何内容,而是更改页面的行为和/或设置页面属性。 这些魔术字在MagicWordFactory::mDoubleUnderscoreIDs中列出,也列在 帮助:魔术字#行为开关。 大多数标准行为开关的效果都在Parser::handleDoubleUnderscore()中定义。 如果没有定义具体的效果,魔术字将简单地在 page_props 表中设置一个页面属性。 以后也可以通过测试$parser->getOutput()->getPageProperty( 'MAGIC_WORD' )是否为null或空字符串来检查这一点

自定义行为开关

下面是一个实现自定义__CUSTOM__行为开关的示例扩展

custom/extension.json - 这是一个雏形,真正的扩展将填写更多字段。

{
	"name": "Custom",
	"type": "parserhook",
	"AutoloadClasses": {
		"MyHooks": "MyHooks.php"
	},
	"Hooks": {
		"GetDoubleUnderscoreIDs": [
			"MyHooks::onGetDoubleUnderscoreIDs"
		],
		"ParserAfterParse": [
			"MyHooks::onParserAfterParse"
		]
	},
	"ExtensionMessagesFiles": {
		"CustomMagic": "custom.i18n.php"
	},
	"manifest_version": 1
}

custom/custom.i18n.php

<?php
$magicWords = [];
$magicWords['en'] = [
	'MAG_CUSTOM' => [ 0, '__CUSTOM__' ],
];

custom/MyHooks.php

<?php
class MyHooks {
	public static function onGetDoubleUnderscoreIDs( &$ids ) {
		$ids[] = 'MAG_CUSTOM';
	}

	public static function onParserAfterParse( Parser $parser, &$text, StripState $stripState ) {
		if ( $parser->getOutput()->getPageProperty( 'MAG_CUSTOM' ) !== null ) {
			// Do behavior switching here ...
			// e.g. If you wanted to add some JS, you would do $parser->getOutput()->addModules( 'moduleName' );
		}
	}
}

参见