Mo đun : Category handler

Trang mô đun bị khóa vô hạn
Bach khoa toan th? m? Wikipedia
Tai li?u mo đun [ t?o ]
--------------------------------------------------------------------------------

--                                                                            --

--                              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 [[Mo đun:Namespace detect]]      --

--      and [[Mo đun:Yesno]] to be available on the local wiki. It can be     --

--      configured for different wikis by altering the values in              --

--      [[Mo đun:Category handler/config]], and pages can be blacklisted      --

--      from categorisation by using [[Mo đun:Category handler/blacklist]].   --

--                                                                            --

--------------------------------------------------------------------------------


-- Load required modules

local
 yesno
 =
 require
(
'Mo đun: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
(
'Mo đun:Category handler/shared'
)

		return
 mShared
.
matchesBlacklist
(

			self
.
title
.
prefixedText
,

			mw
.
loadData
(
'Mo đun: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
(
'Mo đun: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
(
'Mo đun: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
(
'Mo đun: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
(
'Mo đun:Category handler/data'
)

	local
 args
 =
 require
(
'Mo đun: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