Jump to content

Module:Archive list

Wikipedia se
Badlao 13:24, 2 Julai 2013 tak imported>Mr. Stradivarius (add ability to add arbitrary page and link prefixes) se

This module can be applied to any talk page or discussion archive, and will return links to all the numbered archives of that page or its parent page. By default the module uses the naming convention specified at WP:ARCHIVE, Talk:PAGENAME/Archive 1, with a capital A, a space before the number, and no leading zeros. This module should not usually be substituted – that way, the list of links will update itself whenever a new numbered archive is added.

This module can be used with {{archive box}} to produce a box of numbered archive links without entering them all manually. To do this, use {{archive box|auto=yes}}.

The module is a replacement for the old {{archive list}} and {{archive list long}} templates.

Usage

Main

The main function. Returns a list of archive links.

{{#invoke:Archive list|main
| root            = 
| links           = 
| nobr            = 
| prefix          = 
| prefixspace     = 
| linkprefix      = 
| linkprefixspace = 
| sep             = 
| linesep         = 
| start           = 
| max             = 
| auto            =
}}
Count

The count function. Returns the number of the most recent archive.

{{#invoke:Archive list|count
| root            = 
| prefix          = 
| prefixspace     = 
}}

Parameters

Valid parameters are:

  • root = <root> - use this to specify a root other than that of the page from which the template is transcluded.
  • links = # - the number of links to display per line. The default is 10.
  • nobr = yes - set this to yes to remove all line breaks. This parameter cannot be used in conjunction with |links=.
  • prefix = <prefix> - a custom prefix for the archives, without the number. The default is "Archive ".
  • prefixspace = yes - adds a space between the prefix and the archive number for prefixes specified with |prefix=.
  • linkprefix = <linkprefix> - a custom prefix for the display links, without the number. The default is blank. If auto=long, use 'none' to have it blank.
  • prefixspace = yes - adds a space between the link prefix and the archive number for prefixes specified with |linkprefix=.
  • sep = <sep> - the separator for archive links. The default value is the comma separator for the language set in your preferences: ", ". If this is set to either dot (⧼dot-separator⧽), pipe ( | ), comma (, ), or tpt-languages (⧼tpt-languages-separator⧽), then it uses that separator as specified for your default language. If it is any other value, that value is used as it is. If this module is called from #invoke then whitespace is stripped, but if called from another module then whitespace is preserved. This allows for other modules to use this module to create wikitables, etc. If called from #invoke, the whitespace problem can be worked around by using &#32; (for spaces) and <br /> (for new lines).
  • linesep = <linesep> - the separator for lines of archive links. The possible input values are the same as for the |sep= parameter, and the default separator text is <br />. How often the value is displayed depends on the value of |links=.
  • start = # - the archive number to start listing archives from. This must be smaller than the largest archive number, or |max= if it is specified.
  • max = # - the largest archive number to list. This overrides the automatic detection of archive page numbers.
  • auto = long - outputs as a table. Changes default value of links to 3 and linkprefix to 'Archive '.

Limitations

The old {{archive list}} template was limited to detecting 200 archives. This module has no such limitation. However, at very high numbers of archives this module might reach the expensive function call limit. On a page with no other templates that call expensive functions, this module should be able to output 400,000+ archive links. On pages with other templates that make expensive function calls, the module may fail sooner.


local p = {}

-- Checks whether a page exists, going through pcall
-- in case we are over the expensive function limit.
local function checkPageExists( title )
    if not title then
        error('No title passed to checkArchiveExists', 2)
    end
    local noError, titleObject = pcall(mw.title.new, title)
    if not noError then
        -- If we are over the expensive function limit then assume
        -- that the page doesn't exist.
        return false
    else
        if titleObject then
            return titleObject.exists
        else
            return false -- Return false if given a bad title.
        end
    end
end

-- Checks every nth archive to see if it exists, and returns the
-- number of the first archive that *doesn't* exist. It is
-- necessary to do this in batches because each check is an
-- expensive function call, and we want to avoid making too many
-- of them so as not to go over the expensive function limit.
local function checkArchives( prefix, n, start )
    local i = start
    local exists = true
    while exists do
        exists = checkPageExists( prefix .. tostring( i ) )
        if exists then
            i = i + n
        end
    end
    return i
end

-- Return the biggest archive number, using checkArchives()
-- and starting in intervals of 1000. This should get us a
-- maximum of 500,000 possible archives before we hit the
-- expensive function limit.
local function getBiggestArchiveNum( prefix )
    local check1000 = checkArchives( prefix, 1000, 1 )
    if check1000 == 1 then
        return 0 -- Return 0 if no archives were found.
    end
    local check200 = checkArchives( prefix, 200, check1000 - 1000 )
    local check50 = checkArchives( prefix, 50, check200 - 200 )
    local check10 = checkArchives( prefix, 10, check50 - 50 )
    local check1 = checkArchives( prefix, 1, check10 - 10 )
    -- check1 is the first page that doesn't exist, so we want to
    -- subtract it by one to find the biggest existing archive.
    return check1 - 1
end

local function _main( args )
    -- Get the root page.
    local root = args.root or mw.title.getCurrentTitle().prefixedText
    
    -- Get the prefix.
    local prefix = root .. '/'
    if args.prefix then
        prefix = prefix .. args.prefix
        if args.prefixspace == 'yes' then
            prefix = prefix .. ' '
        end
    else
        prefix = prefix .. 'Archive '
    end
    
    -- Get the biggest archive number for the prefix.
    local archiveMax = getBiggestArchiveNum( prefix )
    
    -- Get the number of archives to put on one line. Set to
    -- math.huge if there should be no line breaks.
    local links = tonumber( args.links )
    local lineNum
    if args.nobr == 'yes' or (args.links and not links) then
        lineNum = math.huge
    -- If links is a number, process it. Negative values and expressions
    -- such as links=8/2 produced some interesting values with the old
    -- template, but we will ignore those for simplicity.
    elseif type(links) == 'number' and links >= 0 then
        -- The old template rounded down decimals to the nearest integer.
        lineNum = math.floor( links )
        if lineNum == 0 then
            -- In the old template, values of links between 0 and 0.999
            -- suppressed line breaks.
            lineNum = math.huge
        end
    else
        lineNum = 10 -- Default to 10 links.
    end
    
    -- If there are no archives yet, return a message and a
    -- link to create Archive one.
    if archiveMax == 0 then
        return 'no archives yet ([[' .. prefix .. '1|create]])'
    end
    
    -- Get the link prefix.
    local linkprefix = ''
    if args.linkprefix then
        linkprefix = args.linkprefix
        if args.linkprefixspace == 'yes' then
            linkprefix = linkprefix .. ' '
        end
    end
    
    -- Generate the archive links.
    local lineCounter = 1 -- The counter to see whether we need a line break or not.
    local ret = '' -- The string to return.
    for archiveNum = 1, archiveMax do
        ret = ret .. '[[' .. prefix .. tostring(archiveNum) .. '|' .. linkprefix .. tostring(archiveNum) .. ']]'
        -- If we don't need a new line, output a comma. We don't need
        -- a comma after the last link. 
        if lineCounter < lineNum and archiveNum < archiveMax then
            ret = ret .. ', '
            lineCounter = lineCounter + 1
        -- Output new lines if needed. We don't need a new line after
        -- the last link.
        elseif lineCounter >= lineNum and archiveNum < archiveMax then
            ret = ret .. '<br />'
            lineCounter = 1
        end
    end
    return ret
end

function p.main( frame )
    -- If we are being called from #invoke, get the args from #invoke
    -- if they exist, or else get the arguments passed to the parent
    -- frame. Otherwise, assume the arguments are being passed directly
    -- in from another module or from the debug console.
    local origArgs
    if frame == mw.getCurrentFrame() then
        origArgs = frame:getParent().args
        for k, v in pairs( frame.args ) do
            origArgs = frame.args
            break
        end
    else
        origArgs = frame
    end
    
    -- Trim whitespace from all arguments, and ignore blank values for
    -- parameters other than "links", which functions differently
    -- depending on whether it is blank or absent.
    local args = {}
    for k, v in pairs( origArgs ) do
        v = mw.text.trim(v)
        if k == 'links' or v ~= '' then
            args[k] = v
        end
    end
    
    return _main( args )
end

return p