<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh">
	<id>http://wiki.kyoshihira.uk/index.php?action=history&amp;feed=atom&amp;title=Module%3ANamespace_pagename</id>
	<title>Module:Namespace pagename - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.kyoshihira.uk/index.php?action=history&amp;feed=atom&amp;title=Module%3ANamespace_pagename"/>
	<link rel="alternate" type="text/html" href="http://wiki.kyoshihira.uk/index.php?title=Module:Namespace_pagename&amp;action=history"/>
	<updated>2026-10-25T17:22:36Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.43.1</generator>
	<entry>
		<id>http://wiki.kyoshihira.uk/index.php?title=Module:Namespace_pagename&amp;diff=2751&amp;oldid=prev</id>
		<title>Lhscogs：​导入1个版本</title>
		<link rel="alternate" type="text/html" href="http://wiki.kyoshihira.uk/index.php?title=Module:Namespace_pagename&amp;diff=2751&amp;oldid=prev"/>
		<updated>2026-10-20T01:25:53Z</updated>

		<summary type="html">&lt;p&gt;导入1个版本&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;zh&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;←上一版本&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;2026年10月20日 (二) 01:25的版本&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;zh&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;（没有差异）&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Lhscogs</name></author>
	</entry>
	<entry>
		<id>http://wiki.kyoshihira.uk/index.php?title=Module:Namespace_pagename&amp;diff=2750&amp;oldid=prev</id>
		<title>wikipedia&gt;Hamish：​已更改“Module:Namespace pagename”的保护设置：高風險模板​（[编辑=仅允许模板编辑员]（无限期）​[移动=仅允许模板编辑员]（无限期））</title>
		<link rel="alternate" type="text/html" href="http://wiki.kyoshihira.uk/index.php?title=Module:Namespace_pagename&amp;diff=2750&amp;oldid=prev"/>
		<updated>2026-10-18T06:15:13Z</updated>

		<summary type="html">&lt;p&gt;已更改“&lt;a href=&quot;/index.php/Module:Namespace_pagename&quot; title=&quot;Module:Namespace pagename&quot;&gt;Module:Namespace pagename&lt;/a&gt;”的保护设置：&lt;a href=&quot;/index.php?title=WP:HRT&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;WP:HRT（页面不存在）&quot;&gt;高風險模板&lt;/a&gt;​（[编辑=仅允许模板编辑员]（无限期）​[移动=仅允许模板编辑员]（无限期））&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;-- =====================================================================&lt;br /&gt;
-- 根据页面命名空间和实际内容综合判断该页面类型&lt;br /&gt;
--&lt;br /&gt;
-- 原作者：SunAfterRain&lt;br /&gt;
--&lt;br /&gt;
-- 维护说明：&lt;br /&gt;
--&lt;br /&gt;
-- 测试用例见 [[Template:Namespace pagename/testcases]]&lt;br /&gt;
--&lt;br /&gt;
-- 1. 命名空间（含伪空间）ID、英文名与简繁中文名在[[Module:Namespace/data]]维护。如增加新命名空间注意同时修改[[Template:NS1]]&lt;br /&gt;
-- 2. 页面具体内容（例如重定向、沙盒等）名称、判定规则在[[Module:Namespace pagename/data]]维护。&lt;br /&gt;
-- 3. 判断逻辑在本页维护。&lt;br /&gt;
-- =====================================================================&lt;br /&gt;
&lt;br /&gt;
require(&amp;#039;strict&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
local yesno = require(&amp;#039;Module:Yesno&amp;#039;)&lt;br /&gt;
local mNS = require(&amp;#039;Module:Namespace&amp;#039;)&lt;br /&gt;
local mError = require(&amp;#039;Module:Error&amp;#039;)&lt;br /&gt;
local data = mw.loadData(&amp;#039;Module:Namespace pagename/data&amp;#039;)&lt;br /&gt;
local lan = mNS._lan&lt;br /&gt;
local NS = data.NS&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
-- ---------------------------------------------------------------------&lt;br /&gt;
-- 辅助函数&lt;br /&gt;
-- ---------------------------------------------------------------------&lt;br /&gt;
local function msg(group, key, lang)&lt;br /&gt;
	-- 包裹 lan(data[group][key], lang)&lt;br /&gt;
	return lan(data[tostring(group)][tostring(key)] or {}, lang)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function inArray(item, arr)&lt;br /&gt;
	for i, v in ipairs(arr) do&lt;br /&gt;
		if item == v then&lt;br /&gt;
			return v&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function getDefaultSuffix(nsid, lang)&lt;br /&gt;
	local pageConv = data.NamespaceSuffixConfig.DefaultSuffixList[nsid]&lt;br /&gt;
	if pageConv == false then&lt;br /&gt;
		return &amp;#039;&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	return lan(pageConv, lang)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function lowerFirst(value)&lt;br /&gt;
	-- 將字串第一個文字換成小寫&lt;br /&gt;
	return mw.ustring.lower(mw.ustring.sub(value, 1, 1)) .. mw.ustring.sub(value, 2)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function makeError(errorMessage)&lt;br /&gt;
	return mError.error{&amp;#039;[[Module:Namespace pagename]]錯誤：&amp;#039; .. errorMessage}&lt;br /&gt;
end&lt;br /&gt;
-- ---------------------------------------------------------------------&lt;br /&gt;
-- 页面类型匹配规则&lt;br /&gt;
-- ---------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
-- 是否为沙盒&lt;br /&gt;
local function isSandbox(title, nsid)&lt;br /&gt;
	local nsSandbox = data.SandboxPageNames[nsid]&lt;br /&gt;
	if nsSandbox and nsSandbox[title.text] then&lt;br /&gt;
		return true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- 用户页沙盒&lt;br /&gt;
	if nsid == NS.USER and mw.ustring.match(title.text, &amp;#039;^[^/]+/沙盒$&amp;#039;) then&lt;br /&gt;
		return true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- 根据data中配置的子页面名称（SubpageRules）匹配页面类型&lt;br /&gt;
local function matchSubpageType(title, nsid)&lt;br /&gt;
	local subpageName = lowerFirst(title.subpageText)&lt;br /&gt;
	local isSubpage = title.text ~= title.rootText&lt;br /&gt;
&lt;br /&gt;
	for pageType, rule in pairs(data.SubpageRules) do&lt;br /&gt;
		-- 先判斷這條規則在本命名空間、本頁面是否適用&lt;br /&gt;
		local ok&lt;br /&gt;
		if rule.matcher then&lt;br /&gt;
			-- 自定义 matcher 取代默认的命名空间白名单与子页面判断&lt;br /&gt;
			ok = true&lt;br /&gt;
			if rule.matcher.allowNs then&lt;br /&gt;
				ok = inArray(nsid, rule.matcher.allowNs) ~= nil&lt;br /&gt;
			end&lt;br /&gt;
			if rule.matcher.subpageOnly then&lt;br /&gt;
				ok = ok and isSubpage&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			-- 默认子页面匹配：必须是子页面，且符合命名空间白名单&lt;br /&gt;
			local allowList = (pageType == &amp;#039;temp&amp;#039;)&lt;br /&gt;
				and data.NamespaceSuffixConfig.AllowTempType&lt;br /&gt;
				or data.NamespaceSuffixConfig.AllowTemplateType&lt;br /&gt;
			ok = isSubpage and inArray(nsid, allowList) ~= nil&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- 不論有沒有 matcher，rule.names 存在時都必須命中，&lt;br /&gt;
		-- 否則設了 matcher 的規則會變成該命名空間下所有子頁面的萬用規則&lt;br /&gt;
		if ok and (not rule.names or inArray(subpageName, rule.names)) then&lt;br /&gt;
			return pageType&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- 根据data中配置的页面内容特征（ContentRules）匹配类型&lt;br /&gt;
local function matchContentType(content, nsid)&lt;br /&gt;
	local isAllowTemplateType = inArray(nsid, data.NamespaceSuffixConfig.AllowTemplateType)&lt;br /&gt;
&lt;br /&gt;
	for pageType, patterns in pairs(data.ContentRules) do&lt;br /&gt;
		-- doc 与 testcases 仅在 AllowTemplateType 指定的命名空间下检测&lt;br /&gt;
		local allowed = (pageType == &amp;#039;sandbox&amp;#039;) or isAllowTemplateType&lt;br /&gt;
		if allowed then&lt;br /&gt;
			for _, pat in ipairs(patterns) do&lt;br /&gt;
				if type(pat) == &amp;#039;function&amp;#039; then&lt;br /&gt;
					if pat(nsid, content) then return pageType end&lt;br /&gt;
				elseif type(pat) == &amp;#039;string&amp;#039; then&lt;br /&gt;
					if mw.ustring.match(content, pat) then return pageType end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- 检查提示类特殊页面（Editnotice / Emailnotice 等）&lt;br /&gt;
local function matchNotice(title, nsid)&lt;br /&gt;
	for pageType, rule in pairs(data.NoticeRules) do&lt;br /&gt;
		if rule.matcher then&lt;br /&gt;
			local nsRule = rule.matcher[nsid]&lt;br /&gt;
			if nsRule then&lt;br /&gt;
				local ok = true&lt;br /&gt;
				if nsRule.rootText then&lt;br /&gt;
					ok = ok and title.rootText == nsRule.rootText&lt;br /&gt;
				end&lt;br /&gt;
				if nsRule.subpageText then&lt;br /&gt;
					ok = ok and title.subpageText == nsRule.subpageText&lt;br /&gt;
				end&lt;br /&gt;
				if nsRule.onlyFirstLevel then&lt;br /&gt;
					ok = ok and title.rootText == title.baseText&lt;br /&gt;
				end&lt;br /&gt;
				if ok then&lt;br /&gt;
					return pageType&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- ---------------------------------------------------------------------&lt;br /&gt;
-- 核心解析逻辑&lt;br /&gt;
-- ---------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
-- @param {string} [lang]&lt;br /&gt;
-- @param {string | number} [pageOrNs]&lt;br /&gt;
-- - string: 頁面（註：此函數不檢查是否有效） or （偽）命名空間的名字&lt;br /&gt;
-- - number: 命名空間數字&lt;br /&gt;
-- @param {boolean} [cfg.forcePage] 讓模組強行把輸入解釋成頁面&lt;br /&gt;
-- @param {boolean} [cfg.skipCheckPageType] 抑制檢測頁面類型，效果形同 pageOrNs 不是傳頁面&lt;br /&gt;
-- @param {boolean} [cfg.skipCheckContent] 抑制使用頁面內容檢測頁面類型&lt;br /&gt;
function p._namespace_pagename(lang, pageOrNs, cfg)&lt;br /&gt;
	cfg = cfg or {}&lt;br /&gt;
&lt;br /&gt;
	local success, title, PNS, PNSIsTalk, nsid&lt;br /&gt;
&lt;br /&gt;
	--&lt;br /&gt;
	-- 一、处理标题&lt;br /&gt;
	--&lt;br /&gt;
	if not pageOrNs or pageOrNs == &amp;#039;&amp;#039; then&lt;br /&gt;
	    -- 如果未指定頁面及命名空間參數，以當前頁面讀取&lt;br /&gt;
	    title = mw.title.getCurrentTitle()&lt;br /&gt;
	    nsid = title.namespace&lt;br /&gt;
	else&lt;br /&gt;
		local ns&lt;br /&gt;
		if not cfg.forcePage then&lt;br /&gt;
			if pageOrNs:match(&amp;#039;^-?%d+$&amp;#039;) and mw.site.namespaces[tonumber(pageOrNs)] then&lt;br /&gt;
				-- 如果用户指定一个数字，优先视为命名空间数字，无相应数字时才视为条目名称&lt;br /&gt;
				ns = mw.site.namespaces[tonumber(pageOrNs)]&lt;br /&gt;
			else&lt;br /&gt;
				-- 再判断是否为命名空间名称&lt;br /&gt;
				ns = mw.site.namespaces[pageOrNs]&lt;br /&gt;
				if not ns and pageOrNs:match(&amp;#039;:$&amp;#039;) then&lt;br /&gt;
					-- 允許 &amp;lt;ns&amp;gt;:&lt;br /&gt;
					ns = mw.site.namespaces[pageOrNs:sub(1, -2)]&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- 如果为命名空间名称，按命名空间处理，否则按页面标题处理&lt;br /&gt;
		if ns then -- pageOrNs 是{{ns:}}能解析的&lt;br /&gt;
			-- 請注意：&lt;br /&gt;
			-- 如果你想指向一個名為 [[3]] 的條目，你應該&lt;br /&gt;
			-- 1. 傳參 :3&lt;br /&gt;
			-- 2. 指定 forcePage=true&lt;br /&gt;
			-- 以免落到這裡發生錯誤&lt;br /&gt;
			-- 想指定名為 [[維基百科]] 的條目同理&lt;br /&gt;
			nsid = ns.id&lt;br /&gt;
			title = nil&lt;br /&gt;
		else&lt;br /&gt;
			success, title = pcall(mw.title.new, pageOrNs)&lt;br /&gt;
			if not success or not title or title.prefixedText == &amp;#039;&amp;#039; then&lt;br /&gt;
				-- 不是一个合法页面名称，报错&lt;br /&gt;
				return makeError(string.format(msg(&amp;#039;Error&amp;#039;, &amp;#039;pg-error&amp;#039;, lang), pageOrNs))&lt;br /&gt;
			else&lt;br /&gt;
				-- 其他正常標題或偽命名空間，無效的命名空間也被當條目處理&lt;br /&gt;
				nsid = title.namespace&lt;br /&gt;
				if nsid == 0 or nsid == 1 then&lt;br /&gt;
					PNS, PNSIsTalk = mNS._isPseudoNamespace(pageOrNs, true)&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- 1.1 外部链接与伪命名空间，提前返回&lt;br /&gt;
	if title and title.isExternal then&lt;br /&gt;
		return msg(&amp;#039;Type&amp;#039;, &amp;#039;external&amp;#039;, lang)&lt;br /&gt;
	elseif PNS then&lt;br /&gt;
		-- 偽命名空間&lt;br /&gt;
		-- 丟給[[Module:Namespace]]處理&lt;br /&gt;
		return mNS._pseudoNamespaceDisplay(lang, PNS, PNSIsTalk)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- 1.2 命名空间名称&lt;br /&gt;
	local namespace = mNS._namespaceName(lang, nsid)&lt;br /&gt;
&lt;br /&gt;
	-- 如果不需要检测页面类型，或者没有加载页面内容，则直接结束&lt;br /&gt;
	if cfg.skipCheckPageType or not title then&lt;br /&gt;
		return namespace .. getDefaultSuffix(nsid, lang)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--&lt;br /&gt;
	-- 二、判断頁面内容類型&lt;br /&gt;
	--&lt;br /&gt;
	local pageType&lt;br /&gt;
&lt;br /&gt;
	-- 特殊处理：固定沙盒&lt;br /&gt;
	if isSandbox(title, nsid) then&lt;br /&gt;
		return namespace .. msg(&amp;#039;Type&amp;#039;, &amp;#039;sandbox&amp;#039;, lang)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- 特殊处理：编辑提示/邮件提示页面&lt;br /&gt;
	pageType = matchNotice(title, nsid)&lt;br /&gt;
	if pageType ~= nil then&lt;br /&gt;
		local text = msg(&amp;#039;Type&amp;#039;, pageType, lang)&lt;br /&gt;
		local userLink = &amp;#039;[[User:&amp;#039; .. title.rootText .. &amp;#039;|&amp;#039; .. title.rootText .. &amp;#039;]]&amp;#039;&lt;br /&gt;
		text = string.gsub(text, &amp;#039;%%u&amp;#039;, function() return userLink end)&lt;br /&gt;
		return text&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- 特殊处理：（特例處理）模組討論頁當測試樣例展示效果&lt;br /&gt;
	-- 模組討論命名空間不在 EnablePageTypeNamespaces 内，必须在 2.1 之前处理&lt;br /&gt;
	if nsid == NS.MODULE_TALK and lowerFirst(title.subpageText) == &amp;#039;testcases&amp;#039; then&lt;br /&gt;
		return namespace .. msg(&amp;#039;Type&amp;#039;, &amp;#039;testcases&amp;#039;, lang)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- 2.1 判断是否应该继续检测页面内容类型&lt;br /&gt;
	local isCheckPageType = inArray(nsid, data.NamespaceSuffixConfig.EnablePageTypeNamespaces)&lt;br /&gt;
	if not isCheckPageType then&lt;br /&gt;
		return namespace .. getDefaultSuffix(nsid, lang)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- 2.2 根据内容模型判断，如非标准wikitext则直接结束&lt;br /&gt;
	local modelType = data.ContentModelMap[title.contentModel]&lt;br /&gt;
	if modelType then&lt;br /&gt;
		return namespace .. msg(&amp;#039;Type&amp;#039;, modelType, lang)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- 2.3 是否为重定向&lt;br /&gt;
	if title.isRedirect then&lt;br /&gt;
		return namespace .. msg(&amp;#039;Type&amp;#039;, &amp;#039;redirect&amp;#039;, lang)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- 2.4 根据子页面名称判断&lt;br /&gt;
	-- 追加檢測文檔、沙盒、測試樣例的命名空間&lt;br /&gt;
	-- 追加檢測臨時頁面的命名空間&lt;br /&gt;
	-- matchSubpageType已对该命名空间该不该追加作出判断&lt;br /&gt;
	if pageType == nil then&lt;br /&gt;
		pageType = matchSubpageType(title, nsid)&lt;br /&gt;
		-- 立即结束，减少不必要嵌入&lt;br /&gt;
		if pageType ~= nil then&lt;br /&gt;
			return namespace .. msg(&amp;#039;Type&amp;#039;, pageType, lang)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- 2.5 根据页面内容判断&lt;br /&gt;
	if not cfg.skipCheckContent then&lt;br /&gt;
		local content = title:getContent() or &amp;#039;&amp;#039;&lt;br /&gt;
		pageType = matchContentType(content, nsid)&lt;br /&gt;
	end&lt;br /&gt;
	if pageType then&lt;br /&gt;
		return namespace .. msg(&amp;#039;Type&amp;#039;, pageType, lang)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return (namespace .. getDefaultSuffix(nsid, lang) or &amp;#039;&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.main(frame) &lt;br /&gt;
	local args = require(&amp;#039;Module:Arguments&amp;#039;).getArgs(frame, {&lt;br /&gt;
		valueFunc = function (key, value)&lt;br /&gt;
			if key == 2 then&lt;br /&gt;
				return type(value) == &amp;#039;string&amp;#039; and mw.text.trim(value) or value&lt;br /&gt;
			elseif value then&lt;br /&gt;
				value = mw.text.trim(value)&lt;br /&gt;
				if value ~= &amp;#039;&amp;#039; then&lt;br /&gt;
					return value&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			return nil&lt;br /&gt;
		end&lt;br /&gt;
	})&lt;br /&gt;
&lt;br /&gt;
	local lang = args[1] or args[&amp;#039;1&amp;#039;] or args[&amp;#039;lang&amp;#039;] or nil&lt;br /&gt;
	local pageOrNs = args[2] or args[&amp;#039;2&amp;#039;] or args[&amp;#039;pageOrNs&amp;#039;] or nil&lt;br /&gt;
	local forcePage = yesno(args[&amp;#039;forcePage&amp;#039;]) or false&lt;br /&gt;
	local skipCheckPageType = yesno(args[&amp;#039;skipCheckPageType&amp;#039;]) or false&lt;br /&gt;
	local skipCheckContent = yesno(args[&amp;#039;skipCheckContent&amp;#039;]) or false&lt;br /&gt;
&lt;br /&gt;
	return p._namespace_pagename(lang, pageOrNs, {&lt;br /&gt;
		forcePage = forcePage,&lt;br /&gt;
		skipCheckPageType = skipCheckPageType,&lt;br /&gt;
		skipCheckContent = skipCheckContent,&lt;br /&gt;
	})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>wikipedia&gt;Hamish</name></author>
	</entry>
</feed>