Lua 制作Mediawiki模板的最佳方法是根据参数显示不同的内容?

Lua 制作Mediawiki模板的最佳方法是根据参数显示不同的内容?,lua,mediawiki,mediawiki-templates,Lua,Mediawiki,Mediawiki Templates,我将有数百个人物传记,其中包括一些文本、标记和图像 我想有一个模板,你可以写,例如{{传记|史蒂文}},它从所有bios的页面中获取传记,每个bios都链接到一个参数 此外,只显示部分个人简历的选项,例如{{传记|史蒂文|个性}} 我知道我可以为每一本传记制作一个模板,但我会有数百个模板,编辑们必须找到,我不知道这是否是一个好的性能方面的明智的做法,这样可以吗 然后我仍然不知道如何设置模板以有条件地显示在bio的某些部分上 我还想知道我是否应该有一些数据存储扩展,但我不认为这可能比转置页面上的文

我将有数百个人物传记,其中包括一些文本、标记和图像

我想有一个模板,你可以写,例如{{传记|史蒂文}},它从所有bios的页面中获取传记,每个bios都链接到一个参数

此外,只显示部分个人简历的选项,例如{{传记|史蒂文|个性}}

我知道我可以为每一本传记制作一个模板,但我会有数百个模板,编辑们必须找到,我不知道这是否是一个好的性能方面的明智的做法,这样可以吗

然后我仍然不知道如何设置模板以有条件地显示在bio的某些部分上

我还想知道我是否应该有一些数据存储扩展,但我不认为这可能比转置页面上的文本更快

我是否需要使用ParserFunctions或我的首选项Lua和use的条件代码

我认为这个模板是一个很好的特性,因为人们可以在一个页面上编辑任何个人简历,或者每个角色分类编辑一个页面,然后任何人都可以将其删除,而不是写出相同的内容,但会出错、浪费时间等等

此模板将使用非常高的使用率,因此它的重要之处在于它的性能良好且易于编辑器使用


我并不是要求有人为我写这篇文章,只是建议如何去做

要做到这一点,您需要提供足够的数据,以便能够选择各个传记字段。在MediaWiki中有几种方法可以做到这一点

解析器函数 您可以使用语句创建一个模板来完成此工作,而无需添加任何扩展。例如,您可以在Template:传记/data:

然后,您可以从Template:传记中调用它,如下所示:

{{#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:传记的不同子模板中,例如Template:传记/data/Steven、Template:传记/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
}}
这比我们的第一次尝试要好,因为长开关语句在MediaWiki中的速度是出了名的慢。但是,您仍然需要两个级别的子模板才能使其工作,如果您没有指定特征,则必须多次调用子模板。所以它仍然会很慢

斯克里布托 您可以通过扩展在Lua中编写模板来加快速度。您可以这样编写一个数据模块,我们称之为模块:传记/数据:

然后可以使用加载数据,这将在每页加载整个表一次,而不是每次使用{{liography}模板。例如:

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语法以及wikitext语法,才能将条目添加到数据模块中。Lua语法通常比wikitext更难掌握,因此这可能会让人们不愿意贡献

扩展 维基文本数据非结构化的问题由来已久,因此多年来人们一直在尝试解决这个问题。在决定使用纯解析器函数或纯Scribunto之前,最好先研究一下为解决此问题而进行的一些扩展。请记住,您可以通过模板访问这些扩展,通常也可以通过Scribunto访问这些扩展

例如,扩展将允许您为您的角色编写普通传记,划分不同的部分,然后将这些部分单独转移到其他页面

还有更多以数据为中心的扩展,可以帮助您制作更精细的模板,而不会陷入切换功能或数据模块的泥潭:

-运行的扩展 这些字段将分别存储在数据库中,通常与MediaWiki安装相同,因此性能特征将取决于生成页面所需的数据库访问次数以及缓存设置方式


如果我是你,我会先看看可用的扩展,看看是否有适合你情况的扩展,然后使用模板或Scribunto对其进行微调。

传记模板通常会在同一页面上使用多次吗?或者它通常每页只使用一次?可能一次,但可能更多哇谢谢你这么详细的回答。我在慢慢地咀嚼,我想我明白了。在我赶上公共汽车后,我将进行更多的测试并尝试这些扩展。我比你高得多,只是因为我的名声还不到+15。非常感谢,我真的很喜欢你的想法和代码。
return {
    ['Steven'] = {
        Personality = 'Outgoing',
        Age = 25,
    },
    ['Dennis'] = {
        Personality = 'Shy',
        Age = 34,
    },
}
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