This page is a translated version of the page Help:Templates and the translation is 100% complete.
PD 注意:當您編輯本頁面時,即同意以CC0協議授權您的貢獻。您可以在公有領域帮助页面找到更多信息。 PD

如果你有某個標準文本要放入到多个页面中,MediaWiki的模板就能發揮作用。 模板不像是擴充功能或媒体文件,它没有集中的存放庫。模板可以是新编写的、也可以是某個已完成的工作,將它从wiki站点(如维基百科)导出,然后导入到目标wiki站点,以節省重复的工作。

创建

模板就是标准的wiki页面,其内容是設計用來嵌入包含(將文件以連結的形式置入)到其他页面中的。模板名称遵循以“Template:”為前置字元的慣例,這會将其指派给對應的命名空间;而且,您可以像创建其他任何Wiki页面一样创建模板頁面

最简单的模板用法如下。假设您创建了一个内容如下、名为“Template:Welcome”的页面:

您好!欢迎来到本wiki。

這樣,你就已經創建了你的第一個模板!如果你接下來在其他任何頁面中插入這段程式碼:

{{Welcome}}

在任何其他页面中查看该页面时,“你好!欢迎来到本wiki。”的文本将代替 {{Welcome}}。模板内容被“嵌入包含”到另一个页面中,也就是,它被結合在页面中。

您可以在任何您想要欢迎某人的页面上的任何位置插入 {{Welcome}}。假设它已被使用在100个页面中,若您随后将模板内容更改为:

你好呀!欢迎来到这个奇妙的Wiki。

然後你重新访问任何一个那100个使用该模板的页面,您将看到新文本而不是原始文本。在這種方式中,您不曾编辑100个页面的内容卻已经更改了它们,就是因为該模板已被嵌入包含到这些页面中。

这只是模板的一个最基本的应用。嵌入包含还有几个其它功能,丰富了这一机制,使模板变得非常有用。

用法

模板可以以下列方式用於在其他页面中:

  • {{模板名稱}}—就像上面描述的那样,每当带有这串代码(一般我们称这串代码为“模板调用”)的页面被加载时(即读者开始浏览内容页面时),这串代码将会被某個命名為模板:模板名称的頁面的当前内容被一個被称为“嵌入包含(transclusion)”的过程給“动态地”替换掉。 由于模板的调用会保留在源代码中,因此对模板:模板名称的任何后续的更改,都会在包含了此模板调用的页面上看到。 同时,这个页面也会被列入“链接到”这个模板的列表中。
  • {{subst:模板名称}} — 在此类型的模板被使用的時候,從在包含此模板调用的页面被保存之时起,它會被模板:模板名称的“静态副本”所取代。 这就是说,模板:模板名称的内容会在调用之时,被它的副本所“替代”(SUBSTitute)。 页面與模板之间不再保持链接,所以每一个页面都可以另外被编辑而不會影响其餘的页面。 在效果上,使用此方式替代模板的内容,相比於只是单純地将內容“手动”输入到页面源代码中,還是有些微的不同。
  • {{safesubst:模板名称}} — 用於模板在包含有对其他模板或解析器函数的调用时,允許其递归替换。 更多信息,请参见Help:替换引用
  • {{msgnw:模板名称}} - 将模板内容的源代码包含在页面中,类似‎<nowiki>一样。

事实上,一般的wiki页面也可以用作模板,只需指定其所在的命名空间即可,因此:

  • {{模板:页面名称}} 嵌入包含 [[模板:页面名称]] 的内容(等同于{{页面名称}})。
  • {{讨论:页面名称}} 嵌入包含标题为“讨论:页面名称”的页面的内容。
  • {{:页面名称}} 嵌入包含标题为“页面名称”的页面的内容(例如,在主命名空间)。
    • {{subst::页面名称}} 替换为标题为“页面名称”的内容。

若指定的命名空间不存在,则完整的标题會被假定是一个模板:

  • {{Foo:Bar}} 會嵌入“模板:Foo:Bar”。

参数

为丰富嵌入包含的机制,MediaWiki允许模板被嵌入时,对这个模板传递参数。由于参数的作用,模板可以產生出不同的内容或表現出不同的行为。

假设你想要在其他用户裏的讨论页之中插入一条感谢函,有如:


感谢你! 感谢你的努力。 祝好,张三敬上。


這個感谢函會包括感谢的原因(示例中的“你的努力”)和署名(“张三”)。您的目标是任何一個用户都可以感谢任何其他的用户,无论是任何原因。

这样,這個感谢函在任何地方使用时都会看起来相似,你可以定义一个,譬如說,命名为模板:Thankyou 的模板。 虽然某個用户感谢其他用户的感谢函看起来都差不多,但其特定内容(即原因和署名)仍有所不同。 基於這個理由,你應該把这些内容设置为参数。 如果我们忽略其余用于格式化方框和放置图片的元素,模板的核心内容将是这样的:

'''感谢你!'''
感谢{{{1}}}。
祝好,{{{2}}}敬上。

注意{{{1}}}{{{2}}}的使用。这就是使用模板时在模板內识别传入的参数的方法。請注意:在模板内,每一个参数都是被三组花括号包围:{{{ }}}。这与一般的模板名称的使用不同。

在使用模板时,需要为参数赋值,不同参数间用一个管道符(|)分隔。MediaWiki允许三种为参数赋值的方式:匿名(Anonymously)、编号(Numbered)、命名(Named)。

匿名参数

要匿名传递参数,需要按顺序列举出这些参数:

{{Thankyou/zh|你的努力|张三}}

在这个例子中,{{Thankyou}}模板接收参数{{{1}}}=你的努力{{{2}}}=张三,于是输出:


感谢你! 感谢你的努力。 祝好,张三敬上。


匿名传递参数时,赋值的顺序十分重要。假如颠倒了赋值顺序:

{{Thankyou|张三|你的努力}}

输出结果为:


感谢你! 感谢张三。 祝好,你的努力敬上。


按顺序识别参数(用{{{1}}}等等)「僅」对匿名参数有效。 任何用名称标识的参数,如下图所示,将無法被使用序号的模板访问。
如果在匿名模板参数的变量中有個等号(=),它将會被错误地解讀为一个命名参数(在下面有解释),把等号之前的文本误认为参数名称、且把等号后面的文本误认为参数的值。 当您需要在属性中包含某個外部链接或某個HTML元素时,就会遇到这个常见的问题(参见任务T16235)。 避免这个问题的方法是使用命名参数来代替,或编号参数,见下文。

编号参数

按编号传递参数时,需要给出变量的编号:

{{Thankyou|2=张三|1=你的友好}}

例中,虽然它们是按相反的顺序提供的,但模板{{Thankyou}}接收到的是{{{1}}}=你的友好{{{2}}}=张三,所以将会输出:


感谢你! 感谢你的友好。 祝好,张三敬上。


如果任何已编号的参数中含有“=”这个字符,这方法應該有用。
範例:
{{Thankyou|1=你的一切=無限大|2=张三}}

会生成:


感谢你! 感谢你的一切=無限大。 祝好,张三敬上。

  警告: 這樣做其他的参数也都需要被编號。

命名参数

与编号参数类似,第三种赋值方法只是把编号换成了名称。为了演示,需要将模板内容改为:

'''感谢你!'''
感谢{{{reason}}}。
祝好,{{{signatrue}}}敬上。

我們在模板中分辨参数是使用{{{reason}}}{{{signature}}},而不是数字。若你要按名称传递这些参数,请在传递时标明每个参数::

{{Thankyou|signature=张三|reason=你的一切}}

例中{{Thankyou}}模板接收{{{reason}}}=你的一切{{{signature}}}=张三并输出:


感谢你! 感谢你的一切。 祝好,张三敬上。


命名参数是区分大小写的,所以若是寫給李四:

{{Thankyou|signature=张三|Reason=你的一切|reason=讓我排在前面}}

会變成:


感谢你! 感谢讓我排在你的前面。 祝好,我敬上。


在你的模板中使用命名参数的优点是,除了参数顺序灵活之外,还可以在有许多参数时,使模板代码更容易理解。

默认值

当您嵌入了一个应该有参数的模板,但未提供它需要的参数的话,即:

{{Thankyou}}

在上面的编号参数的例子中,你会得到 :


感谢你! 感谢{{{1}}}。 祝好,{{{2}}}敬上。


当没有包含一个参数时,它会直接输出变量本身。此时,设置变量的默认值会方便许多。比如,如果更改模板内容为:

'''感谢你!'''
感谢{{{reason|你的一切}}}。
祝好,{{{signature|张三}}}敬上。

{{{reason|你的一切}}}表示如果{{{reason}}}变量的参数没有被赋值,则输出默认值你的一切。类似的,{{{signature|张三}}}{{{signature}}}变量默认输出张三。修改后的模板输出如下结果:


感谢你! 感谢你的一切。 祝好,张三敬上。


参数的值可以是空字符串。 例如,在{{foo|bar=}}{{foo|bar=|baz=qux}}中,foo模板认为bar的参数是""。 这与完全省略参数是不同的,后者会使参数不被定义,并触发上述的默认值机制。
If you need to treat an empty string the same way as a missing parameter, you can use a conditional operator through an extension like ParserFunctions. For instance, {{#if:{{{1|}}}|{{{1|}}}|undefined}} returns undefined if the parameter is either undefined or empty, while {{{1|undefined}}} does so only if the parameter is undefined.

常用默认值是用来指定参数的替代名称。 例如,如果你有個{{{a|{{{b|}}} }}},模板先查找名为「a」的参数。 如果这个参数不存在,则使用名为b的参数。 如果a和b都不存在,则什么都不输出。

运算过程

这是高级话题,需要时才需要阅读。

通常来说,模板参数会在标记化(tokenization)之后被代入模板之內,但依旧維持不變。 这些参数直到使用时才会被运算。

这会有一些后果。 第一个后果,如果你有個包含{{mytemplateTemplate:Start,還有個包含|foo=bar}}Template:End,然後在页面上放置{{start}}{{end}},那么mytemplate不会被嵌入包含,因为像“|”这样的保留字符不会被模板添加進去,而是在模板中維持其特殊的含义。 你依然可以使用模板控制某個参数或者模板的名称,但是你不能在多个模板之間切開某个模板调用。

第二个后果是死代码消除(dead-code elimination)。 如果你调用一個像{{foo|{{DISPLAYTITLE:Bar}} }}这样的模板,且{{{1}}}並不包含在Template:Foo裏,那么displaytitle就不会被使用到,因为運算只会在有需要时进行且这里没有任何参数被代入进去,所以它永遠不會被運算。 这通常在扩展:解析器函数时出现,尤其在和int:魔术字(会随用户语言改变)一起使用时就会注意到。

以魔术字subst:safesubst:开头的模板调用会在单独的第一次传递时(仅在保存时发生)时计算,和~~~~和链接一起,使用管道技巧。 如果在第一次传递时不能计算,那么safesubst:会被视为像普通的模板一样。

很多(但不是所有)在特殊页面嵌入的的解析器函数、解析器标签不会像模板那样被包含,而是被替换为“strip marker”。 这意味着,你不能使用像padleft:这样的解析器函数或者扩展中的类似函数处理这些结果,因为这些函数会将这些结果其视为strip marker而非解析器函数的结果。

在模板中递归

将模板包含到它本身并不会导致MediaWiki无限递归。 MediaWiki将停止递归调用,将模板名称加粗显示。 例如,如果Template:Aaaa的内容是a {{Aaaa}} z,它将显示为“a a Template loop detected: Template:Aaaa z z”。

禁止的用法

这种保障措施排除了一种可能有用的模板习性,即模板自我规范化其调用参数。 在这个被禁止的例子中,template:d可以被称为{{d|20200311}}或¥3。 如果以第一种方式调用,它会使第二个参数结构(使用字符串解析器函数得到)递归到自身中,之后遵守统一的处理路径。

{{#if:{{{1|}}}|{{d|y={{#sub:{{{1}}}|0|4}}|m={{#sub:{{{1}}}|4|2}}|d={{#sub:{{{1}}}|6|2}}}}|<!-- processing path with arguments y,m,d regardless of original call pattern -->}}

如果将template:d修改为递归为template:d/2,而template:d/2template:d相同的手动创建的副本,则此语句可以正常工作,因为自递归保护措施是动态运行而非静态的。

让MediaWiki软件放宽自递归规则的一种可行方法是要求每个递归调用具有与所有先前活动调用不同的参数计数,最多一次递归,参数计数不减少。 这将为防止无限自递归提供有力保证,同时以灵活的方式启用有用的语句,例如此处描述的语句。

如果处理路径的复杂性较低,则有一个仅使用一个模板的简单解决方案,在单独的if/else分支上处理每个调用约定,在每种情况下复制处理路径的逻辑。 如果处理路径比较复杂,则每个调用结构案例都可以委托给具有统一调用结构的实现模板,该模板提供最终的模板行为。

参数中的表格

由于管道字符(|)和等号(=)在模板调用和wikitable中有不同的含义,为了在模板参数的值中使用表格标记,通常需要“转义”这个字符(例如,保护它们以防被理解为模板标记),可以使用以及的特殊序列:

  • 内置的魔术字 {{!}}提供了自MediaWiki 1.24版以来|的“转义”版本
  • 内置的魔术字{{=}}提供了自MediaWiki 1.39版以来=的“转义”版本

在介绍这些魔术字之前,许多wiki使用模板来完成相同的事情。 在这样的wiki上,魔术字优先于同名模板。

示例

A B C
A1 B1 C1
A2 B2 C1

代码:

{| class=wikitable
!A!!B!!C
|-
|A1||B1||C1
|-
|A2||B2||C1
|}

转移表代码

{{{!}} class{{=}}wikitable
!A!!B!!C
{{!}}-
{{!}}A1{{!}}{{!}}B1{{!}}{{!}}C1
{{!}}-
{{!}}A2{{!}}{{!}}B2{{!}}{{!}}C2
{{!}}}

请注意,第一个左大括号({)被解释为字面左大括号字符,因为它紧跟{{!}}魔术字。 同样,最后一个右大括号(})被解释为字面右大括号字符,因为它前面紧跟着相同的魔术字。 但是在某些情况下,这些大括号字符确实会导致问题,因此一些wiki也提供了用于转义这些字符的模板:

  • 模板调用{{(}}可能提供{的“转义”版本
  • 模板调用{{)}}可能提供}的“转义”版本

一些wiki甚至更进一步,提供如{{(!}}, {{!)}}, {{!!}}等更多便利的模板。 在这样的wiki上,代码可以简化为以下形式:

{{(!}} class{{=}}wikitable
!A!!B!!C
{{!}}-
{{!}}A1{{!!}}B1{{!!}}C1
{{!}}-
{{!}}A2{{!!}}B2{{!!}}C2
{{!)}}

控制模板嵌入

默认状态,模板内容被显示在实例中,无论被直接查看还是包含到其他页面中。当然,你可以用‎<noinclude>‎<includeonly>‎<onlyinclude> 来控制模板的哪些部分会被嵌入。

任何在‎<noinclude>‎</noinclude>之间的标记,都只会在直接查看模板页面的时候显示出来,而不会被包含在页面中。当你不想让包括在模板中的文本或代码传播到任何包括它页面这各功能很有用,比如:

  • 为模板归类请使用分类链接
  • 跨语言链接 可连接到其他语言版本中的类似模板
  • 关于如何使用该模板的解释文字

与此相对的是‎<includeonly>。在‎<includeonly>‎</includeonly>之间的文字只会在嵌入页面的时候才会被处理或显示,直接查看时不会显示。比如:

  • 很明显的一个使用方式是将所有有某个模板的页面加入某个分类,而不将模板本身加入这个分类。  注意: 当你改变模板中的分类的时候,使用这个模板的分类可能不会立即改变;这会在工作排队 中处理。
  • 确认查看模板页面本身时模板代码没有执行。典型地,这是因为它需要参数,并且没有参数时执行会产生不想要的结果。

当模板页面被直接查看和被其他页面包含时,所有‎<noinclude>‎<includeonly>之外的代码都会被处理和显示。 关键是这两个标记之间的内容。

所有‎<onlyinclude>标记之外的代码在嵌入时被弃置不用。 即使段落被标记为 includeonly,在嵌入时一样会被弃用,除非它们也被标记为 onlyinclude。 关键在于标记之外的东西。

也可以嵌套这些标签。

这三部分嵌入标记实现了处理和表达所有可能的组合。 评论也能起效。

整理模板

为了使模板起作用,用户需要找到并且了解如何使用模板。

找模板的方法:

  1. 点击特殊页面>所有页面
  2. 命名空间:列表中,选择Template,并点击提交

要说明用法,请包含一个示例,就像下面的例子:

<noinclude>
== 用法 ==
欢迎用户:
{{Thankyou|reason=原因|signature=名字}}
</noinclude>

然后,编辑者就可以剪切粘贴来插入这个模板。

编辑页面时,编辑框的下方会有一个已使用的所有模板的列表,显示在一个可折叠的段落中,该段落标题为“本页使用的模板:”(或者叫“本预览使用的模板:”或者“该章节使用的模板:”,取决于环境)。 这个列表提供了模板页面的便捷的链接,以及有关保护状态的信息。 被重定向的模板会以斜体显示,其重定向的目标会添加为单独的列表项。

链接到模板

模板页面可以像任何其他wiki页面一样链接。例如,使用wikicode[[Template:Navbar]]生成链接Template:Navbar

在许多维基上,Template:Tl 可用于提供指向模板的链接,该模板的格式为显示转换模板所需的“双花括号”wikicode,而不实际进行转换。例如,代码 {{tl|Navbar}}可用于创建链接{{Navbar}}。

这种结构通常用于模板文档、帮助页面和讨论页面中引用模板之處。 使用 {{[[Template:Navbar|Navbar]]}}可以实现相同的效果,但是 {{tl}} 方法用字更少。 在任何给定的wiki上,Tl模板(如果存在)可能会也可能不会在“code”元素中呈现为等宽文本,如此处所示。 如果没有(就像在本wiki上),另一个类似命名的模板可能会这样做。 例如,请参阅英语维基百科的en:Template:Tl文档的“See also”部分。

从一个wiki复制到另一个wiki

模板常需要CSS或其他模板,用户常在从一个wiki到另一个wiki复制模板时遇到问题。下列步骤对大多数模板的复制有效。

MediaWiki代码

如果你有新wiki的导入权限(特别是导入上传):

  1. 到來源wiki的Special:Export,下载一个包含有所需的模板的完整历史的.xml文件,如下:
    • 在大文本输入框中输入模板名字,比如“Template:Welcome”。请特别关注大写字母和特殊字符。如果模板名字不是完全正确,导出仍可能发生,但.xml文件中将没有预期的数据。
    • 选择“包含模板”。
    • 选择“仅包含当前修订,而不是完整历史”。
    • 点击“导出”。
  2. 到新wiki的Special:导入,上传.xml文件。

如果没有新wiki的导入权限:

  1. 前往來源wiki上你想复制的模板页面,到编辑页面,然後复制全部的维基文本;
  2. 打开新wiki,到來源wiki上的模板同名的页面,点击创建/编辑,粘贴刚才拷贝的维基文本。在每個模板的编辑摘要中,链接到來源模板页面以注明出處。
  3. 回到來源wiki刚才复制代码的页面,在编辑区域下方,查看“本页使用的模板”列表。每个列出的模板都按上述步骤操作。对于这些模板所使用到的任何模板也要这样做,依此类推。

这将复制全部需要的代码,并将满足一些模板的需要。 请注意,只有在渲染页面时解析的页面元素才会被导出,因此文档子页面不会作为这个过程的一部分被导出。 如果不起效果,请检查编辑框下面“当前版本的页面引用的页面:”下方的红色链接。如果有,到源wiki重复上面的步骤并复制模块中的代码。

成功导入其他维基上的模板和它链接的模板后,可以个性化编辑以适用于新wiki。例如更改Logo、删除冗余分类和红色链接等。

扩展

在模板中通常使用的扩展是解析器函数。 访问Extension:解析器函數 页面,查看你拷贝的模板中是否包含其中列明的函数。 如果有,則你必需安装解析器函數 扩展。 你需要你的MediaWiki所在的服务器的管理员权限才能安装。

另一個模板可能會使用到的附屬程式是Lua,尤其是在维基百科网站更是如此。在模板代码中使用{{#invoke: }}是一个好主意。 以防萬一它會使用到,你需要安装 Scribunto 扩展(也需要系统管理员权限)。 您可以参看其页面来了解如何安装和使用该扩展。

CSS 和 JavaScript 代码

在MediaWiki代码之外,许多模板要用到CSS,有些模板还以来JavaScript才能完全生效。如果复制来的模板不能很好的起效果,这也是可能的原因之一。要将需要的CSS和JavaScript复制到你的wiki,一般来说你需要有管理员权限,因为你将需要编辑"MediaWiki:"名字空间中的系统消息。

  1. 查看模板用到的CSS类(与class="foobar"类似的文本)。这些类中如果出现了源wiki上的"MediaWiki:Common.css" 或 "MediaWiki:Monobook.css",请将那些类复制到新wiki"MediaWiki:Common.css"页面,再去检查模板现在是不是工作。
  2. 如果复制来的模板仍然不能很好的工作,检查是否有代码在源wiki上 "MediaWiki:Common.js" 或者 "MediaWiki:Monobook.js"中,如果有,你可以试着复制到"MediaWiki:Common.js"。一般情况下,应该复制信任的代码,首先检查代码,然后选定有关代码。你可能会发现一些注释,可以给检查各被部分功能提供一些线索。

參見

一般模板使用

模板中使用的特殊的构造

其他的有关信息

外部链接