Jump to content

Module:Uses TemplateStyles: Difference between revisions

From p1gwars
m 1 revision imported
copy slopped edit from sandbox to provide a link to Special:EditPage for the linked pages; looks great to me on all the testcases, i dont think this will bust anything but yolo User:Pppery feel free to shoot me if i break anything
Line 1: Line 1:
require("strict");
-- This module implements the {{Uses TemplateStyles}} template.
local yesno = require('Module:Yesno')
local yesno = require('Module:Yesno')
local mList = require('Module:List')
local mList = require('Module:List')
Line 10: Line 8:


local function format(msg, ...)
local function format(msg, ...)
-- Content sourced from [[commons:Data:I18n/Uses TemplateStyles.tab]]
return TNT.format('I18n/Uses TemplateStyles', msg, ...)
return TNT.format('I18n/Uses TemplateStyles', msg, ...)
end
end
Line 18: Line 15:
end
end


function p.main(frame)
local function makeEditSup(pageName)
local origArgs = frame:getParent().args
return string.format('<sup>&lbrack;[[Special:Edit/%s|e]]&rbrack;</sup>', pageName)
local args = {}
for k, v in pairs(origArgs) do
v = v:match('^%s*(.-)%s*$')
if v ~= '' then
args[k] = v
end
end
return p._main(args)
end
end


function p._main(args, cfg)
-- Build just the "(sandbox)" suffix using the i18n message, without duplicating the main link.
local tStyles = mTableTools.compressSparseArray(args)
local function makeSandboxSuffix(tsSandboxPrefixed)
local box = p.renderBox(tStyles)
-- i18n message is: "$1 ([[$2|sandbox]])"
local trackingCategories = p.renderTrackingCategories(args, tStyles)
-- Passing empty $1 yields " ([[:...|sandbox]])" -> trim leading whitespace to get "(sandbox)" portion.
return box .. trackingCategories
local s = format('sandboxlink', '', ':' .. tsSandboxPrefixed)
return (s:gsub('^%s+', ''))
end
end


function p.renderBox(tStyles)
local function renderBox(tStyles)
local boxArgs = {}
local boxArgs = {
type = 'notice',
small = true,
image = string.format('[[File:Farm-Fresh css add.svg|32px|alt=%s]]', format('logo-alt'))
}
 
if #tStyles < 1 then
if #tStyles < 1 then
boxArgs.text = string.format('<strong class="error">%s</strong>', format('error-emptylist'))
boxArgs.text = string.format('<strong class="error">%s</strong>', format('error-emptylist'))
Line 44: Line 39:
local cfg = getConfig()
local cfg = getConfig()
local tStylesLinks = {}
local tStylesLinks = {}
for i, ts in ipairs(tStyles) do
for i, ts in ipairs(tStyles) do
local link = string.format('[[:%s]]', ts)
local viewLink = string.format('[[:%s]]', ts)
local sandboxLink = nil
local editSup = makeEditSup(ts)
 
local out = viewLink .. editSup
 
-- Optional sandbox link + sandbox edit link
local tsTitle = mw.title.new(ts)
local tsTitle = mw.title.new(ts)
if tsTitle and cfg['sandbox_title'] then
if tsTitle and cfg['sandbox_title'] then
local tsSandboxTitle = mw.title.new(string.format(
local tsSandboxTitle = mw.title.new(string.format(
'%s:%s/%s/%s', tsTitle.nsText, tsTitle.baseText, cfg['sandbox_title'], tsTitle.subpageText))
'%s:%s/%s/%s',
tsTitle.nsText,
tsTitle.baseText,
cfg['sandbox_title'],
tsTitle.subpageText
))
 
if tsSandboxTitle and tsSandboxTitle.exists then
if tsSandboxTitle and tsSandboxTitle.exists then
sandboxLink = format('sandboxlink', link, ':' .. tsSandboxTitle.prefixedText)
local sandboxSuffix = makeSandboxSuffix(tsSandboxTitle.prefixedText)
local sandboxEditSup = makeEditSup(tsSandboxTitle.prefixedText)
out = out .. ' ' .. sandboxSuffix .. ' ' .. sandboxEditSup
end
end
end
end
tStylesLinks[i] = sandboxLink or link
 
tStylesLinks[i] = out
end
end
local tStylesList = mList.makeList('bulleted', tStylesLinks)
local tStylesList = mList.makeList('bulleted', tStylesLinks)
boxArgs.text = format(
boxArgs.text = format(
mw.title.getCurrentTitle():inNamespaces(828,829) and 'header-module' or 'header-template') ..
mw.title.getCurrentTitle():inNamespaces(828, 829) and 'header-module' or 'header-template'
'\n' .. tStylesList
) .. '\n' .. tStylesList
end
end
boxArgs.type = 'notice'
 
boxArgs.small = true
boxArgs.image = string.format('[[File:Farm-Fresh css add.svg|32px|alt=%s]]', format('logo-alt'))
return mMessageBox.main('mbox', boxArgs)
return mMessageBox.main('mbox', boxArgs)
end
end


function p.renderTrackingCategories(args, tStyles, titleObj)
local function renderTrackingCategories(args, tStyles, titleObj)
if yesno(args.nocat) then
if yesno(args.nocat) then
return ''
return ''
end
end
 
local cfg = getConfig()
local cfg = getConfig()
local cats = {}
local cats = {}
 
-- Error category
-- Error category
if #tStyles < 1 and cfg['error_category'] then
if #tStyles < 1 and cfg['error_category'] then
cats[#cats + 1] = cfg['error_category']
cats[#cats + 1] = cfg['error_category']
end
end
 
-- TemplateStyles category
-- TemplateStyles category
titleObj = titleObj or mw.title.getCurrentTitle()
titleObj = titleObj or mw.title.getCurrentTitle()
Line 95: Line 102:
local addedLevelCat = false
local addedLevelCat = false
local addedPadlockCat = false
local addedPadlockCat = false
for i, ts in ipairs(tStyles) do
for _, ts in ipairs(tStyles) do
local tsTitleObj = mw.title.new(ts)
local tsTitleObj = mw.title.new(ts)
local tsProt = tsTitleObj.protectionLevels["edit"] and tsTitleObj.protectionLevels["edit"][1] or nil
local tsProt = tsTitleObj.protectionLevels["edit"] and tsTitleObj.protectionLevels["edit"][1] or nil
if cfg['protection_conflict_category'] and tsProt ~= currentProt and not addedLevelCat then
addedLevelCat = true
cats[#cats + 1] = cfg['protection_conflict_category']
end
if cfg['padlock_pattern'] and tsProt and not addedPadlockCat then
if cfg['padlock_pattern'] and tsProt and not addedPadlockCat then
local content = tsTitleObj:getContent()
local content = tsTitleObj:getContent()
Line 107: Line 110:
cats[#cats + 1] = cfg['missing_padlock_category']
cats[#cats + 1] = cfg['missing_padlock_category']
addedPadlockCat = true
addedPadlockCat = true
end
end
if cfg['protection_conflict_category'] and currentProt and tsProt ~= currentProt and not addedLevelCat then
currentProt = cfg['protection_hierarchy'][currentProt] or 0
tsProt = cfg['protection_hierarchy'][tsProt] or 0
if tsProt < currentProt then
addedLevelCat = true
cats[#cats + 1] = cfg['protection_conflict_category']
end
end
end
end
Line 112: Line 123:
end
end
end
end
for i, cat in ipairs(cats) do
for i, cat in ipairs(cats) do
cats[i] = string.format('[[Category:%s]]', cat)
cats[i] = string.format('[[Category:%s]]', cat)
end
end
return table.concat(cats)
return table.concat(cats)
end
function p._main(args)
local cfg = getConfig()
if #args == 0 then
local prefixed = mw.title.getCurrentTitle().prefixedText
prefixed = prefixed:gsub("/doc", "")
args[1] = prefixed .. "/" .. cfg["default_subpage_name"]
end
local tStyles = mTableTools.compressSparseArray(args)
local box = renderBox(tStyles)
local trackingCategories = renderTrackingCategories(args, tStyles)
return box .. trackingCategories
end
function p.main(frame)
local origArgs = frame:getParent().args
local args = {}
for k, v in pairs(origArgs) do
v = v:match('^%s*(.-)%s*$')
if v ~= '' then
args[k] = v
end
end
return p._main(args)
end
end


return p
return p

Revision as of 03:11, 16 February 2026

-


local yesno = require('Module:Yesno')
local mList = require('Module:List')
local mTableTools = require('Module:TableTools')
local mMessageBox = require('Module:Message box')
local TNT = require('Module:TNT')

local p = {}

local function format(msg, ...)
	return TNT.format('I18n/Uses TemplateStyles', msg, ...)
end

local function getConfig()
	return mw.loadData('Module:Uses TemplateStyles/config')
end

local function makeEditSup(pageName)
	return string.format('<sup>&lbrack;[[Special:Edit/%s|e]]&rbrack;</sup>', pageName)
end

-- Build just the "(sandbox)" suffix using the i18n message, without duplicating the main link.
local function makeSandboxSuffix(tsSandboxPrefixed)
	-- i18n message is: "$1 ([[$2|sandbox]])"
	-- Passing empty $1 yields " ([[:...|sandbox]])" -> trim leading whitespace to get "(sandbox)" portion.
	local s = format('sandboxlink', '', ':' .. tsSandboxPrefixed)
	return (s:gsub('^%s+', ''))
end

local function renderBox(tStyles)
	local boxArgs = {
		type = 'notice',
		small = true,
		image = string.format('[[File:Farm-Fresh css add.svg|32px|alt=%s]]', format('logo-alt'))
	}

	if #tStyles < 1 then
		boxArgs.text = string.format('<strong class="error">%s</strong>', format('error-emptylist'))
	else
		local cfg = getConfig()
		local tStylesLinks = {}

		for i, ts in ipairs(tStyles) do
			local viewLink = string.format('[[:%s]]', ts)
			local editSup = makeEditSup(ts)

			local out = viewLink .. editSup

			-- Optional sandbox link + sandbox edit link
			local tsTitle = mw.title.new(ts)
			if tsTitle and cfg['sandbox_title'] then
				local tsSandboxTitle = mw.title.new(string.format(
					'%s:%s/%s/%s',
					tsTitle.nsText,
					tsTitle.baseText,
					cfg['sandbox_title'],
					tsTitle.subpageText
				))

				if tsSandboxTitle and tsSandboxTitle.exists then
					local sandboxSuffix = makeSandboxSuffix(tsSandboxTitle.prefixedText)
					local sandboxEditSup = makeEditSup(tsSandboxTitle.prefixedText)
					out = out .. ' ' .. sandboxSuffix .. ' ' .. sandboxEditSup
				end
			end

			tStylesLinks[i] = out
		end

		local tStylesList = mList.makeList('bulleted', tStylesLinks)
		boxArgs.text = format(
			mw.title.getCurrentTitle():inNamespaces(828, 829) and 'header-module' or 'header-template'
		) .. '\n' .. tStylesList
	end

	return mMessageBox.main('mbox', boxArgs)
end

local function renderTrackingCategories(args, tStyles, titleObj)
	if yesno(args.nocat) then
		return ''
	end

	local cfg = getConfig()
	local cats = {}

	-- Error category
	if #tStyles < 1 and cfg['error_category'] then
		cats[#cats + 1] = cfg['error_category']
	end

	-- TemplateStyles category
	titleObj = titleObj or mw.title.getCurrentTitle()
	if (titleObj.namespace == 10 or titleObj.namespace == 828)
		and not cfg['subpage_blacklist'][titleObj.subpageText]
	then
		local category = args.category or cfg['default_category']
		if category then
			cats[#cats + 1] = category
		end
		if not yesno(args.noprotcat) and (cfg['protection_conflict_category'] or cfg['padlock_pattern']) then
			local currentProt = titleObj.protectionLevels["edit"] and titleObj.protectionLevels["edit"][1] or nil
			local addedLevelCat = false
			local addedPadlockCat = false
			for _, ts in ipairs(tStyles) do
				local tsTitleObj = mw.title.new(ts)
				local tsProt = tsTitleObj.protectionLevels["edit"] and tsTitleObj.protectionLevels["edit"][1] or nil
				if cfg['padlock_pattern'] and tsProt and not addedPadlockCat then
					local content = tsTitleObj:getContent()
					if not content:find(cfg['padlock_pattern']) then
						cats[#cats + 1] = cfg['missing_padlock_category']
						addedPadlockCat = true
					end
				end
				if cfg['protection_conflict_category'] and currentProt and tsProt ~= currentProt and not addedLevelCat then
					currentProt = cfg['protection_hierarchy'][currentProt] or 0
					tsProt = cfg['protection_hierarchy'][tsProt] or 0
					if tsProt < currentProt then
						addedLevelCat = true
						cats[#cats + 1] = cfg['protection_conflict_category']
					end
				end
			end
		end
	end

	for i, cat in ipairs(cats) do
		cats[i] = string.format('[[Category:%s]]', cat)
	end
	return table.concat(cats)
end

function p._main(args)
	local cfg = getConfig()
	if #args == 0 then
		local prefixed = mw.title.getCurrentTitle().prefixedText
		prefixed = prefixed:gsub("/doc", "")
		args[1] = prefixed .. "/" .. cfg["default_subpage_name"]
	end
	local tStyles = mTableTools.compressSparseArray(args)
	local box = renderBox(tStyles)
	local trackingCategories = renderTrackingCategories(args, tStyles)
	return box .. trackingCategories
end

function p.main(frame)
	local origArgs = frame:getParent().args
	local args = {}
	for k, v in pairs(origArgs) do
		v = v:match('^%s*(.-)%s*$')
		if v ~= '' then
			args[k] = v
		end
	end
	return p._main(args)
end

return p