我将有数百种人物传记,其中包括一些文本,标记和图像。
我想要一个模板,您可以在其中编写例如{{传记|Steven}},它从所有 bios 的页面中抓取该传记,其中每个 bios 都链接到一个参数。
此外,仅显示部分传记的选项,例如{{传记|史蒂文|个性}}
我知道我可以为每本传记制作一个模板,但是我会有数百个编辑必须找到的模板,我不知道这是否具有良好的性能(它有点好吗?
然后我仍然不知道如何设置模板以有条件地显示在生物的某些部分上。
我也想知道我是否应该有一些数据存储扩展,但我看不出这怎么可能比页面上的文本更快。
我是否需要使用ParserFunctions或我的首选项Lua的条件代码,并使用其许多可能版本的switch语句。
我认为这个模板是一个很好的功能,因为人们可以在一页上编辑任何生物,或者为每个字符分类编辑一页,然后任何人都可以将其排除,而不是写出相同的内容,但会犯错误、浪费时间等。
此模板将使用极高的使用率,因此它的性能良好且易于编辑使用非常重要。
我不是要别人为我写,只是建议如何去做。
为此,您需要使数据足够精细,以便能够选择单个传记字段。在MediaWiki中有几种方法可以做到这一点。
解析器函数
您可以使用 #switch 语句创建将完成这项工作的模板,而无需添加任何扩展名。例如,您可以在Template:Biography/data
处有一个数据模块:
{{#switch: {{{character|}}}
| Steven = {{#switch: {{{trait|}}}
| Personality = Outgoing
| Age = 25
}}
| Dennis = {{#switch: {{{trait|}}}
| Personality = Shy
| Age = 34
}}
}}
然后,您可以从Template:Biography
调用它,如下所示:
{{#if: {{{2|}}}
| {{Biography/data|character={{{1|}}}|trait={{{2|}}}}}
|
* Name: {{{1|}}}
* Age: {{Biography/data|character={{{1|}}}|trait=Age}}
* Personality: {{Biography/data|character={{{1|}}}|trait=Personality}}
}}
您可以通过几种不同的方式组织此 #switch 语句。例如,您可以将每个字符的数据存储在Template:Biography
的不同子模板中,如Template:Biography/data/Steven
、Template:Biography/data/Dennis
等。
模板:传记:
{{#if: {{{2|}}}
| {{Biography/data|{{{1|}}}|{{{2|}}}}}
|
* Name: {{{1|}}}
* Age: {{Biography/data|{{{1|}}}|Age}}
* Personality: {{Biography/data|{{{1|}}}|Personality}}
}}
模板:传记/数据
{{Biography/data/{{{1|}}}|trait={{{2|}}}}}
模板:传记/数据/史蒂文:
{{#switch: {{{trait|}}}
| Personality = Outgoing
| Age = 25
}}
这将比我们的第一次尝试更好,因为长switch语句在MediaWiki中是出了名的慢。但是,您仍然需要两级子模板才能使其工作,如果您不指定特征,则必须多次调用子模板。所以它仍然会很慢。
斯克里邦托
您可以通过 Scribunto 扩展在 Lua 中编写模板来加快速度。你可以编写这样的数据模块(假设它被称为Module:Biography/data
):
return {
['Steven'] = {
Personality = 'Outgoing',
Age = 25,
},
['Dennis'] = {
Personality = 'Shy',
Age = 34,
},
}
然后,您可以使用 mw.loadData 加载数据,这将每页加载一次整个表,而不是每次使用{{Biography}}
模板时加载。例如:
local data = mw.loadData('Module:Biography/data')
local p = {}
local BIO_TEMPLATE = [[
* Name: %s
* Age: %d
* Personality: %s]]
-- Trim whitespace from args, and treat blank args as nil
local function preprocessArg(s)
if not s then
return nil
end
s = s:match('^%s*(.-)%s*$') -- trim whitespace
if s == '' then
return nil
else
return s
end
end
function p.main(frame)
local args = frame.args
local character = preprocessArg(args[1])
local trait = preprocessArg(args[2])
-- Check for blank character arguments
if not character then
return ''
end
-- Get the data for the specified character
local characterData = data[character]
if not characterData then
return ''
end
if trait then
-- User specified a trait, so return it
return characterData[trait] or ''
else
-- Return the biography template with all the traits in it
return string.format(
BIO_TEMPLATE,
character,
characterData.Age,
characterData.Personality
)
end
end
return p
您还可以按字符或特征拆分数据页,其方式与 #switch 大致相同。
使用Lua的缺点是你的编辑者需要学习Lua语法以及wiki文本语法才能向数据模块添加条目。Lua语法通常比wiki文本更难掌握,所以这可能会让人们放弃贡献。
扩展
维基文本数据是非结构化的是一个长期存在的问题,因此多年来有很多尝试来解决这个问题。在确定纯解析器函数或纯 Scribunto 之前,您最好研究一些为尝试解决此问题而进行的扩展。(请记住,您可以通过模板访问这些扩展,通常也可以通过 Scribunto 访问。
例如,标记的部分转译扩展将允许您为您的角色写一本普通的传记,分隔不同的部分,然后将这些部分单独排除到其他页面上。
还有更多以数据为中心的扩展,可以帮助您制作更精细的模板,而不会陷入开关功能或数据模块的泥潭:
- 维基库 - 运行维基数据的扩展
- 语义媒体维基
- 维基数据库
- 货物
这些会将您的数据字段单独存储在数据库中(通常与您的MediaWiki安装相同),因此性能特征将取决于生成页面所需的数据库访问次数以及缓存设置方式。
如果我是你,我会先看看可用的扩展,看看是否有任何适合你情况的扩展,然后使用模板或 Scribunto 对其进行微调。