<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>https://wiki.statsape.com/index.php?action=history&amp;feed=atom&amp;title=%E6%A8%A1%E5%9D%97%3ANavplate</id>
	<title>模块:Navplate - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.statsape.com/index.php?action=history&amp;feed=atom&amp;title=%E6%A8%A1%E5%9D%97%3ANavplate"/>
	<link rel="alternate" type="text/html" href="https://wiki.statsape.com/index.php?title=%E6%A8%A1%E5%9D%97:Navplate&amp;action=history"/>
	<updated>2026-04-04T04:30:40Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.39.6</generator>
	<entry>
		<id>https://wiki.statsape.com/index.php?title=%E6%A8%A1%E5%9D%97:Navplate&amp;diff=1302&amp;oldid=prev</id>
		<title>Zeroclanzhang：​创建页面，内容为“-------------------------------------------------------------------------------- -- Module:Navplate                                                            -- -- This module implements {{Navplate}}                                        -- -- Based on Module:Infobox                                                    -- -- This is a work in progress                                                 -- ------------------------------------------------------------…”</title>
		<link rel="alternate" type="text/html" href="https://wiki.statsape.com/index.php?title=%E6%A8%A1%E5%9D%97:Navplate&amp;diff=1302&amp;oldid=prev"/>
		<updated>2023-08-04T08:58:18Z</updated>

		<summary type="html">&lt;p&gt;创建页面，内容为“-------------------------------------------------------------------------------- -- Module:Navplate                                                            -- -- This module implements {{Navplate}}                                        -- -- Based on Module:Infobox                                                    -- -- This is a work in progress                                                 -- ------------------------------------------------------------…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;--------------------------------------------------------------------------------&lt;br /&gt;
-- Module:Navplate                                                            --&lt;br /&gt;
-- This module implements {{Navplate}}                                        --&lt;br /&gt;
-- Based on Module:Infobox                                                    --&lt;br /&gt;
-- This is a work in progress                                                 --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
local args = {}&lt;br /&gt;
local origArgs = {}&lt;br /&gt;
local root&lt;br /&gt;
&lt;br /&gt;
local function union(t1, t2)&lt;br /&gt;
    -- Returns the union of the values of two tables, as a sequence.&lt;br /&gt;
    local vals = {}&lt;br /&gt;
    for k, v in pairs(t1) do&lt;br /&gt;
        vals[v] = true&lt;br /&gt;
    end&lt;br /&gt;
    for k, v in pairs(t2) do&lt;br /&gt;
        vals[v] = true&lt;br /&gt;
    end&lt;br /&gt;
    local ret = {}&lt;br /&gt;
    for k, v in pairs(vals) do&lt;br /&gt;
        table.insert(ret, k)&lt;br /&gt;
    end&lt;br /&gt;
    return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns a table containing the numbers of the arguments that exist&lt;br /&gt;
-- for the specified prefix. For example, if the prefix was &amp;#039;data&amp;#039;, and&lt;br /&gt;
-- &amp;#039;data1&amp;#039;, &amp;#039;data2&amp;#039;, and &amp;#039;data5&amp;#039; exist, it would return {1, 2, 5}.&lt;br /&gt;
local function getArgNums(prefix)&lt;br /&gt;
    local nums = {}&lt;br /&gt;
    for k, v in pairs(args) do&lt;br /&gt;
        local num = tostring(k):match(&amp;#039;^&amp;#039; .. prefix .. &amp;#039;([1-9]%d*)$&amp;#039;)&lt;br /&gt;
        if num then table.insert(nums, tonumber(num)) end&lt;br /&gt;
    end&lt;br /&gt;
    table.sort(nums)&lt;br /&gt;
    return nums&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function addRow(rowArgs, content)&lt;br /&gt;
    -- Adds a row to the navplate, with either a header&lt;br /&gt;
    -- or a label/list combination.&lt;br /&gt;
    if rowArgs.header then&lt;br /&gt;
        content&lt;br /&gt;
                :tag(&amp;#039;div&amp;#039;)&lt;br /&gt;
                :addClass(&amp;#039;template-navplate__groupheader&amp;#039;)&lt;br /&gt;
                :wikitext(rowArgs.header)&lt;br /&gt;
    elseif rowArgs.list then&lt;br /&gt;
        local row = content:tag(&amp;#039;div&amp;#039;)&lt;br /&gt;
        row:addClass(&amp;#039;template-navplate-item&amp;#039;)&lt;br /&gt;
        row&lt;br /&gt;
                :tag(&amp;#039;div&amp;#039;)&lt;br /&gt;
                :addClass(&amp;#039;template-navplate-item__label&amp;#039;)&lt;br /&gt;
                :wikitext(rowArgs.label)&lt;br /&gt;
                :done()&lt;br /&gt;
&lt;br /&gt;
        local list = row:tag(&amp;#039;div&amp;#039;)&lt;br /&gt;
        list&lt;br /&gt;
                :addClass(&amp;#039;template-navplate-item__list&amp;#039;)&lt;br /&gt;
                :wikitext(rowArgs.list)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function renderTitle(header)&lt;br /&gt;
    local headerContent = mw.html.create(&amp;#039;div&amp;#039;)&lt;br /&gt;
    headerContent:addClass(&amp;#039;template-navplate__headerContent&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
    if not args.title then return end&lt;br /&gt;
    if args.subtitle then&lt;br /&gt;
        headerContent&lt;br /&gt;
                :tag(&amp;#039;div&amp;#039;)&lt;br /&gt;
                :addClass(&amp;#039;template-navplate__subtitle&amp;#039;)&lt;br /&gt;
                :wikitext(args.subtitle)&lt;br /&gt;
                :done()&lt;br /&gt;
    end&lt;br /&gt;
    headerContent&lt;br /&gt;
            :tag(&amp;#039;div&amp;#039;)&lt;br /&gt;
            :addClass(&amp;#039;template-navplate__title&amp;#039;)&lt;br /&gt;
            :wikitext(args.title)&lt;br /&gt;
&lt;br /&gt;
    header:node(headerContent)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function renderRows(content)&lt;br /&gt;
    -- Gets the union of the header and list argument numbers,&lt;br /&gt;
    -- and renders them all in order using addRow.&lt;br /&gt;
    local rownums = union(getArgNums(&amp;#039;header&amp;#039;), getArgNums(&amp;#039;list&amp;#039;))&lt;br /&gt;
    table.sort(rownums)&lt;br /&gt;
    for k, num in ipairs(rownums) do&lt;br /&gt;
        addRow({&lt;br /&gt;
            header = args[&amp;#039;header&amp;#039; .. tostring(num)],&lt;br /&gt;
            label = args[&amp;#039;label&amp;#039; .. tostring(num)],&lt;br /&gt;
            list = args[&amp;#039;list&amp;#039; .. tostring(num)]&lt;br /&gt;
        },&lt;br /&gt;
                content)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- If the argument exists and isn&amp;#039;t blank, add it to the argument table.&lt;br /&gt;
-- Blank arguments are treated as nil to match the behaviour of ParserFunctions.&lt;br /&gt;
local function preprocessSingleArg(argName)&lt;br /&gt;
    if origArgs[argName] and origArgs[argName] ~= &amp;#039;&amp;#039; then&lt;br /&gt;
        args[argName] = origArgs[argName]&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Assign the parameters with the given prefixes to the args table, in order, in&lt;br /&gt;
-- batches of the step size specified. This is to prevent references etc. from&lt;br /&gt;
-- appearing in the wrong order. The prefixTable should be an array containing&lt;br /&gt;
-- tables, each of which has two possible fields, a &amp;quot;prefix&amp;quot; string and a&lt;br /&gt;
-- &amp;quot;depend&amp;quot; table. The function always parses parameters containing the &amp;quot;prefix&amp;quot;&lt;br /&gt;
-- string, but only parses parameters in the &amp;quot;depend&amp;quot; table if the prefix&lt;br /&gt;
-- parameter is present and non-blank.&lt;br /&gt;
local function preprocessArgs(prefixTable, step)&lt;br /&gt;
    if type(prefixTable) ~= &amp;#039;table&amp;#039; then&lt;br /&gt;
        error(&amp;quot;Non-table value detected for the prefix table&amp;quot;, 2)&lt;br /&gt;
    end&lt;br /&gt;
    if type(step) ~= &amp;#039;number&amp;#039; then&lt;br /&gt;
        error(&amp;quot;Invalid step value detected&amp;quot;, 2)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    -- Get arguments without a number suffix, and check for bad input.&lt;br /&gt;
    for i,v in ipairs(prefixTable) do&lt;br /&gt;
        if type(v) ~= &amp;#039;table&amp;#039; or type(v.prefix) ~= &amp;quot;string&amp;quot; or&lt;br /&gt;
                (v.depend and type(v.depend) ~= &amp;#039;table&amp;#039;) then&lt;br /&gt;
            error(&amp;#039;Invalid input detected to preprocessArgs prefix table&amp;#039;, 2)&lt;br /&gt;
        end&lt;br /&gt;
        preprocessSingleArg(v.prefix)&lt;br /&gt;
        -- Only parse the depend parameter if the prefix parameter is present&lt;br /&gt;
        -- and not blank.&lt;br /&gt;
        if args[v.prefix] and v.depend then&lt;br /&gt;
            for j, dependValue in ipairs(v.depend) do&lt;br /&gt;
                if type(dependValue) ~= &amp;#039;string&amp;#039; then&lt;br /&gt;
                    error(&amp;#039;Invalid &amp;quot;depend&amp;quot; parameter value detected in preprocessArgs&amp;#039;)&lt;br /&gt;
                end&lt;br /&gt;
                preprocessSingleArg(dependValue)&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    -- Get arguments with number suffixes.&lt;br /&gt;
    local a = 1 -- Counter variable.&lt;br /&gt;
    local moreArgumentsExist = true&lt;br /&gt;
    while moreArgumentsExist == true do&lt;br /&gt;
        moreArgumentsExist = false&lt;br /&gt;
        for i = a, a + step - 1 do&lt;br /&gt;
            for j,v in ipairs(prefixTable) do&lt;br /&gt;
                local prefixArgName = v.prefix .. tostring(i)&lt;br /&gt;
                if origArgs[prefixArgName] then&lt;br /&gt;
                    -- Do another loop if any arguments are found, even blank ones.&lt;br /&gt;
                    moreArgumentsExist = true&lt;br /&gt;
                    preprocessSingleArg(prefixArgName)&lt;br /&gt;
                end&lt;br /&gt;
                -- Process the depend table if the prefix argument is present&lt;br /&gt;
                -- and not blank, or we are processing &amp;quot;prefix1&amp;quot; and &amp;quot;prefix&amp;quot; is&lt;br /&gt;
                -- present and not blank, and if the depend table is present.&lt;br /&gt;
                if v.depend and (args[prefixArgName] or (i == 1 and args[v.prefix])) then&lt;br /&gt;
                    for j,dependValue in ipairs(v.depend) do&lt;br /&gt;
                        local dependArgName = dependValue .. tostring(i)&lt;br /&gt;
                        preprocessSingleArg(dependArgName)&lt;br /&gt;
                    end&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
        a = a + step&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function parseDataParameters()&lt;br /&gt;
    preprocessSingleArg(&amp;#039;id&amp;#039;)&lt;br /&gt;
    preprocessSingleArg(&amp;#039;subtitle&amp;#039;)&lt;br /&gt;
    preprocessSingleArg(&amp;#039;title&amp;#039;)&lt;br /&gt;
    preprocessArgs({&lt;br /&gt;
        {prefix = &amp;#039;header&amp;#039;},&lt;br /&gt;
        {prefix = &amp;#039;list&amp;#039;, depend = {&amp;#039;label&amp;#039;}},&lt;br /&gt;
    }, 50)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function _navplate()&lt;br /&gt;
    root = mw.html.create(&amp;#039;div&amp;#039;)&lt;br /&gt;
    header = mw.html.create(&amp;#039;div&amp;#039;)&lt;br /&gt;
    content = mw.html.create(&amp;#039;div&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
    header&lt;br /&gt;
            :addClass(&amp;#039;template-navplate__header&amp;#039;)&lt;br /&gt;
            :addClass(&amp;#039;mw-collapsible-toggle&amp;#039;)&lt;br /&gt;
            :tag(&amp;#039;div&amp;#039;)&lt;br /&gt;
            :addClass(&amp;#039;citizen-ui-icon mw-ui-icon-wikimedia-collapse&amp;#039;)&lt;br /&gt;
            :done()&lt;br /&gt;
&lt;br /&gt;
    content&lt;br /&gt;
            :addClass(&amp;#039;template-navplate__content&amp;#039;)&lt;br /&gt;
            :addClass(&amp;#039;mw-collapsible-content&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
    renderTitle(header)&lt;br /&gt;
    renderRows(content)&lt;br /&gt;
&lt;br /&gt;
    root&lt;br /&gt;
            :addClass(&amp;#039;template-navplate&amp;#039;)&lt;br /&gt;
            :addClass(&amp;#039;mw-collapsible&amp;#039;)&lt;br /&gt;
            :attr(&amp;#039;role&amp;#039;, &amp;#039;navigation&amp;#039;)&lt;br /&gt;
            :node(header)&lt;br /&gt;
            :node(content)&lt;br /&gt;
&lt;br /&gt;
    if args.id then root:attr(&amp;#039;id&amp;#039;, &amp;#039;navplate-&amp;#039; .. args.id) end&lt;br /&gt;
&lt;br /&gt;
    return mw.getCurrentFrame():extensionTag{&lt;br /&gt;
        name = &amp;#039;templatestyles&amp;#039;, args = { src = &amp;#039;Module:Navplate/styles.css&amp;#039; }&lt;br /&gt;
    } .. tostring(root)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- If called via #invoke, use the args passed into the invoking template.&lt;br /&gt;
-- Otherwise, for testing purposes, assume args are being passed directly in.&lt;br /&gt;
function p.navplate(frame)&lt;br /&gt;
    if frame == mw.getCurrentFrame() then&lt;br /&gt;
        origArgs = frame:getParent().args&lt;br /&gt;
    else&lt;br /&gt;
        origArgs = frame&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    parseDataParameters()&lt;br /&gt;
&lt;br /&gt;
    return _navplate()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- For calling via #invoke within a template&lt;br /&gt;
function p.navplateTemplate(frame)&lt;br /&gt;
    origArgs = {}&lt;br /&gt;
    for k,v in pairs(frame.args) do origArgs[k] = mw.text.trim(v) end&lt;br /&gt;
&lt;br /&gt;
    parseDataParameters()&lt;br /&gt;
&lt;br /&gt;
    return _navplate()&lt;br /&gt;
end&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Zeroclanzhang</name></author>
	</entry>
</feed>