Module:LC zh

Module documentation

DescriptionDescription

Implements {{LC zh }} for zh language conversion.

Module QualityModule Quality

Test Status
Module:LC zh success: 36, error: 0

Test casesTest cases

All tests passed.

test_main:

Text Expected Actual
Yes {{#invoke:LC zh|main}} An error Caught expected error: Lua error: Unknown content type code "nil".
Yes {{#invoke:LC zh|main|lang = {{{lang|}}}}} An error Caught expected error: Lua error: Unknown content type code "nil".
Yes {{#invoke:LC zh|main|lang = {{{lang|}}}|type = N}} An error Caught expected error: Lua error: Missing parameter "ns".
Yes {{#invoke:LC zh|main|lang = {{{lang|}}}|type = N|ns = }}
Yes {{#invoke:LC zh|main|lang = {{{lang|}}}|type = N|ns = User}} User User
Yes {{#invoke:LC zh|main|lang = {{{lang|}}}|type = N|ns = Help}} Help Help
Yes {{#invoke:LC zh|main|lang = {{{lang|}}}|type = T}} An error Caught expected error: Lua error: Require at least one of the parameter: "zh-hans", "zh-hant", "zh-hk".
Yes {{#invoke:LC zh|main|lang = {{{lang|}}}|type = T|ns = User}} An error Caught expected error: Lua error at line 521: Require at least one of the parameter: "zh-hans", "zh-hant", "zh-hk".
Yes {{#invoke:LC zh|main|lang = {{{lang|}}}|type = T|ns = User|zh-hans = Example|zh-hant = Example}} User:Example User:Example
Yes {{#invoke:LC zh|main|lang = {{{lang|}}}|type = T|ns = Help|zh-hans = 示例|zh-hant = 範例}} Help:示例 Help:示例
Yes {{#invoke:LC zh|main|lang = {{{lang|}}}|type = T|ns = Help|zh-hant = 範例}} Help:範例 Help:範例
Yes {{#invoke:LC zh|main|lang = {{{lang|}}}|type = T|hide_ns = 1|ns = Help}} An error Caught expected error: Lua error: Require at least one of the parameter: "zh-hans", "zh-hant", "zh-hk".
Yes {{#invoke:LC zh|main|lang = {{{lang|}}}|type = T|hide_ns = 1|ns = Help|zh-hans = 示例|zh-hant = 範例}} 示例 示例
Yes {{#invoke:LC zh|main|lang = {{{lang|}}}|type = H}} An error Caught expected error: Lua error at line 550: Require at least one of the parameter: "zh-hans", "zh-hant", "zh-hk".
Yes {{#invoke:LC zh|main|lang = {{{lang|}}}|type = H|zh-hans = 用户|zh-hant = 使用者|zh-hk = 用戶}} 用户 用户
Yes {{#invoke:LC zh|main|lang = {{{lang|}}}|type = C}} An error Caught expected error: Lua error: Require at least one of the parameter: "zh-hans", "zh-hant", "zh-hk".
Yes {{#invoke:LC zh|main|lang = {{{lang|}}}|type=C|zh-hans=示例|zh-hant=範例}} 示例 示例

test_template:

Text Expected Actual
Yes {{LC zh}} An error Caught expected error: Lua error: Unknown content type code "nil".
Yes {{LC zh|lang = {{{lang|}}}}} An error Caught expected error: Lua error: Unknown content type code "nil".
Yes {{LC zh|lang = {{{lang|}}}|type = N}} An error Caught expected error: Lua error: Missing parameter "ns".
Yes {{LC zh|lang = {{{lang|}}}|type = N|ns = }}
Yes {{LC zh|lang = {{{lang|}}}|type = N|ns = User}} User User
Yes {{LC zh|lang = {{{lang|}}}|type = N|ns = Help}} Help Help
Yes {{LC zh|lang = {{{lang|}}}|type = T}} An error Caught expected error: Lua error: Require at least one of the parameter: "zh-hans", "zh-hant", "zh-hk".
Yes {{LC zh|lang = {{{lang|}}}|type = T|ns = User}} An error Caught expected error: Lua error at line 521: Require at least one of the parameter: "zh-hans", "zh-hant", "zh-hk".
Yes {{LC zh|lang = {{{lang|}}}|type = T|ns = User|zh-hans = Example|zh-hant = Example}} User:Example User:Example
Yes {{LC zh|lang = {{{lang|}}}|type = T|ns = Help|zh-hans = 示例|zh-hant = 範例}} Help:示例 Help:示例
Yes {{LC zh|lang = {{{lang|}}}|type = T|ns = Help|zh-hant = 範例}} Help:範例 Help:範例
Yes {{LC zh|lang = {{{lang|}}}|type = T|hide_ns = 1|ns = Help}} An error Caught expected error: Lua error: Require at least one of the parameter: "zh-hans", "zh-hant", "zh-hk".
Yes {{LC zh|lang = {{{lang|}}}|type = T|hide_ns = 1|ns = Help|zh-hans = 示例|zh-hant = 範例}} 示例 示例
Yes {{LC zh|lang = {{{lang|}}}|type = H}} An error Caught expected error: Lua error at line 550: Require at least one of the parameter: "zh-hans", "zh-hant", "zh-hk".
Yes {{LC zh|lang = {{{lang|}}}|type = H|zh-hans = 用户|zh-hant = 使用者|zh-hk = 用戶}} 用户 用户
Yes {{LC zh|lang = {{{lang|}}}|type = C}} An error Caught expected error: Lua error: Require at least one of the parameter: "zh-hans", "zh-hant", "zh-hk".
Yes {{LC zh|lang = {{{lang|}}}|type=C|zh-hans=示例|zh-hant=範例}} 示例 示例

test_template_localized_link:

Text Expected Actual
Yes {{Localized link}} [[Special:MyLanguage/{{{1}}}|{{{1}}}]]<span style="display:none">[[:{{{1}}}| ]]</span> [[Special:MyLanguage/{{{1}}}|{{{1}}}]]<span style="display:none">[[:{{{1}}}| ]]</span>

test_template_localized_link_sandbox:

Text Expected Actual
Yes {{Localized link/sandbox}} [[Special:MyLanguage/{{{1}}}|{{{1}}}]]<span style="display:none">[[:{{{1}}}| ]]</span> [[Special:MyLanguage/{{{1}}}|{{{1}}}]]<span style="display:none">[[:{{{1}}}| ]]</span>

-- @var table
local p = {}

-- @param frame frame
-- @return args Merged argument table
function p.getMergedArgs( frame )
	local args = {}

	-- @var args Argument table
	-- {{#invoke:Module name|function name|key = value}}
	local frameArgs = frame.args

	-- @var args Argument table
	-- {{Template name|key = value}}
	local frameParentArgs = frame:getParent().args

	for k, v in pairs( frameArgs ) do
		v = mw.text.trim( tostring( v ) )
		args[k] = v
	end

	for k, v in pairs( frameParentArgs ) do
		v = mw.text.trim( v )
		args[k] = v
	end

	return args
end

-- @return table Array of language variants
--   in MediaWiki internal language codes
function p.getContentVariants()
	return {
		"zh-hans",
		"zh-hant",
		"zh-hk"
	}
end

-- @return table Array of language variants
--   in MediaWiki internal language codes
function p.getTargetVariants()
	return {
		"zh",
		"zh-hans",
		"zh-hant",
		"zh-cn",
		"zh-tw",
		"zh-hk",
		"zh-mo",
		"zh-sg",
		"zh-my",
	}
end

-- @param string langCode MediaWiki internal language code
-- @return bool Whether is one of zh target language variant
function p.hasTargetVariant( langCode )
	-- @vvar table
	local variants = p.getTargetVariants()

    for _, variant in ipairs( variants ) do
        if langCode == variant then
            return true
        end
    end

    return false
end

-- @param string convMode Conversion mode:
--   - LANGUAGE_CONVERTER: Convertable (language converter syntax)
--   - UNCONVERTIBLE: Unconvertable
-- @param string langCode MediaWiki internal language code.
-- @param string namespaceName English canonical namespace name,
--   use whitespace instead of underscore.
-- @return string Localized namespace name
function p.getNamespaceName( convMode, langCode, namespaceName )
	if namespaceName == "" then
		return ""
	end

	-- @var table
	local namespaceNames = {
		-- Prevent fallback
		-- Always use en namespace names for zh
		["en"] = {
			-- 0 (Main)
			[""] = "",
			-- 1
			["Talk"] = "Talk",
			-- 2
			["User"] = "User",
			-- 3
			["User talk"] = "User talk",
			-- 4
			["Project"] = "Project",
			-- 5
			["Project talk"] = "Project talk",
			-- 6
			["File"] = "File",
			-- 7
			["File talk"] = "File talk",
			-- 8
			["MediaWiki"] = "MediaWiki",
			-- 9
			["MediaWiki talk"] = "MediaWiki talk",
			-- 10
			["Template"] = "Template",
			-- 11
			["Template talk"] = "Template talk",
			-- 12
			["Help"] = "Help",
			-- 13
			["Help talk"] = "Help talk",
			-- 14
			["Category"] = "Category",
			-- 15
			["Category talk"] = "Category talk",
			-- 90
			["Thread"] = "Thread",
			-- 91
			["Thread talk"] = "Thread talk",
			-- 92
			["Summary"] = "Summary",
			-- 93
			["Summary talk"] = "Summary talk",
			-- 100
			["Manual"] = "Manual",
			-- 101
			["Manual talk"] = "Manual talk",
			-- 102
			["Extension"] = "Extension",
			-- 103
			["Extension talk"] = "Extension talk",
			-- 104
			["API"] = "API",
			-- 105
			["API talk"] = "API talk",
			-- 106
			["Skin"] = "Skin",
			-- 107
			["Skin talk"] = "Skin talk",
			-- 486
			["Data"] = "Data",
			-- 487
			["Data talk"] = "Data talk",
			-- 828
			["Module"] = "Module",
			-- 829
			["Module talk"] = "Module talk",
			-- 1198
			["Translations"] = "Translations",
			-- 1199
			["Translations talk"] = "Translations talk",
			-- 2300
			["Gadget"] = "Gadget",
			-- 2301
			["Gadget talk"] = "Gadget talk",
			-- 2302
			["Gadget definition"] = "Gadget definition",
			-- 2303
			["Gadget definition talk"] = "Gadget definition talk",
			-- 2600
			["Topic"] = "Topic",
			-- 5500
			["Newsletter"] = "Newsletter",
			-- 5501
			["Newsletter talk"] = "Newsletter talk",
		},
		["zh-hans"] = {
			["Talk"] = "讨论",
			["User"] = "用户",
			["User talk"] = "用户讨论",
			["Project"] = "项目",
			["Project talk"] = "项目讨论",
			["File"] = "文件",
			["File talk"] = "文件讨论",
			["MediaWiki talk"] = "MediaWiki讨论",
			["Template"] = "模板",
			["Template talk"] = "模板讨论",
			["Help"] = "帮助",
			["Help talk"] = "帮助讨论",
			["Category"] = "分类",
			["Category talk"] = "分类讨论",
			["Thread"] = "帖子",
			["Thread talk"] = "帖子讨论",
			["Summary"] = "摘要",
			["Summary talk"] = "摘要讨论",
			["Manual"] = "手册",
			["Manual talk"] = "手册讨论",
			["Extension"] = "扩展",
			["Extension talk"] = "扩展讨论",
			["API talk"] = "API讨论",
			["Skin"] = "皮肤",
			["Skin talk"] = "皮肤讨论",
			["Data"] = "数据",
			["Data talk"] = "数据讨论",
			["Module"] = "模块",
			["Module talk"] = "模块讨论",
			["Translations"] = "翻译",
			["Translations talk"] = "翻译讨论",
			["Gadget"] = "小工具",
			["Gadget talk"] = "小工具讨论",
			["Gadget definition"] = "小工具定义",
			["Gadget definition talk"] = "小工具定义讨论",
			["Topic"] = "话题",
			["Newsletter"] = "电子报",
			["Newsletter talk"] = "电子报讨论",
		},
		["zh-hant"] = {
			["Talk"] = "討論",
			["User"] = "使用者",
			["User talk"] = "使用者討論",
			["Project"] = "專案",
			["Project talk"] = "專案討論",
			["File"] = "檔案",
			["File talk"] = "檔案討論",
			["MediaWiki talk"] = "MediaWiki討論",
			["Template"] = "模板",
			["Template talk"] = "模板討論",
			["Help"] = "說明",
			["Help talk"] = "說明討論",
			["Category"] = "分類",
			["Category talk"] = "分類討論",
			["Thread"] = "討論串",
			["Thread talk"] = "討論串討論",
			["Summary"] = "摘要",
			["Summary talk"] = "摘要討論",
			["Manual"] = "手冊",
			["Manual talk"] = "手冊討論",
			["Extension"] = "擴充功能",
			["Extension talk"] = "擴充功能討論",
			["API talk"] = "API討論",
			["Skin"] = "外觀",
			["Skin talk"] = "外觀討論",
			["Data"] = "資料",
			["Data talk"] = "資料討論",
			["Module"] = "模組",
			["Module talk"] = "模組討論",
			["Translations"] = "翻譯",
			["Translations talk"] = "翻譯討論",
			["Gadget"] = "小工具",
			["Gadget talk"] = "小工具討論",
			["Gadget definition"] = "小工具定義",
			["Gadget definition talk"] = "小工具定義討論",
			["Topic"] = "話題",
			["Newsletter"] = "電子報",
			["Newsletter talk"] = "電子報討論",
		},
		["zh-hk"] = {
			["User"] = "用戶",
			["User talk"] = "用戶討論",
		},
	}

	-- Only allow known namespace names
	if
		namespaceNames["en"] == nil or
		namespaceNames["en"][namespaceName] == nil or
		namespaceNames["zh-hans"] == nil or
		namespaceNames["zh-hans"][namespaceName] == nil or
		namespaceNames["zh-hant"] == nil or
		namespaceNames["zh-hant"][namespaceName] == nil
	then
		return error( "Unknown namespace name \"" .. tostring( namespaceName ) .. "\"", 2 )
	end

	if convMode == "LANGUAGE_CONVERTER" then
		local t = {}

		t[#t + 1] = "-{zh:"
		t[#t + 1] = namespaceNames["en"][namespaceName]
		t[#t + 1] = "; zh-hans:"
		t[#t + 1] = namespaceNames["zh-hans"][namespaceName]
		t[#t + 1] = "; zh-hant:"
		t[#t + 1] = namespaceNames["zh-hant"][namespaceName]

		if
			namespaceNames["zh-hk"] and
			namespaceNames["zh-hk"][namespaceName]
		then
			t[#t + 1] = "; zh-hk:"
			t[#t + 1] = namespaceNames["zh-hk"][namespaceName]
		end

		t[#t + 1] = ";}-"

		return table.concat( t )
	end

	if convMode == "UNCONVERTIBLE" then
		if
			langCode == "zh-hans" or
			langCode == "zh-cn" or
			langCode == "zh-my" or
			langCode == "zh-sg"
		then
			return namespaceNames["zh-hans"][namespaceName]
		end

		if
			langCode == "zh-hant" or
			langCode == "zh-tw"
		then
			return namespaceNames["zh-hant"][namespaceName]
		end

		if
			langCode == "zh-hk" or
			langCode == "zh-mo"
		then
			return ( namespaceNames["zh-hk"] and namespaceNames["zh-hk"][namespaceName] ) or
				namespaceNames["zh-hans"][namespaceName]
		end

		return namespaceNames["en"][namespaceName]
	end

	return error( "Unknown language conversion mode \"" .. tostring( convMode ) .. "\"", 2 )
end

-- @param string langCode MediaWiki internal language code.
-- @param table content The table contain content in different languages.
function p.getConvertibleLangConverterContent( langCode, content )
	-- @var table
	local contentVariants = p.getContentVariants()

	-- @var table
	local t = {}

	t[#t + 1] = "-{"

	for _, variant in ipairs( contentVariants ) do
		if content[variant] ~= nil then
			t[#t + 1] = variant
			t[#t + 1] = ":"
			t[#t + 1] = content[variant]
			t[#t + 1] = ";"
			t[#t + 1] = " "
		end
	end

	if t[7] == nil then
		return t[4]
	end

	t[#t] = "}-"

	return table.concat( t )
end

-- @param string langCode MediaWiki internal language code.
-- @param table content The table contain content in different languages.
function p.getUnconvertibleContent( langCode, content )
	if
		langCode == "zh-hans" or
		langCode == "zh-cn" or
		langCode == "zh-my" or
		langCode == "zh-sg"
	then
		return content["zh-hans"] or
			content["zh-hant"] or
			content["zh-hk"]
	end

	if
		langCode == "zh-hant" or
		langCode == "zh-tw"
	then
		return content["zh-hant"] or
			content["zh-hk"] or
			content["zh-hans"]
	end

	if
		langCode == "zh-hk" or
		langCode == "zh-mo"
	then
		return content["zh-hk"] or
			content["zh-hant"] or
			content["zh-hans"]
	end

	return content["zh-hans"] or
		content["zh-hant"] or
		content["zh-hk"]
end

-- @param string convMode Conversion mode:
--   - LANGUAGE_CONVERTER: Convertable (language converter syntax)
--   - UNCONVERTIBLE: Unconvertable
-- @param string langCode MediaWiki internal language code.
-- @param table content The table contain content in different languages.
function p.getMaybeConvertibleContent( convMode, langCode, content )
	-- Require at least one of parameters: "zh-hans", "zh-hant", "zh-hk",
	-- allow empty string but not null value
	if
		content["zh-hans"] == nil and
		content["zh-hant"] == nil and
		content["zh-hk"] == nil
	then
		return error(
			"Require at least one of the parameter: \"zh-hans\", \"zh-hant\", \"zh-hk\"",
			2
		)
	end

	if convMode == "LANGUAGE_CONVERTER" then
		return p.getConvertibleLangConverterContent( langCode, content )
	elseif convMode == "UNCONVERTIBLE" then
		return p.getUnconvertibleContent( langCode, content )
	end

	return error( "Unknown language conversion mode \"" .. tostring( convMode ) .. "\"", 2 )
end

-- @param table options
-- @return string Wikitext
function p.getWikitext( options )
	-- @var string convMode Conversion mode:
	--   - LANGUAGE_CONVERTER: Convertable (language converter syntax)
	--   - UNCONVERTIBLE: Unconvertable
	local convMode = options["mode"]

	-- @var string langCode MediaWiki internal language code.
	local langCode = options["lang"]

	-- @var bool Whether to hide namespace text (not applied to ns_2)
	local hideNs = tostring( options["hide_ns"] ) ~= "0"

	-- @var string contentTypeCode Content type code:
	--   - N: Namespaces
	--   - T: Display title text
	--   - H: Headings wikitext
	--   - C: Content wikitext
	local contentTypeCode = options["type"]

	-- @var string ns English canonical namespace name
	local ns = options["ns"]

	-- @var string ns2 English secondary pseudo-namespace canonical namespace name
	local ns2 = options["ns_2"]

	-- @var table content The table contain content in different languages.
	local content = options["content"]

	if contentTypeCode == "N" then
		-- Require parameter "ns", allow empty string but not null value
		if ns == nil then
			return error( "Missing parameter \"ns\"", 2 )
		end

		-- Optional parameter "ns_2", require parameter "ns" not empty string
		if ns2 ~= nil and ns2 ~= "" then
			if ns == "" then
				return error(
					"Parameter \"ns\" need to be non-empty string when parameter \"ns_2\" is used",
					2
				)
			end

			if 
				hideNs or
				p.getNamespaceName( convMode, langCode, ns ) == ""
			then
				return p.getNamespaceName( convMode, langCode, ns2 )
			end

			return p.getNamespaceName( convMode, langCode, ns ) ..
				":" ..
				p.getNamespaceName( convMode, langCode, ns2 )
		end

		if hideNs then
			return ""
		end

		return p.getNamespaceName( convMode, langCode, ns )
	end

	if contentTypeCode == "T" then
		if ns == nil then
			ns = ""
		end

		-- Optional parameter "ns_2", require parameter "ns" not empty string
		if ns2 ~= nil and ns2 ~= "" then
			if ns == "" then
				return error(
					"Parameter \"ns\" need to be non-empty string when parameter \"ns_2\" is used",
					2
				)
			end

			if
				hideNs or
				p.getNamespaceName( convMode, langCode, ns ) == ""
			then
				return p.getNamespaceName( convMode, langCode, ns2 ) ..
					":" ..
					p.getMaybeConvertibleContent( convMode, langCode, content )
			end

			return p.getNamespaceName( convMode, langCode, ns ) ..
				":" ..
				p.getNamespaceName( convMode, langCode, ns2 ) ..
				":" ..
				p.getMaybeConvertibleContent( convMode, langCode, content )
		end

		if
			hideNs or
			p.getNamespaceName( convMode, langCode, ns ) == ""
		then
			return p.getMaybeConvertibleContent( convMode, langCode, content )
		end

		return p.getNamespaceName( convMode, langCode, ns ) ..
			":" ..
			p.getMaybeConvertibleContent( convMode, langCode, content )
	end

	if contentTypeCode == "H" then
		-- @var table
		local contentVariants = p.getContentVariants()

		-- @var table
		local a = {}

		-- @var table For deduplication
		local aIdx = {}

		-- @var string|nil
		local anc

		-- URL anchors
		for _, variant in ipairs( contentVariants ) do
			if content[variant] ~= nil and aIdx[content[variant]] == nil then
				aIdx[content[variant]] = true

				a[#a + 1] = "<span id=\""
				a[#a + 1] = string.gsub( content[variant], " ", "_" )
				a[#a + 1] = "\"></span>"
			end
		end

		anc = table.concat( a )

		return anc .. p.getMaybeConvertibleContent( convMode, langCode, content )
	end

	if contentTypeCode == "C" then
		return p.getMaybeConvertibleContent( convMode, langCode, content )
	end

	return error( "Unknown content type code \"" .. tostring( contentTypeCode ) .. "\"", 2 )
end

-- @param frame frame
-- @param table args
--   - lang: Output language/language variant.
--   - hide_ns: Whether to hide the namespace prefixes.
--       (only apply to parameter "ns", does not affect parameter "ns_2")
--   - type: Content type code.
--   - ns: English canonical namespace name.
--   - ns_2: English secondary pseudo-namespace canonical namespace name.
--   - zh-hans: Mandarin - Simplified Han script content.
--   - zh-hant: Mandarin - Traditional Han script content.
--   - zh-hk: Mandarin - Traditional Han script, Hong Kong content.
-- @return string
function p._main( frame, args )
	-- @var title
	local pageTitle = mw.title.getCurrentTitle()

	-- @var string Title.pageLang.code is an expensive function in Scribunto,
	--   thus not using pageLang.code here
	local pageLangCode = frame:preprocess( "{{PAGELANGUAGE}}" )

	-- @var string Used for /variant-code subpage text detection
	local pageTitleSubpageText = pageTitle.subpageText

	-- @var string
	local uiLangCode = frame:callParserFunction{
		name = "int",
		args = { "lang" }
	}

	-- @var string convMode Conversion mode:
	--   - LANGUAGE_CONVERTER: Convertable (language converter syntax)
	--   - UNCONVERTIBLE: Unconvertable
	local convMode = "LANGUAGE_CONVERTER"

	-- @var string? langCode MediaWiki internal language code.
	local langCode = args["lang"]

	if pageLangCode ~= "zh" then
		convMode = "UNCONVERTIBLE"

		if langCode == nil or langCode == "" then
			if p.hasTargetVariant( pageTitleSubpageText ) then
				langCode = pageTitleSubpageText
			end
		end
	end

	if langCode == nil or langCode == "" then
		langCode = uiLangCode
	end

	-- @var string
	local hideNs = "0"
	
	if
		args["hide_ns"] ~= nil and
		args["hide_ns"] ~= "" and
		tostring( args["hide_ns"] ) ~= "0"
	then
		hideNs = "1"
	elseif
		args["nsp"] ~= nil and
		args["nsp"] ~= "" and
		tostring( args["nsp"] ) ~= "0"
	then
		hideNs = "1"
	elseif
		args[2] ~= nil and
		args[2] ~= "" and
		tostring( args[2] ) ~= "0"
	then
		hideNs = "1"
	end

	-- @var table options
	local options = {
		["mode"] = convMode,
		["lang"] = langCode,
		["hide_ns"] = hideNs,
		["type"] = args["type"] or args["mode"] or args[1],
		["ns"] = args["ns"] or args["namespace"] or args[3],
		["ns_2"] = args["ns_2"],
		["content"] = {
			["zh-hans"] = args["zh-hans"],
			["zh-hant"] = args["zh-hant"],
			["zh-hk"] = args["zh-hk"],
		},
	}

	return p.getWikitext( options )
end

-- @param frame frame
-- @return string
function p.main( frame )
	local args = p.getMergedArgs( frame )

	return p._main( frame, args )
end

return p
Category:Modules Category:Modules subject to page protection Category:Pages using the JsonConfig extension Category:Pages with script errors