Modul:Category handler

Daripada Wikipedia, ensiklopedia bebas.
Lompat ke: pandu arah, cari

Modul ini melaksanakan templat {{category handler}}. Templat kategori pengendali membantu templat lain untuk mengautomasikan kedua-dua kategori dan Kategori penyekatan. Untuk maklumat lanjut mengenai menggunakan templat kategori pengendali dalam templat lain, sila lihat template documentation. Teruskan membaca untuk maklumat mengenai menggunakan modul kategori pengendali dalam modul Lua lain, atau untuk maklumat mengenai mengeksport modul ini untuk wiki-wiki lain.

Gunakan dari modul Lua lain[sunting]

Apabila tidak menggunakan modul ini[sunting]

Bagi kes-kes di mana modul yang hanya perlu untuk mengkategorikan di salah satu ruang nama utama (artikel), fail (imej) atau kategori, maka dengan modul ini adalah pembunuhan besar-besaran. Sebaliknya, anda hanya boleh mendapatkan objek tajuk menggunakan mw.title.getCurrentTitle dan periksa lapangan nsText. Sebagai contoh:

local title = mw.title.getCurrentTitle()
if title.nsText == 'File' then
    -- do something
end

Walau bagaimanapun, jika anda memerlukan modul untuk mengkategorikan dalam mana-mana ruang nama lain, maka kami cadangkan anda menggunakan modul ini, kerana ia menyediakan penindasan kategori yang betul dan membuat ia mudah untuk memilih bagaimana untuk mengkategorikan dalam ruang nama yang berbeza.

Ruang nama[sunting]

Modul ini mengesan dan kumpulan semua berbeza Ruang nama digunakan di Wikipedia kepada beberapa jenis. Jenis ini digunakan sebagai nama parameter dalam modul ini.

main = Ruang/Rencana utama, seperti dalam artikel-artikel Wikipedia biasa.
talk = Any talk space, such as page names that start with "Talk:", "User talk:", "File talk:" and so on.
user, wikipedia, file ... = The other namespaces except the talk pages. Namespace aliases are also accepted. See the table below for the full list.
other = Any namespaces that were not specified as a parameter to the template. See examples below.
Senarai parameter ruang nama mungkin

(tidak termasuk talk dan other)

Namespace Aliases
main
pengguna user
wikipedia project
fail file, image, imej
mediawiki
templat template
bantuan help
kategori category
portal
modul module
gadget
gadget definition
topic

Penggunaan asas[sunting]

Modul ini mengambil masa dua atau lebih parameter. Ini adalah contoh menggunakan program dunia hello:

p = {}
local categoryHandler = require( 'Module:Category handler' ).main
 
function p.main( frame )
    local result = 'Hello world!'
    local category = categoryHandler{
        '[[Category:Somecat]]',
        nocat = frame.args.nocat -- So "nocat=true/false" works
    }
    category = category or '' -- Check that we don't have a nil value for the category variable.
    return result .. category
end
 
return p

Contoh di atas menggunakan tetapan lalai bagi modul kategori pengendali. Ini bermakna modul contoh yang akan mengkategorikan di muka surat dalam ruang nama berikut:

main, file, help, category, portal and book

But it will not categorize in any other namespaces, e.g.:

talk, user, wikipedia, mediawiki, template ...

Dan ia akan tidak mengkategorikan di muka surat disenaraihitamkan. (Lihat seksyen blacklist di bawah.)

Sebab modul kategori pengendali tidak mengkategorikan di beberapa ruang nama adalah bahawa orang-orang dalam ruang nama yang paling modul dan templat hanya menunjukkan atau disenaraikan, tidak digunakan. Oleh itu yang paling modul dan templat tidak mengkategorikan mereka dalam ruang nama.

Mana-mana modul atau templat yang dimaksudkan untuk satu atau lebih dari ruang nama mana modul ini mengkategorikan boleh menggunakan sintaks asas seperti di atas.

Penggunaan Lanjutan[sunting]

Modul ini mengambil masa satu atau lebih parameter dinamakan selepas jenis halaman yang berbeza seperti yang disenaraikan dalam seksyen namespaces di atas. Dengan menggunakan parameter anda boleh menentukan dengan tepat di mana ruang nama templat anda harus mengkategorikan. Seperti ini:

p = {}
local categoryHandler = require( 'Module:Category handler' ).main
 
function p.main( frame )
    local result = 'This is a module meant for articles and talk pages.'
    local category = categoryHandler{
        main = '[[Category:Somecat1]]', -- Categorize in main (article) space
        talk = '[[Category:Somecat2]]', -- Categorize in talk space
        nocat = frame.args.nocat -- So "nocat=true/false" works
    }
    category = category or '' -- Check that we don't have a nil value for the category variable.
    return result .. category
end
 
return p

Modul atas hanya akan mengkategorikan di ruang utama dan bercakap. Tetapi ia tidak akan mengkategorikan di muka surat / arkib kerana mereka disenaraihitamkan. (Lihat seksyen blacklist di bawah.) Dan jika anda perlu menunjukkan (berbincang) modul pada talkpage, maka anda boleh memberi makan "nocat='true'" untuk mengelakkan dari templat yang mengkategorikan. (Lihat seksyen nocat below.) Like this:

== My new module ==
Hey guys, have you seen my new module?
{{#invoke:mymodule|main|nocat=true}}
Nice, isn't it?
--~~~~

Kadang-kadang kita mahu menggunakan kategori yang sama dalam beberapa ruang nama, kemudian melakukan seperti ini:

p = {}
local categoryHandler = require( 'Module:Category handler' ).main
 
function p.main( frame )
    local result = 'This is a module used in several namespaces.'
    local category = categoryHandler{
        main = '[[Category:Somecat1]]',
        [ 1 ] = '[[Category:Somecat2]]', -- For help and user space
        help = 1,
        user = 1,
        talk = '', -- No categories on talk pages
        other = '[[Category:Somecat3]]', -- For all other namespaces
        nocat = frame.args.nocat -- So "nocat=true/false" works
    }
    category = category or '' -- Check that we don't have a nil value for the category variable.
    return result .. category
end
 
return p

Dalam contoh di atas kita menggunakan parameter yang bernombor untuk memberi makan salah satu kategori, dan kemudian kita memberitahu modul ini menggunakan parameter yang bernombor untuk kedua-dua bantuan dan ruang pengguna.

Modul kategori pengendali memahami nombor yang tidak terhad parameter bernombor.

lain-lain parameter mentakrifkan apa yang perlu digunakan dalam ruang nama baki yang belum jelas menjadi data diberi makan.

Nota yang kosong tetapi ditakrifkan cakap parameter. Bahawa berhenti modul ini dari menunjukkan apa yang telah diberi makan kepada lain-lain parameter, apabila di ruang cakap.

Modul kategori pengendali juga mempunyai parameter yang dipanggil semua. Ia berfungsi seperti ini:

p = {}
local categoryHandler = require( 'Module:Category handler' ).main
 
function p.main( frame )
    local result = 'This is a module used in all namespaces.'
    local category = categoryHandler{
        all = '[[Category:Somecat1]]', -- Categorize in all namespaces
        nocat = frame.args.nocat -- So "nocat=true/false" works
    }
    category = category or '' -- Check that we don't have a nil value for the category variable.
    return result .. category
end
 
return p

Contoh di atas akan mengkategorikan dalam semua ruang nama, melainkan bukan pada halaman disenaraihitamkan. Jika anda mahu untuk menunjukkan bahawa modul pada laman, kemudian gunakan "nocat=true" untuk mengelakkan templat dari mengkategorikan.

Kami mencadangkan mengelakkan semua parameter, sejak modul dan templat harus sebaik-baiknya hanya mengkategorikan dalam ruang nama mereka perlu.

Parameter semua juga boleh digabungkan dengan seluruh parameter. Seperti ini:

p = {}
local categoryHandler = require( 'Module:Category handler' ).main
 
function p.main( frame )
    local result = 'This is a module used in all namespaces.'
    local category = categoryHandler{
        all = '[[Category:Somecat1]]', -- Categorize in all namespaces
        main = '[[Category:Somecat2]]', -- And add this in main space
        other = '[[Category:Somecat3]]', -- And add this in all other namespaces
        nocat = frame.args.nocat -- So "nocat=true/false" works
    }
    category = category or '' -- Check that we don't have a nil value for the category variable.
    return result .. category
end
 
return p

Jika modul di atas diletakkan pada artikel, maka ia akan menambah kategori "Somecat1" dan "Somecat2". Tetapi pada semua jenis lain halaman ia sebaliknya akan menambah "Somecat1" dan "Somecat3". Sebagai contoh yang menunjukkan, yang semua parameter bekerja secara bebas daripada yang lain daripada parameter.

Halaman kecil[sunting]

Modul kategori pengendali memahami halaman kecil parameter. Seperti ini:

p = {}
local categoryHandler = require( 'Module:Category handler' ).main
 
function p.main( frame )
    local result = 'This is a module used in all namespaces.'
    local category = categoryHandler{
        subpage = 'no' -- Don't categorize on subpages
        wikipedia = '[[Category:Somecat]]',
        nocat = frame.args.nocat -- So "nocat=true/false" works
    }
    category = category or '' -- Check that we don't have a nil value for the category variable.
    return result .. category
end
 
return p

Jika "subpage='no'" kemudian templat ini tidak akan mengkategorikan pada halaman kecil. Untuk majlis itu jarang berlaku hanya andaingin mengkategorikan pada halaman kecil, kemudian gunakan "subpage='only'". Jika halaman kecil kosong atau undefined kemudian templat ini mengkategorikan kedua-dua pada petak halaman dan pada halaman kecil.

Senarai Hitam[sunting]

Modul ini mempunyai senarai hitam di laman-laman dan jenis halaman di mana templat tidak perlu auto-Kategorikan. Oleh itu modul yang menggunakan meta-templat ini kehendak misalnya tidak mengkategorikan di muka surat / arkib dan pada halaman kecil daripada Wikipedia:Template messages.

Jika anda mahu templat untuk mengkategorikan pada halaman yang disenarai hitam, kemudiannya menyuapkan "nocat = false" untuk modul apabila anda meletakkannya pada halaman, dengan itu melangkau semak senarai hitam. Ambil perhatian bahawa modul ini hanya mengkategorikan jika ia mempunyai data untuk ruang nama itu. Sebagai contoh, jika sintaks asas digunakan (lihat basic usage di atas), maka walaupun anda menetapkan "nocat = false" templat tidak akan mengkategorikan pada halaman perbualan, kerana ia tidak mempunyai data untuk laman perbincangan. Tetapi ia mempunyai data untuk ruang bantuan, jadi pada laman bantuan disenaraihitamkan ia akan mengkategorikan.

Senarai hitam yang terletak di kotak meja konfigurasi cfg.blacklist near the top of the module code.

The "nocat" parameter[sunting]

This module understands the nocat parameter:

  • If "nocat = true" then this template does not categorize.
  • If nocat is nil then this template categorizes as usual.
  • If "nocat = false" this template categorizes even when on blacklisted pages. (See section blacklist above.)
  • The nocat parameter also accepts aliases for true and false as defined by Module:Yesno, e.g. "yes", "y", "true", and 1 for true, and "no", "n", "false", and 0 for false.

Modul dan templat yang menggunakan {{category handler}} hendaklah mengemukakan nocat, supaya mereka juga memahami nocat. kod ini "nocat = frame.args.nocat" ditunjukkan dalam contoh-contoh di muka surat ini melakukan hal tersebut.

Kategori "parameter"[sunting]

Untuk keserasian ke belakang modul ini juga memahami kategori parameter. Ia berfungsi sama seperti nocat. Seperti ini:

  • Jika "categories = false" kemudian templat ini telah tidak mengkategorikan.
  • Jika kategori kosong atau tak ditentukan kemudian templat ini mengkategorikan seperti biasa.
  • Jika "categories = true" templat ini mengkategorikan walaupun di muka surat disenaraihitamkan.
  • Parameter kategori juga menerima alias untuk true and false sebagaimana yang ditakrifkan oleh Module:Yesno, e.g. "yes", "y", "true", dan 1 dari true, and "no", "n", "false", dan 0 dari false.

Kategori2 "parameter"[sunting]

Untuk keserasian ke belakang templat ini jenis menyokong lama "kategori =" parameter. Tetapi nama parameter "kategori" telah digunakan dalam modul ini untuk memberi makan untuk kategori data apabila di ruang kategori. Jadi, ini menggunakan templat kategori2 untuk kegunaan yang sama dengan nocat. Seperti ini:

  • Jika "category2 = " (kosong tetapi ditakrifkan), atau "category2 = 'no'", atau jika kategori2 diberi makan apa-apa data yang lain (kecuali seperti yang dinyatakan di dalam kedua-dua mata yang akan datang), maka templat ini telah tidak mengkategorikan.
  • Jika category2 adalah tak ditentukan atau jika "category2 = '¬'", kemudian templat ini mengkategorikan seperti biasa.
  • Jika "category2 = 'yes'" templat ini mengkategorikan walaupun di muka surat disenaraihitamkan.

Kategori dan teks[sunting]

Selain daripada kategori, anda boleh makan apa-apa lagi untuk modul ini, misalnya beberapa teks. Seperti ini:

p = {}
local categoryHandler = require( 'Module:Category handler' ).main

function p.main( frame )
    local result = 'This is a module used on talk pages.'
    local category = categoryHandler{
        talk = '[[Category:Somecat]]',
        other = '<p class="error">This module should only be used on talk pages.</p>',
        nocat = frame.args.nocat -- So "nocat=true/false" works
    }
    category = category or '' -- Check that we don't have a nil value for the category variable.
    return result .. category
end

return p

Apabila kod modul di atas digunakan pada apa-apa selain daripada halaman perbualan, ia akan kelihatan seperti ini:

This is a module used on talk pages.

This module should only be used on talk pages.

Teks yang tidak akan menunjukkan pada muka surat yang disenarai hitam, jadi tidak menggunakan kaedah ini untuk menunjukkan apa-apa maklumat penting. Pemakanan "nocat = 'true'" kepada templat yang menyembunyikan teks, sebagaimana ia menyembunyikan apa-apa kategori.

"halaman" parameter[sunting]

Bagi tujuan ujian dan demonstrasi modul ini boleh mengambil parameter bernama halaman. Seperti ini:

p = {}
local categoryHandler = require( 'Module:Category handler' ).main
 
function p.main( frame )
    local category = categoryHandler{
        main = 'Category:Some cat',
        talk = 'Category:Talk cat',
        nocat = frame.args.nocat, -- So "nocat=true/false" works
        page = 'User talk:Example'
    }
    return category
end
 
return p

Dalam kod di atas kita dengan sengaja meninggalkan daripada kurungan di seluruh nama-nama kategori supaya kita melihat output pada halaman. Tidak kira pada jenis halaman kod di atas digunakan ia akan kembali ini:

Category:Talk cat

halaman parameter membuat berkelakuan modul ini betul-betul seolah-olah pada laman tersebut. Walaupun senarai hitam yang bekerja. Nama halaman yang tidak perlu menjadi halaman yang telah ada.

Jika halaman parameter kosong atau tak ditentukan, nama halaman semasa menentukan hasilnya.

Anda boleh membuatnya begitu modul anda juga memahami halaman parameter. Ini bermakna anda boleh menguji bagaimana templat anda akan mengkategorikan di muka surat yang berbeza, tanpa mempunyai untuk benar-benar mengedit halaman tersebut. Kemudian lakukan seperti ini:

p = {}
local categoryHandler = require( 'Module:Category handler' ).main

function p.main( frame )
    local category = categoryHandler{
        main = 'Category:Some cat',
        talk = 'Category:Talk cat',
        nocat = frame.args.nocat, -- So "nocat=true/false" works
        page = frame.args.page -- For testing
    }
    return category
end

return p

Parameter[sunting]

Senarai semua parameter:

  • First positional parameter - for default settings
  • subpage = 'no' / 'only'
  • 1, 2, 3 ...
  • all = '[[Category:Somecat]]' / 'Text'
  • main = 1, 2, 3 ... / '[[Category:Somecat]]' / 'Text'
  • ...
  • other = 1, 2, 3 ... / '[[Category:Somecat]]' / 'Text'
  • nocat = frame.args.nocat / true / false / 'yes' / 'no' / 'y' / 'n' / 'true' / 'false' / 1 / 0
  • categories = frame.args.categories / false / true / 'no' / 'yes' / 'n' / 'y' / 'false' / 'true' / 0 / 1
  • category2 = frame.args.category or '¬' / / 'no' / not defined / '¬' / 'yes'
  • page = frame.args.page / 'User:Example'

Perhatikan bahawa nilai kosong kepada parameter "utama" ... "lain-lain" mempunyai makna khas (lihat contoh di atas). Parameter "semua" tidak memahami parameter bernombor, kerana tidak sekali keperluan untuk itu.

Mengeksport ke wiki-wiki lain[sunting]

Modul ini boleh dieksport ke wiki-wiki lain dengan menukar nilai-nilai dalam konfigurasi kotak meja cfg. Semua nilai-nilai pembolehubah adalah dikonfigurasikan, jadi selepas nilai konfigurasi telah ditetapkan tidak ada keperluan untuk mengubah kod modul utama. Butiran setiap nilai konfigurasi dimasukkan dalam komen kod modul. Di samping itu, modul ini memerlukan Module:Namespace detect boleh didapati di wiki tempatan.

Lihat juga[sunting]


----------------------------------------------------------------------------------------------------------
--                                                                                                      --
--                                          CATEGORY HANDLER                                            --
--                                                                                                      --
--      This module implements the {{category handler}} template in Lua, with a few improvements: all   --
--      namespaces and all namespace aliases are supported, and namespace names are detected            --
--      automatically for the local wiki. This module requires [[Module:Namespace detect]] and          --
--      [[Module:Yesno]] to be available on the local wiki. It can be configured for different wikis    --
--      by altering the values in the "cfg" table.                                                      --
--                                                                                                      --
----------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------
--                                          Configuration data                                          --
--                      Language-specific parameter names and values can be set here.                   --
----------------------------------------------------------------------------------------------------------

local cfg = {}

-- The following config values set the names of parameters that suppress categorisation. They are used
-- with Module:Yesno, and work as follows:
--
-- cfg.nocat:
-- Result of yesno(args[cfg.nocat])         Effect
-- true                                     Categorisation is suppressed
-- false                                    Categorisation is allowed, and the blacklist check is skipped
-- nil                                      Categorisation is allowed
--
-- cfg.categories:
-- Result of yesno(args[cfg.categories])    Effect
-- true                                     Categorisation is allowed, and the blacklist check is skipped
-- false                                    Categorisation is suppressed
-- nil                                      Categorisation is allowed
cfg.nocat = 'nocat'    
cfg.categories = 'categories'

-- The parameter name for the legacy "category2" parameter. This skips the blacklist if set to the
-- cfg.category2Yes value, and suppresses categorisation if present but equal to anything other than
-- cfg.category2Yes or cfg.category2Negative.
cfg.category2 = 'category2'
cfg.category2Yes = 'yes'
cfg.category2Negative = '¬'

-- cfg.subpage is the parameter name to specify how to behave on subpages. cfg.subpageNo is the value to
-- specify to not categorise on subpages; cfg.only is the value to specify to only categorise on subpages.
cfg.subpage = 'subpage'
cfg.subpageNo = 'no'
cfg.subpageOnly = 'only'

-- The parameter for data to return in all namespaces.
cfg.all = 'all'

-- The parameter name for data to return if no data is specified for the namespace that is detected. This
-- must be the same as the cfg.other parameter in [[Module:Namespace detect]].
cfg.other = 'other'

-- The parameter name used to specify a page other than the current page; used for testing and
-- demonstration. This must be the same as the cfg.page parameter in [[Module:Namespace detect]].
cfg.page = 'page'

-- The categorisation blacklist. Pages that match Lua patterns in this list will not be categorised.
-- (However, see the explanation of cfg.nocat, cfg.categories and cfg.category2 for some exceptions.)
-- If the namespace name has a space in, it must be written with an underscore, e.g. "Wikipedia_talk".
-- Other parts of the title can have either underscores or spaces.
cfg.blacklist = {
    '^Main Page$', -- don't categorise the main page.
    
    -- Don't categorise the following pages or their subpages.
    '^Wikipedia:Cascade%-protected items$',
    '^Wikipedia:Cascade%-protected items/.*$',
    '^User:UBX$', -- The userbox "template" space.
    '^User:UBX/.*$',
    '^User_talk:UBX$',
    '^User_talk:UBX/.*$',
    
    -- Don't categorise subpages of these pages, but allow
    -- categorisation of the base page.
    '^Wikipedia:Template messages/.+$',
    
    '/[aA]rchive' -- Don't categorise archives.
}

-- This is a table of namespaces to categorise by default. They should be in the format of parameter
-- names accepted by [[Module:Namespace detect]].
cfg.defaultNamespaces = {
    'main',
    'file',
    'help',
    'category'
}

----------------------------------------------------------------------------------------------------------
--                                          End configuration data                                      --
----------------------------------------------------------------------------------------------------------

-- Get dependent modules
local nsDetect = require('Module:Namespace detect')
local yesno = require('Module:Yesno')

----------------------------------------------------------------------------------------------------------
--                                          Local functions                                             --
--      The following are internal functions, which we do not want to be accessible from other modules. --
----------------------------------------------------------------------------------------------------------

-- Find whether we need to return a category or not.
local function needsCategory(pageObject, args)
    -- Don't categorise if the relevant options are set.
    if yesno(args[cfg.nocat])
        or yesno(args[cfg.categories]) == false
        or (
            args[cfg.category2] 
            and args[cfg.category2] ~= cfg.category2Yes 
            and args[cfg.category2] ~= cfg.category2Negative
        )
    then
        return false
    end
    -- If there is no pageObject available, then that either means that we are over
    -- the expensive function limit or that the title specified was invalid. Invalid
    -- titles will probably only be a problem during testing, so we choose the best
    -- fallback for being over the expensive function limit. The fallback behaviour
    -- of the old template was to assume the page was not a subpage, so we will do
    -- the same here.
    if args[cfg.subpage] == cfg.subpageNo and pageObject and pageObject.isSubpage then
        return false
    end
    if args[cfg.subpage] == cfg.subpageOnly 
        and (not pageObject or (pageObject and not pageObject.isSubpage))
    then
        return false
    end
    return true
end

-- Find whether we need to check the blacklist or not.
local function needsBlacklistCheck(args)
    if yesno(args[cfg.nocat]) == false
        or yesno(args[cfg.categories]) == true
        or args[cfg.category2] == cfg.category2Yes
    then
        return false
    else
        return true
    end
end

-- Find whether any namespace parameters have been specified.
-- Mappings is the table of parameter mappings taken from
-- [[Module:Namespace detect]].
local function nsParamsExist(mappings, args)
    if args[cfg.all] or args[cfg.other] then
        return true
    end
    for ns, params in pairs(mappings) do
        for i, param in ipairs(params) do
            if args[param] then
                return true
            end
        end
    end
    return false
end

----------------------------------------------------------------------------------------------------------
--                                          Global functions                                            --
--      The following functions are global, because we want them to be accessible from #invoke and      --
--      from other Lua modules.                                                                         --
----------------------------------------------------------------------------------------------------------

local p = {}

-- Find if a string matches the blacklist. Returns the match if one is found, or nil otherwise.
-- Input should be a page title with a namespace prefix, e.g. "Wikipedia talk:Articles for deletion".
function p.matchesBlacklist(page)
    if type(page) ~= 'string' then return end
    for i, pattern in ipairs(cfg.blacklist) do
        local match = mw.ustring.match(page, pattern)
        if match then
            return match
        end
    end
end

-- The main structure of the module. Checks whether we need to categorise,
-- and then passes the relevant arguments to [[Module:Namespace detect]].
function p._main(args)
    -- Get the page object and argument mappings from
    -- [[Module:Namespace detect]], to save us from having to rewrite the
    -- code.
    local pageObject = nsDetect.getPageObject(args[cfg.page])
    local mappings = nsDetect.getParamMappings()
    
    if not needsCategory(pageObject, args) then return end
    
    local ret = ''
    -- Check blacklist if necessary.
    if not needsBlacklistCheck(args) or not p.matchesBlacklist(pageObject.prefixedText) then
        if not nsParamsExist(mappings, args) then
            -- No namespace parameters exist; basic usage. Pass args[1] to
            -- [[Module:Namespace detect]] using the default namespace
            -- parameters, and return the result.
            local ndargs = {}
            for _, ndarg in ipairs(cfg.defaultNamespaces) do
                ndargs[ndarg] = args[1]
            end
            ndargs.page = args.page
            ndargs.demospace = args.demospace
            local ndresult = nsDetect._main(ndargs)
            if ndresult then
                ret = ret .. ndresult
            end
        else
            -- Namespace parameters exist; advanced usage.
            -- If the all parameter is specified, return it.
            local all = args.all
            if type(all) == 'string' then
                ret = ret .. all
            end
            
            -- Get the arguments to pass to [[Module:Namespace detect]].
            local ndargs = {}
            for ns, params in pairs(mappings) do
                for _, param in ipairs(params) do
                    ndargs[param] = args[param] or args[cfg.other] or nil
                end
            end
            ndargs.other = args.other
            ndargs.page = args.page
            ndargs.demospace = args.demospace
            
            local data = nsDetect._main(ndargs)
            
            -- Work out what to return based on the result of the namespace detect call.
            local datanum = tonumber(data)
            if type(datanum) == 'number' then
                -- "data" is a number, so return that positional parameter.
                -- Remove non-positive integer values, as only positive integers
                -- from 1-10 were used with the old template.
                if datanum > 0 and math.floor(datanum) == datanum then
                    local dataArg = args[datanum]
                    if type(dataArg) == 'string' then
                        ret = ret .. dataArg
                    end
                end
            else
                -- "data" is not a number, so return it as it is.
                if type(data) == 'string' then
                    ret = ret .. data
                end
            end
        end
    end
    return ret
end

function p.main(frame)
    -- If called via #invoke, use the args passed into the invoking
    -- template, or the args passed to #invoke if any exist. Otherwise
    -- assume args are being passed directly in.
    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 and remove blank arguments for the following args:
    -- 1, 2, 3 etc., "nocat", "categories", "subpage", and "page".
    local args = {}
    for k, v in pairs(origArgs) do
        if type(v) == 'string' then
            v = mw.text.trim(v) -- Trim whitespace.
        end
        if type(k) == 'number'
            or k == cfg.nocat
            or k == cfg.categories
            or k == cfg.subpage
            or k == cfg.page
        then
            if v ~= '' then
                args[k] = v
            end
        else
            args[k] = v
        end
    end
    
    -- Lower-case "nocat", "categories", "category2", and "subpage". These
    -- parameters are put in lower case whenever they appear in the old
    -- template, so we can just do it once here and save ourselves some work.
    local lowercase = {cfg.nocat, cfg.categories, cfg.category2, cfg.subpage}
    for _, v in ipairs(lowercase) do
        local argVal = args[v]
        if type(argVal) == 'string' then
            args[v] = mw.ustring.lower(argVal)
        end
    end
    
    return p._main(args)
end

return p