مواد ڏانھن هلو

ماڊيول:Category handler

کليل ڄاڻ چيڪلي، وڪيپيڊيا مان


هي ماڊيول {{category handler}} سانچي کي لاڳو ڪري ٿو۔ category handler سانچو ٻين سانچن کي زمري بندي ۽ زمري بندي کي دٻائڻ پاڻمرادو ڪرڻ ۾ مدد ڏئي ٿو۔ ٻين سانچن ۾ category handler سانچي جي استعمال بابت ڄاڻ لاءِ، مهرباني ڪري سانچي جي دستاويز ڏسو۔ ٻين Lua ماڊيولن ۾ category handler ماڊيول استعمال ڪرڻ، يا هن ماڊيول کي ٻين وڪين ڏانهن منتقل ڪرڻ بابت ڄاڻ لاءِ پڙهڻ جاري رکو۔

ٻين Lua ماڊيولن مان استعمال

[سنواريو]

هي ماڊيول ڪڏهن استعمال نه ڪجي

[سنواريو]

انهن حالتن ۾ جتي ڪنهن ماڊيول کي صرف مکيه نيم اسپيس، فائيل نيم اسپيس يا زمري نيم اسپيس ۾ زمري بندي ڪرڻي هجي، اتي هي ماڊيول استعمال ڪرڻ ضرورت کان وڌيڪ آهي۔ ان جي بدران، اوهان mw.title.getCurrentTitle استعمال ڪري title object حاصل ڪري سگهو ٿا ۽ nsText field چيڪ ڪري سگهو ٿا۔ مثال طور:

local title = mw.title.getCurrentTitle()
if title.nsText == 'File' then
    -- ڪجهه ڪريو
end

بهرحال، جيڪڏهن اوهان جي ماڊيول کي ڪنهن ٻئي نيم اسپيس ۾ زمري بندي ڪرڻي هجي، ته اسان صلاح ڏيون ٿا ته هي ماڊيول استعمال ڪريو، ڇاڪاڻ⁠تہ اهو مناسب category suppression مهيا ڪري ٿو ۽ مختلف نيم اسپيسن ۾ زمري بندي چونڊڻ کي آسان بڻائي ٿو۔

نيم اسپيسون

[سنواريو]

هي ماڊيول وڪيپيڊيا تي استعمال ٿيندڙ مختلف نيم اسپيسن کي سڃاڻي ۽ ڪيترن قسمن ۾ ورهائي ٿو۔ اهي قسم هن ماڊيول ۾ parameter names طور استعمال ٿين ٿا۔

main = مکيه/مضمون واري جاءِ، جيئن عام وڪيپيڊيا مضمونن ۾۔
talk = ڪو به ڳالهه ٻولهه وارو اسپيس، جهڙوڪ اهي صفحا جن جا نالا "Talk:"، "User talk:"، "File talk:" وغيره سان شروع ٿين ٿا۔
user, wikipedia, file ... = ڳالهه ٻولهه صفحن کان سواءِ ٻيون نيم اسپيسون۔ نيم اسپيس aliases پڻ قبول ڪيا وڃن ٿا۔ مڪمل فهرست لاءِ هيٺ ڏنل ٽيبل ڏسو۔
other = اهي نيم اسپيسون جيڪي سانچي کي parameter طور مخصوص نه ڪيون ويون هجن۔ هيٺ مثال ڏسو۔
ممڪن نيم اسپيس parameters جي فهرست

(talk ۽ other کان سواءِ)

Namespace Aliases
main
واپرائيندڙ user, يوزر
وڪيپيڊيا project, wikipedia, wp
فائل file, عڪس, image
ذريعات وڪي mediawiki
سانچو template, سنچو
مدد help
زمرو category
باب
timedtext
ماڊيول module
event

بنيادي استعمال

[سنواريو]

هي ماڊيول ٻه يا وڌيڪ parameters وٺي ٿو۔ هيٺ hello world پروگرام سان هڪ مثال ڏنل آهي:

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 -- ته جيئن "nocat=true/false" ڪم ڪري
    }
    category = category or '' -- چيڪ ڪريو ته category variable لاءِ nil value نه هجي۔
    return result .. category
end

return p

مٿيون مثال category handler ماڊيول جون default settings استعمال ڪري ٿو۔ ان جو مطلب آهي ته مثال وارو ماڊيول هيٺين نيم اسپيسن ۾ صفحن کي زمري بندي ڪندو:

main، file، help، category، portal ۽ book

پر اهو ٻين نيم اسپيسن ۾ زمري بندي نه ڪندو، مثال طور:

talk، user، wikipedia، mediawiki، template ...

۽ اهو blacklisted صفحن تي به زمري بندي نه ڪندو۔ هيٺ blacklist وارو سيڪشن ڏسو۔

category handler ماڊيول ڪجهه نيم اسپيسن ۾ زمري بندي ان ڪري نٿو ڪري، ڇاڪاڻ⁠تہ انهن نيم اسپيسن ۾ گهڻا ماڊيول ۽ سانچا صرف ڏيکاريا يا فهرست ڪيا ويندا آهن، استعمال نه ٿيندا آهن۔ تنهن ڪري گهڻن ماڊيولن ۽ سانچن کي انهن نيم اسپيسن ۾ زمري بندي نه ڪرڻ گهرجي۔

ڪو به ماڊيول يا سانچو جيڪو انهن نيم اسپيسن مان هڪ يا وڌيڪ لاءِ ٺاهيو ويو هجي جتي هي ماڊيول زمري بندي ڪري ٿو، اهو مٿي ڏيکاريل بنيادي syntax استعمال ڪري سگهي ٿو۔

ترقي يافته استعمال

[سنواريو]

هي ماڊيول مٿي نيم اسپيسون واري سيڪشن ۾ ڏنل مختلف page types جي نالن وارا هڪ يا وڌيڪ parameters وٺي ٿو۔ انهن parameters کي استعمال ڪري اوهان بلڪل طئي ڪري سگهو ٿا ته اوهان جو سانچو ڪهڙين نيم اسپيسن ۾ زمري بندي ڪري۔ جيئن هيٺ:

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]]', -- مکيه/مضمون واري جاءِ ۾ زمري بندي
        talk = '[[Category:Somecat2]]', -- ڳالهه ٻولهه واري جاءِ ۾ زمري بندي
        nocat = frame.args.nocat -- ته جيئن "nocat=true/false" ڪم ڪري
    }
    category = category or '' -- چيڪ ڪريو ته category variable لاءِ nil value نه هجي۔
    return result .. category
end

return p

مٿيون ماڊيول صرف main ۽ talk space ۾ زمري بندي ڪندو۔ پر اهو /archive صفحن تي زمري بندي نه ڪندو، ڇاڪاڻ⁠تہ اهي blacklisted آهن۔ هيٺ blacklist وارو سيڪشن ڏسو۔ جيڪڏهن اوهان کي ماڊيول کي talkpage تي demonstrate ڪرڻو هجي، ته اوهان "nocat='true'" ڏئي سگهو ٿا ته جيئن اهو سانچو زمري بندي نه ڪري۔ هيٺ nocat وارو سيڪشن ڏسو۔ جيئن هيٺ:

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

ڪڏهن ڪڏهن اسان ساڳيو زمرو ڪيترين نيم اسپيسن ۾ استعمال ڪرڻ چاهيون ٿا، ته پوءِ هيئن ڪريو:

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]]', -- help ۽ user space لاءِ
        help = 1,
        user = 1,
        talk = '', -- talk pages تي ڪوبه زمرو نه
        other = '[[Category:Somecat3]]', -- باقي سڀني نيم اسپيسن لاءِ
        nocat = frame.args.nocat -- ته جيئن "nocat=true/false" ڪم ڪري
    }
    category = category or '' -- چيڪ ڪريو ته category variable لاءِ nil value نه هجي۔
    return result .. category
end

return p

مٿي مثال ۾ اسان هڪ numbered parameter استعمال ڪري هڪ زمرو ڏنو آهي، پوءِ هن ماڊيول کي ٻڌايو آهي ته اهو numbered parameter help ۽ user space ٻنهي لاءِ استعمال ڪري۔

category handler ماڊيول numbered parameters جو لامحدود تعداد سمجهي ٿو۔

other parameter اهو طئي ڪري ٿو ته باقي انهن نيم اسپيسن ۾ ڇا استعمال ڪيو وڃي، جن لاءِ واضح طور data نه ڏنو ويو آهي۔

خالي پر defined talk parameter تي ڌيان ڏيو۔ اهو talk space ۾ هن ماڊيول کي other parameter ۾ ڏنل شي ڏيکارڻ کان روڪي ٿو۔

category handler ماڊيول وٽ all نالي parameter پڻ آهي۔ اهو هيئن ڪم ڪري ٿو:

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]]', -- سڀني نيم اسپيسن ۾ زمري بندي
        nocat = frame.args.nocat -- ته جيئن "nocat=true/false" ڪم ڪري
    }
    category = category or '' -- چيڪ ڪريو ته category variable لاءِ nil value نه هجي۔
    return result .. category
end

return p

مٿيون مثال سڀني نيم اسپيسن ۾ زمري بندي ڪندو، پر blacklisted صفحن تي نه۔ جيڪڏهن اوهان انهي ماڊيول کي ڪنهن صفحي تي demonstrate ڪرڻ چاهيو ٿا، ته "nocat=true" استعمال ڪريو ته جيئن سانچو زمري بندي نه ڪري۔

اسان all parameter کان پاسو ڪرڻ جي صلاح ڏيون ٿا، ڇاڪاڻ⁠تہ ماڊيولن ۽ سانچن کي ترجيحي طور صرف انهن نيم اسپيسن ۾ زمري بندي ڪرڻ گهرجي جن جي انهن کي ضرورت هجي۔

all parameter کي باقي parameters سان گڏ به استعمال ڪري سگهجي ٿو۔ جيئن هيٺ:

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]]', -- سڀني نيم اسپيسن ۾ زمري بندي
        main = '[[Category:Somecat2]]', -- ۽ main space ۾ هي به شامل ڪريو
        other = '[[Category:Somecat3]]', -- ۽ سڀني ٻين نيم اسپيسن ۾ هي شامل ڪريو
        nocat = frame.args.nocat -- ته جيئن "nocat=true/false" ڪم ڪري
    }
    category = category or '' -- چيڪ ڪريو ته category variable لاءِ nil value نه هجي۔
    return result .. category
end

return p

جيڪڏهن مٿيون ماڊيول ڪنهن مضمون تي رکيو وڃي، ته اهو "Somecat1" ۽ "Somecat2" زمرا شامل ڪندو۔ پر ٻين سڀني قسمن جي صفحن تي اهو بدران "Somecat1" ۽ "Somecat3" شامل ڪندو۔ جيئن مثال ڏيکاري ٿو، all parameter باقي parameters کان آزاد نموني ڪم ڪري ٿو۔

ذيلي صفحا

[سنواريو]

category handler ماڊيول subpage parameter سمجهي ٿو۔ جيئن هيٺ:

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' -- ذيلي صفحن تي زمري بندي نه ڪريو
        wikipedia = '[[Category:Somecat]]',
        nocat = frame.args.nocat -- ته جيئن "nocat=true/false" ڪم ڪري
    }
    category = category or '' -- چيڪ ڪريو ته category variable لاءِ nil value نه هجي۔
    return result .. category
end

return p

جيڪڏهن "subpage='no'" هجي ته هي سانچو ذيلي صفحن تي زمري بندي نه ڪندو۔ ڪنهن ناياب حالت ۾ جيڪڏهن اوهان صرف ذيلي صفحن تي زمري بندي ڪرڻ چاهيو، ته "subpage='only'" استعمال ڪريو۔ جيڪڏهن subpage خالي يا undefined هجي، ته هي سانچو basepages ۽ subpages ٻنهي تي زمري بندي ڪندو۔

Blacklist

[سنواريو]

هن ماڊيول وٽ انهن صفحن ۽ صفحن جي قسمن جي blacklist آهي، جتي سانچن کي پاڻمرادو زمري بندي نه ڪرڻ گهرجي۔ تنهن ڪري جيڪي ماڊيول هي meta-template استعمال ڪن ٿا، اهي مثال طور /archive صفحن ۽ وڪيپيڊيا:سانچو پيغام جي ذيلي صفحن تي زمري بندي نه ڪندا۔

جيڪڏهن اوهان چاهيو ٿا ته ڪو سانچو blacklisted صفحي تي زمري بندي ڪري، ته صفحي تي رکندي ماڊيول کي "nocat = false" ڏيو، جنهن سان blacklist check کي skip ڪيو ويندو۔ ياد رهي ته هي ماڊيول صرف تڏهن زمري بندي ڪندو جڏهن ان وٽ انهي نيم اسپيس لاءِ data هجي۔ مثال طور، جيڪڏهن basic syntax استعمال ڪئي وئي هجي، ته "nocat = false" مقرر ڪرڻ باوجود سانچو talk page تي زمري بندي نه ڪندو، ڇاڪاڻ⁠تہ talk pages لاءِ ان وٽ data ناهي۔ پر help space لاءِ data آهي، تنهن ڪري blacklisted help page تي اهو زمري بندي ڪندو۔

blacklist ماڊيول code جي مٿئين حصي ۾ configuration table cfg.blacklist ۾ موجود آهي۔

"nocat" parameter

[سنواريو]

هي ماڊيول nocat parameter سمجهي ٿو:

  • جيڪڏهن "nocat = true" هجي ته هي سانچو زمري بندي نه ڪندو۔
  • جيڪڏهن nocat nil هجي ته هي سانچو عام طريقي سان زمري بندي ڪندو۔
  • جيڪڏهن "nocat = false" هجي ته هي سانچو blacklisted صفحن تي به زمري بندي ڪندو۔ مٿي blacklist وارو سيڪشن ڏسو۔
  • nocat parameter true ۽ false جا aliases پڻ قبول ڪري ٿو، جيئن ماڊيول:Yesno ۾ defined آهن، مثال طور true لاءِ "yes"، "y"، "true"، ۽ 1؛ ۽ false لاءِ "no"، "n"، "false"، ۽ 0۔

جيڪي ماڊيول ۽ سانچا {{category handler}} استعمال ڪن ٿا، انهن کي nocat اڳتي pass ڪرڻ گهرجي، ته جيئن اهي به nocat سمجهن۔ هن صفحي جي مثالن ۾ ڏيکاريل code "nocat = frame.args.nocat" اهو ئي ڪم ڪري ٿو۔

"categories" parameter

[سنواريو]

پراڻي مطابقت لاءِ هي ماڊيول categories parameter پڻ سمجهي ٿو۔ اهو nocat وانگر ئي ڪم ڪري ٿو۔ جيئن هيٺ:

  • جيڪڏهن "categories = false" هجي ته هي سانچو زمري بندي نه ڪندو۔
  • جيڪڏهن categories خالي يا undefined هجي ته هي سانچو عام طريقي سان زمري بندي ڪندو۔
  • جيڪڏهن "categories = true" هجي ته هي سانچو blacklisted صفحن تي به زمري بندي ڪندو۔
  • categories parameter true ۽ false جا aliases پڻ قبول ڪري ٿو، جيئن ماڊيول:Yesno ۾ defined آهن، مثال طور true لاءِ "yes"، "y"، "true"، ۽ 1؛ ۽ false لاءِ "no"، "n"، "false"، ۽ 0۔

"category2" parameter

[سنواريو]

پراڻي مطابقت لاءِ هي سانچو پراڻي "category =" parameter کي ڪنهن حد تائين support ڪري ٿو۔ پر parameter name "category" هن ماڊيول ۾ اڳ ۾ ئي category space لاءِ category data ڏيڻ لاءِ استعمال ٿئي ٿو۔ تنهن ڪري هي سانچو nocat جهڙي استعمال لاءِ category2 استعمال ڪري ٿو۔ جيئن هيٺ:

  • جيڪڏهن "category2 = "" يعني خالي پر defined هجي، يا "category2 = 'no'" هجي، يا جيڪڏهن category2 کي ڪو ٻيو data ڏنو وڃي، سواءِ ايندڙ ٻن نقطن ۾ بيان ڪيل حالتن جي، ته هي سانچو زمري بندي نه ڪندو۔
  • جيڪڏهن category2 undefined هجي يا "category2 = '¬'" هجي، ته هي سانچو عام طريقي سان زمري بندي ڪندو۔
  • جيڪڏهن "category2 = 'yes'" هجي ته هي سانچو blacklisted صفحن تي به زمري بندي ڪندو۔

زمرا ۽ متن

[سنواريو]

زمرن کان علاوه، اوهان هن ماڊيول کي ٻيو ڪجهه به ڏئي سگهو ٿا، مثال طور ڪجهه متن۔ جيئن هيٺ:

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 -- ته جيئن "nocat=true/false" ڪم ڪري
    }
    category = category or '' -- چيڪ ڪريو ته category variable لاءِ nil value نه هجي۔
    return result .. category
end

return p

جڏهن مٿي ڏنل module code talk page کان سواءِ ڪنهن به ٻئي صفحي تي استعمال ٿيندو، ته اهو هيئن نظر ايندو:

This is a module used on talk pages.

This module should only be used on talk pages.

اهو متن blacklisted صفحن تي ظاهر نه ٿيندو، تنهن ڪري اهم ڄاڻ ڏيکارڻ لاءِ هي طريقو استعمال نه ڪريو۔ سانچي کي "nocat = 'true'" ڏيڻ سان متن لڪي ويندو، بلڪل جيئن اهو ڪنهن به زمري کي suppress ڪري ٿو۔

"page" parameter

[سنواريو]

ٽيسٽ ۽ demonstration لاءِ هي ماڊيول page نالي parameter وٺي سگهي ٿو۔ جيئن هيٺ:

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, -- ته جيئن "nocat=true/false" ڪم ڪري
        page = 'User talk:Example'
    }
    return category
end

return p

مٿي code ۾ اسان ڄاڻي واڻي category names جي چوڌاري brackets نه ڏنا آهن ته جيئن page تي output ڏسي سگهجي۔ مٿي code ڪنهن به قسم جي صفحي تي استعمال ٿئي، اهو هي return ڪندو:

Category:Talk cat

page parameter هن ماڊيول کي بلڪل ائين behave ڪرائي ٿو ڄڻ اهو انهي صفحي تي هجي۔ blacklist به ڪم ڪري ٿي۔ pagename جو موجوده صفحو هجڻ ضروري ناهي۔

جيڪڏهن page parameter خالي يا undefined هجي، ته موجوده صفحي جو نالو result طئي ڪري ٿو۔

اوهان پنهنجو ماڊيول به اهڙو ڪري سگهو ٿا جو اهو page parameter سمجهي۔ ان جو مطلب آهي ته اوهان مختلف صفحن تي پنهنجي سانچي جي زمري بندي کي test ڪري سگهو ٿا، انهن صفحن کي اصل ۾ edit ڪرڻ کان سواءِ۔ پوءِ هيئن ڪريو:

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, -- ته جيئن "nocat=true/false" ڪم ڪري
        page = frame.args.page -- ٽيسٽ لاءِ
    }
    return category
end

return p

Parameters

[سنواريو]

سڀني parameters جي فهرست:

  • پهريون positional parameter - 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'

نوٽ ڪريو ته "main" کان "other" تائين parameters لاءِ empty values جو خاص مطلب آهي۔ مٿي مثال ڏسو۔ "all" parameter numbered parameters نٿو سمجهي، ڇاڪاڻ⁠تہ ان جي ڪڏهن به ضرورت نه هجڻ گهرجي۔

ٻين وڪين ڏانهن منتقل ڪرڻ

[سنواريو]

هي ماڊيول cfg table ۾ configuration values تبديل ڪري ٻين وڪين ڏانهن منتقل ڪري سگهجي ٿو۔ سڀ variable values configurable آهن، تنهن ڪري configuration values مقرر ٿيڻ کان پوءِ main module code تبديل ڪرڻ جي ضرورت نه هجڻ گهرجي۔ هر configuration value جا تفصيل module code comments ۾ شامل آهن۔ ان کان علاوه، هن ماڊيول لاءِ local wiki تي ماڊيول:Namespace detect موجود هجڻ ضروري آهي۔

پڻ ڏسو

[سنواريو]

--------------------------------------------------------------------------------
--                                                                            --
--                              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              --
--      [[Module:Category handler/config]], and pages can be blacklisted      --
--      from categorisation by using [[Module:Category handler/blacklist]].   --
--                                                                            --
--------------------------------------------------------------------------------

-- Load required modules
local yesno = require('Module:Yesno')

-- Lazily load things we don't always need
local mShared, mappings

local p = {}

--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------

local function trimWhitespace(s, removeBlanks)
	if type(s) ~= 'string' then
		return s
	end
	s = s:match('^%s*(.-)%s*$')
	if removeBlanks then
		if s ~= '' then
			return s
		else
			return nil
		end
	else
		return s
	end
end

--------------------------------------------------------------------------------
-- CategoryHandler class
--------------------------------------------------------------------------------

local CategoryHandler = {}
CategoryHandler.__index = CategoryHandler

function CategoryHandler.new(data, args)
	local obj = setmetatable({ _data = data, _args = args }, CategoryHandler)
	
	-- Set the title object
	do
		local pagename = obj:parameter('demopage')
		local success, titleObj
		if pagename then
			success, titleObj = pcall(mw.title.new, pagename)
		end
		if success and titleObj then
			obj.title = titleObj
			if titleObj == mw.title.getCurrentTitle() then
				obj._usesCurrentTitle = true
			end
		else
			obj.title = mw.title.getCurrentTitle()
			obj._usesCurrentTitle = true
		end
	end

	-- Set suppression parameter values
	for _, key in ipairs{'nocat', 'categories'} do
		local value = obj:parameter(key)
		value = trimWhitespace(value, true)
		obj['_' .. key] = yesno(value)
	end
	do
		local subpage = obj:parameter('subpage')
		local category2 = obj:parameter('category2')
		if type(subpage) == 'string' then
			subpage = mw.ustring.lower(subpage)
		end
		if type(category2) == 'string' then
			subpage = mw.ustring.lower(category2)
		end
		obj._subpage = trimWhitespace(subpage, true)
		obj._category2 = trimWhitespace(category2) -- don't remove blank values
	end
	return obj
end

function CategoryHandler:parameter(key)
	local parameterNames = self._data.parameters[key]
	local pntype = type(parameterNames)
	if pntype == 'string' or pntype == 'number' then
		return self._args[parameterNames]
	elseif pntype == 'table' then
		for _, name in ipairs(parameterNames) do
			local value = self._args[name]
			if value ~= nil then
				return value
			end
		end
		return nil
	else
		error(string.format(
			'invalid config key "%s"',
			tostring(key)
		), 2)
	end
end

function CategoryHandler:isSuppressedByArguments()
	return
		-- See if a category suppression argument has been set.
		self._nocat == true
		or self._categories == false
		or (
			self._category2
			and self._category2 ~= self._data.category2Yes
			and self._category2 ~= self._data.category2Negative
		)

		-- Check whether we are on a subpage, and see if categories are
		-- suppressed based on our subpage status.
		or self._subpage == self._data.subpageNo and self.title.isSubpage
		or self._subpage == self._data.subpageOnly and not self.title.isSubpage
end

function CategoryHandler:shouldSkipBlacklistCheck()
	-- Check whether the category suppression arguments indicate we
	-- should skip the blacklist check.
	return self._nocat == false
		or self._categories == true
		or self._category2 == self._data.category2Yes
end

function CategoryHandler:matchesBlacklist()
	if self._usesCurrentTitle then
		return self._data.currentTitleMatchesBlacklist
	else
		mShared = mShared or require('Module:Category handler/shared')
		return mShared.matchesBlacklist(
			self.title.prefixedText,
			mw.loadData('Module:Category handler/blacklist')
		)
	end
end

function CategoryHandler:isSuppressed()
	-- Find if categories are suppressed by either the arguments or by
	-- matching the blacklist.
	return self:isSuppressedByArguments()
		or not self:shouldSkipBlacklistCheck() and self:matchesBlacklist()
end

function CategoryHandler:getNamespaceParameters()
	if self._usesCurrentTitle then
		return self._data.currentTitleNamespaceParameters
	else
		if not mappings then
			mShared = mShared or require('Module:Category handler/shared')
			mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData
		end
		return mShared.getNamespaceParameters(
			self.title,
			mappings
		)
	end
end

function CategoryHandler:namespaceParametersExist()
	-- Find whether any namespace parameters have been specified.
	-- We use the order "all" --> namespace params --> "other" as this is what
	-- the old template did.
	if self:parameter('all') then
		return true
	end
	if not mappings then
		mShared = mShared or require('Module:Category handler/shared')
		mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData
	end
	for ns, params in pairs(mappings) do
		for i, param in ipairs(params) do
			if self._args[param] then
				return true
			end
		end
	end
	if self:parameter('other') then
		return true
	end
	return false
end

function CategoryHandler:getCategories()
	local params = self:getNamespaceParameters()
	local nsCategory
	for i, param in ipairs(params) do
		local value = self._args[param]
		if value ~= nil then
			nsCategory = value
			break
		end
	end
	if nsCategory ~= nil or self:namespaceParametersExist() then
		-- Namespace parameters exist - advanced usage.
		if nsCategory == nil then
			nsCategory = self:parameter('other')
		end
		local ret = {self:parameter('all')}
		local numParam = tonumber(nsCategory)
		if numParam and numParam >= 1 and math.floor(numParam) == numParam then
			-- nsCategory is an integer
			ret[#ret + 1] = self._args[numParam]
		else
			ret[#ret + 1] = nsCategory
		end
		if #ret < 1 then
			return nil
		else
			return table.concat(ret)
		end
	elseif self._data.defaultNamespaces[self.title.namespace] then
		-- Namespace parameters don't exist, simple usage.
		return self._args[1]
	end
	return nil
end

--------------------------------------------------------------------------------
-- Exports
--------------------------------------------------------------------------------

local p = {}

function p._exportClasses()
	-- Used for testing purposes.
	return {
		CategoryHandler = CategoryHandler
	}
end

function p._main(args, data)
	data = data or mw.loadData('Module:Category handler/data')
	local handler = CategoryHandler.new(data, args)
	if handler:isSuppressed() then
		return nil
	end
	return handler:getCategories()
end

function p.main(frame, data)
	data = data or mw.loadData('Module:Category handler/data')
	local args = require('Module:Arguments').getArgs(frame, {
		wrappers = data.wrappers,
		valueFunc = function (k, v)
			v = trimWhitespace(v)
			if type(k) == 'number' then
				if v ~= '' then
					return v
				else
					return nil
				end
			else
				return v
			end
		end
	})
	return p._main(args, data)
end

return p