Module:High-use: Difference between revisions

From NvWiki
Jump to navigation Jump to search
m 1 revision imported: Import modules used with Template:Infobox software
 
(3 intermediate revisions by the same user not shown)
Line 1: Line 1:
{{talk header}}
require('strict')
{{Centralized talk page|Template talk:High-risk}}
{{copied|collapse=yes
|from1=Template:High-use|from_oldid1=777931378|to1=:incubator:Template:Wp/nod/High-risk|to_diff1=4241075
|from2=Template:High-use|from_oldid2=777931378|to2=:incubator:Template:Wp/nod/high-use|to_diff2=4241328
|from3=Template:High-use/doc|from_oldid3=882320677|to3=:incubator:Template:Wp/nod/High-risk/doc|to_diff3=4241810
|from4=Template:Used_in_system|from_oldid4=826013671|to4=:incubator:Template:Wp/nod/used_in_system|to_diff4=4241119
|from5=Template:Used_in_system/doc|from_oldid5=729543962|to5=:incubator:Template:Wp/nod/used_in_system/doc|to_diff5=4241135}}
{{permanently protected}}
{{User:MiszaBot/config
| algo                = old(120d)
| archive            = Template talk:High-use/Archive %(counter)d
| counter            = 1
| maxarchivesize      = 150K
| archiveheader      = {{Automatic archive navigator}}
| minthreadstoarchive = 1
| minthreadsleft      = 4
}}


== Include mainspace count ==
local p = {}
local getArgs = require('Module:Arguments').getArgs


Instead of just taking the number of transclusions and dividing by <nowiki>{{NUMBEROFPAGES}}</nowiki> (which is currently 63,227,481), I was thinking it might make for a more cautionary warning to also show how big the number is compared to <nowiki>{{NUMBEROFARTICLES}}</nowiki>. See [https://en.wikipedia.org/w/index.php?title=Module%3AHigh-use%2Fsandbox&diff=1292860919&oldid=1292860160] for the sandboxed change. Basically, this would cause the template to look like this:
local _fetch = require('Module:Transclusion_count')._fetch -- _fetch looks at the 'demo' argument
<templatestyles src="Module:Message box/ombox.css"></templatestyles><table class="plainlinks ombox ombox-content" role="presentation"><tr><td class="mbox-image">[[File:Ambox warning orange.svg|40px|alt=Warning|link=]]</td><td class="mbox-text">'''This template is used on [https://linkcount.toolforge.org/?project=en.wikipedia.org&page=Template%3AYes#transclusions approximately 6,440,000 pages, which is roughly 92% of all mainspace articles or 10% of all pages]'''.<br /> To avoid major disruption and server load, any changes should be tested in the template's [[Template:Yes/sandbox|/sandbox]] or [[Template:Yes/testcases|/testcases]] subpages, or in your own [[Wikipedia:User pages#SUB|user subpage]]. The tested changes can be added to this page in a single edit. Consider discussing changes on the [[Template talk:Yes|talk page]] before implementing them.</td></tr></table>
local yesno = require('Module:Yesno')
Naturally, not all templates that use {{tl|High-use}} are used in mainspace, so I can see how this change could be a little confusing, but I think it would still make the percent number more meaningfully cautionary. For example, [[Template:Short description]] says that the template is used on "10% of all pages", which honestly feels like not a big number—it would more clearly impress upon the layperson the gravity of the situation if it said "92% of all mainspace articles". [[Template:WikiProject banner shell]] would say: "This template is used on approximately 11,300,000 pages, which is roughly 161% of all mainspace articles or 18% of all pages." [[User:Mz7|Mz7]] ([[User talk:Mz7|talk]]) 06:50, 29 May 2025 (UTC)


:@[[User:Mz7|Mz7]] I'm worried that would be a bit misleading, as it would result in things like {{tl|WikiProject banner shell}} saying that it's being used on 163% of mainspace articles. If there's a strong desire to include this information I could look into having {{noping|Ahechtbot}} tabulate mainspace transclusions in addition to all transclusions, but that would cause a significant increase in runtime and require breaking changes to the data pages. <span class="nowrap">--[[User:Ahecht|Ahecht]] ([[User talk:Ahecht|<b style="color:#FFF;background:#04A;display:inline-block;padding:1px;vertical-align:middle;font:bold 50%/1 sans-serif;text-align:center">TALK<br />PAGE</b>]])</span> 18:13, 29 August 2025 (UTC)
local lang_obj = mw.getContentLanguage() -- this here because the language object is used multiple places in the module
::Just adding that I already did this experiment [[Template_talk:High-use/Archive_1#c-Ahecht-2021-08-05T05:12:00.000Z-Ahecht-2021-08-05T02:19:00.000Z|back in 2021]], and running the transclusion count query limited to the article namespace wasn't feasible (it just sat there for three hours before timing out, compared to 10-20 minutes for the all-namespace query). <span class="nowrap">--[[User:Ahecht|Ahecht]] ([[User talk:Ahecht|<b style="color:#FFF;background:#04A;display:inline-block;padding:1px;vertical-align:middle;font:bold 50%/1 sans-serif;text-align:center">TALK<br />PAGE</b>]])</span> 18:54, 10 October 2025 (UTC)
local large_count_cutoff = 100000
local approx_num_total_pages = 63000000


== Edit request 27 August 2025: refactor ==
local user_subpage_info_page = 'Wikipedia:User pages#SUB'
local sandbox_module_page = 'Module:Sandbox'
local system_messages_cat = 'Pages used in system messages needing protection'
local sandbox_word = 'sandbox'
local testcases_word = 'testcases'
local doc_word = 'doc'


{{edit template-protected|Module:High-use|answered=yes}}
local function count_from_args(args)
'''Description of suggested change:''' I've refactored the module code to make it:
if tonumber(args.count) then -- check if function has already been used
* easier to understand (added comments)
return tonumber(args.count) -- early exit if so
* easier to localize
end
* have less repeated code
* use {{parameter|demo}} as the title everywhere, including in the Toolforge link, if provided
local count
* use the base page for /testcases pages as well as /doc and /sandbox
* use Lua for the system categorization code instead of preprocessing a string containing {{tlx|sandbox other}}, a switch statement, and a [[Module:Effective protection level]] invocation
if yesno(args['fetch']) ~= false then
count = _fetch(args) -- fetch transclusion count
end
-- use explicitly-provided count when fetch fails
if count == nil and args[1] ~= nil and args[1] ~= '' then
-- convert local language number string to a number understandable by Lua
count = mw.ustring.gsub(args[1], '+$', '')
count = lang_obj:parseFormattedNumber(args[1])
end
-- in case someone writes a non-positive number
if count and count > 0 then
return count
end
return nil
end


My code is in [[Module:High-use/sandbox]] and the test cases are at [[Template:High-use/testcases]]. Please check my code and update the main module if it looks good!
-- Actions if there is a large (greater than or equal to 100,000) transclusion count
local function risk_boolean(args)
if args.risk == true or args.risk == false then
return args.risk
elseif args[1] == 'risk' then
return true
else
local count = count_from_args(args)
if count and count >= large_count_cutoff then
return true
end
end
return false
end


'''Diff:'''
-- function retained for backwards compatibility
{{Compare pages|1263627510|1312139913|label=sandbox diff}}
function p._risk(args)
—[[User:CalendulaAsteraceae|CalendulaAsteraceae]] ([[User talk:CalendulaAsteraceae|talk]] • [[Special:Contributions/CalendulaAsteraceae|contribs]]) 08:28, 27 August 2025 (UTC)
return risk_boolean(args) and 'risk' or ''
:Answering your post at {{slink|Wikipedia:Village_pump_(technical)|Code_review_for_Module:High-use_refactor}} here because this is a better venue.
end
:
:Add <syntaxhighlight lang="lua" inline="1">require ('strict')</syntaxhighlight> which will help find globals that ought not be globals, etc.
:
:For i18n, consider rewriting <syntaxhighlight lang="lua" inline="1">count_from_args()</syntaxhighlight> ([[Special:Permalink/1308381229#L-18--L-36|lines 18–36]] – permalink); mayhaps sommat like this:<syntaxhighlight lang="lua">require ('strict');


local lang_obj = mw.getContentLanguage() -- this here because the language object is used multiple places in the module
-- function retained for backwards compatibility
function p.risk(frame)
return p._risk(getArgs(frame))
end


local function count_from_args(args_t)
-- count and no_percent arguments retained for backwards compatibility
if tonumber(args_t.count) then -- check if function has already been used
function p._num(args, count, no_percent)
return count; -- early exit if already used
if count == nil then
count = count_from_args(args)
end
end
args.count = count
args.risk = risk_boolean(args)
-- Build output string
local return_value = ''
if args.count == nil and args.risk then
return 'a very large number of'
elseif args.count == nil then
return 'many'
else
-- Use 2 significant figures for smaller numbers and 3 for larger ones
local sigfig = 2
if args.count >= large_count_cutoff then
sigfig = 3
end
-- Prepare to round to appropriate number of sigfigs
local f = math.floor(math.log10(args.count)) - sigfig + 1
-- Round and insert 'approximately' or '+' when appropriate
if yesno(args[2]) == true or (type(args[1]) == 'string' and (mw.ustring.sub(args[1], -1) == '+')) then
-- Round down
return_value = string.format('%s+', lang_obj:formatNum(math.floor( (args.count / 10^(f)) ) * (10^(f))) )
else
-- Round to nearest
return_value = string.format('approximately&#x20;%s', lang_obj:formatNum(math.floor( (args.count / 10^(f)) + 0.5) * (10^(f))) )
end
-- Insert percentage of pages if that is likely to be >= 1% and when |no-percent= not set to yes
no_percent = yesno(no_percent or args['no-percent'])
if args.count and args.count >= approx_num_total_pages/100 and not no_percent then
local num_total_pages = mw.getCurrentFrame():callParserFunction('NUMBEROFPAGES', 'R')
local total_percent = math.floor( ( ( args.count/num_total_pages ) * 100) + 0.5)
if total_percent >= 1 then
return_value = string.format('%s&#x20;pages, or roughly %s%% of all', return_value, total_percent)
end
end
end
return return_value
end


local count;
-- used by [[Template:Stub documentation]] and other pages
-- count argument retained for backwards compatibility
function p.num(frame, count)
return p._num(getArgs(frame), count)
end


if count == nil and yesno(args_t['fetch']) == true then -- '== true' instead of '~= false'
-- count argument retained for backwards compatibility
count = _fetch(args_t) -- fetch transclusion count
function p._text(args, count)
--[=[
Only show the information about how this template gets updated
if someone is actually editing the page and maybe trying to update the count.
]=]
local bot_text = (mw.getCurrentFrame():preprocess('{{REVISIONID}}') == '') and ("\n\n----\n'''Preview message''':" .. ' Transclusion count updated automatically ([[Template:High-use/doc#Technical details|see documentation]]).') or ''
if count == nil then
count = count_from_args(args)
end
args.count = count
args.risk = risk_boolean(args)
-- trim /doc, /sandbox and /testcases
local title = args.title or (args.demo and args.demo ~= '' and mw.title.new(args.demo, 'Template')) or mw.title.getCurrentTitle()
if title.subpageText == doc_word or title.subpageText == sandbox_word or title.subpageText == testcases_word then
title = title.basePageTitle
end
-- use /testcases of base template
local testcases_page = mw.title.new(title.prefixedText .. '/' .. testcases_word)
-- exists is expensive
while testcases_page.basePageTitle.isSubpage and not testcases_page.exists do
testcases_page = mw.title.new(testcases_page.basePageTitle.basePageTitle.prefixedText .. '/' .. testcases_word)
end
end
if count == nil and args_t[1] ~= nil and args_t[1] ~= '' then -- use explicitly-provided count when fetch fails
local systemMessages = (args['system'] or '') ~= ''
count = math.floor (lang_obj:parseFormattedNumber (args_t[1])); -- convert local language number string to a number understandable by lua
-- This retrieves the project URL automatically to simplify localization.
local templateCount = ('on [https://linkcount.toolforge.org/?project=%s&page=%s#transclusions %s pages]'):format(
title:fullUrl():gsub('//(.-)/.*', '%1'),
mw.uri.encode(title.fullText), p._num(args))
local used_on_text = "'''This " .. (title:inNamespace('Module') and 'Lua module' or 'template') .. ' is used '
if systemMessages then
used_on_text = used_on_text .. args['system'] ..
((args.count and args.count > 2000) and ("''', and " .. templateCount) or ("'''"))
else
used_on_text = used_on_text .. templateCount .. "'''"
end
end
return count > 0 and count or nil; -- incase someone writes a negative number
local sandbox_text = ('%s\'s [[%s/sandbox|/sandbox]] or [[%s|/testcases]] subpages, or in your own [[%s]]. '):format(
end</syntaxhighlight>
title:inNamespace('Module') and 'module' or 'template',
:—[[User:Trappist the monk|Trappist the monk]] ([[User talk:Trappist the monk|talk]]) 16:35, 29 August 2025 (UTC)
title.fullText,
::Thank you, implemented! I think the current code does use <code>_fetch</code> if <code>args['fetch']</code> is nil, so I've left that as-is. —[[User:CalendulaAsteraceae|CalendulaAsteraceae]] ([[User talk:CalendulaAsteraceae|talk]] [[Special:Contributions/CalendulaAsteraceae|contribs]]) 21:25, 29 August 2025 (UTC)
testcases_page.fullText,
:It looks like you've implemented hooks to show percentage of articles in addition to all pages. See the section above for my concerns there. We can tabulate mainspace usage separately with the bot, but it's not worth the effort unless there's actual consensus to include it. <span class="nowrap">--[[User:Ahecht|Ahecht]] ([[User talk:Ahecht|<b style="color:#FFF;background:#04A;display:inline-block;padding:1px;vertical-align:middle;font:bold 50%/1 sans-serif;text-align:center">TALK<br />PAGE</b>]])</span> 19:09, 29 August 2025 (UTC)
title:inNamespace('Module') and (sandbox_module_page .. '|module sandbox') or (user_subpage_info_page .. '|user subpage')
::TBH I just left that in because someone else had been working on it, no problem to take that out. —[[User:CalendulaAsteraceae|CalendulaAsteraceae]] ([[User talk:CalendulaAsteraceae|talk]] • [[Special:Contributions/CalendulaAsteraceae|contribs]]) 21:20, 29 August 2025 (UTC)
)
::@[[User:Ahecht|Ahecht]], @[[User:Trappist the monk|Trappist the monk]], how does the updated code look? —[[User:CalendulaAsteraceae|CalendulaAsteraceae]] ([[User talk:CalendulaAsteraceae|talk]] • [[Special:Contributions/CalendulaAsteraceae|contribs]]) 03:45, 14 September 2025 (UTC)
:::@[[User:CalendulaAsteraceae|CalendulaAsteraceae]] My only concern is using the base page name for the sandbox. There are sub-templates that are listed in [[Module:Transclusion_count/data/]] that likely have their own sandboxes. For example, the "high use" message at [[Module:Adjacent stations/Amtrak]] correctly links to [[Module:Adjacent stations/Amtrak/sandbox]]. For the sandbox, the existing logic that only uses the basePageTitle if it ends in "doc" or "sandbox" is fine. For the testcases, I might see an argument to strip "doc" and "sandbox", check if that testcases page exists (although I'd do it with <code>getContent()</code> since for some reason <code>exists</code> is expensive but <code>getContent()</code> isn't), and if not use the base page title. <span class="nowrap">--[[User:Ahecht|Ahecht]] ([[User talk:Ahecht|<b style="color:#FFF;background:#04A;display:inline-block;padding:1px;vertical-align:middle;font:bold 50%/1 sans-serif;text-align:center">TALK<br />PAGE</b>]])</span> 15:39, 14 September 2025 (UTC)
local infoArg = args['info'] ~= '' and args['info']
::::@[[User:Ahecht|Ahecht]], done. —[[User:CalendulaAsteraceae|CalendulaAsteraceae]] ([[User talk:CalendulaAsteraceae|talk]] • [[Special:Contributions/CalendulaAsteraceae|contribs]]) 03:34, 15 September 2025 (UTC)
if (systemMessages or args.risk) then
::::@[[User:Ahecht|Ahecht]], thoughts on the updated code? —[[User:CalendulaAsteraceae|CalendulaAsteraceae]] ([[User talk:CalendulaAsteraceae|talk]] • [[Special:Contributions/CalendulaAsteraceae|contribs]]) 21:54, 3 October 2025 (UTC)
local info = '.'
:::::@[[User:CalendulaAsteraceae|CalendulaAsteraceae]] The testcases look fine to me. I haven't had a chance to dive into the code, but if you're willing to take ownership then go for it. <span class="nowrap">--[[User:Ahecht|Ahecht]] ([[User talk:Ahecht|<b style="color:#FFF;background:#04A;display:inline-block;padding:1px;vertical-align:middle;font:bold 50%/1 sans-serif;text-align:center">TALK<br />PAGE</b>]])</span> 18:49, 4 October 2025 (UTC)
if systemMessages then
::::::@[[User:Ahecht|Ahecht]]: Thank you! I don't have permissions to edit [[Module:High-use]], but if you copy over my latest edits at [[Module:High-use/sandbox]], I'm happy to keep an eye on things and fix any issues that come up. —[[User:CalendulaAsteraceae|CalendulaAsteraceae]] ([[User talk:CalendulaAsteraceae|talk]] • [[Special:Contributions/CalendulaAsteraceae|contribs]]) 05:27, 5 October 2025 (UTC)
info = info .. '<br />Changes to it can cause immediate changes to the ' .. mw.site.namespaces.Project.name .. ' user interface.'
:{{done}}<!-- Template:ETp --> <span class="nowrap">--[[User:Ahecht|Ahecht]] ([[User talk:Ahecht|<b style="color:#FFF;background:#04A;display:inline-block;padding:1px;vertical-align:middle;font:bold 50%/1 sans-serif;text-align:center">TALK<br />PAGE</b>]])</span> 13:57, 7 October 2025 (UTC)
end
::Thank you! —[[User:CalendulaAsteraceae|CalendulaAsteraceae]] ([[User talk:CalendulaAsteraceae|talk]] • [[Special:Contributions/CalendulaAsteraceae|contribs]]) 21:53, 7 October 2025 (UTC)
if infoArg then
===Transcluding nonexistent /testcases pages===
info = info .. '<br />' .. infoArg
end
sandbox_text = info .. '<br /> To avoid major disruption' ..
(args.count and args.count >= large_count_cutoff and ' and server load' or '') .. -- should this use args.risk?
', any changes should be tested in the ' .. sandbox_text ..
'The tested changes can be added to this page in a single edit. '
else
sandbox_text = (infoArg and ('.<br />' .. infoArg .. ' C') or ' and c') ..
'hanges may be widely noticed. Test changes in the ' .. sandbox_text
end
local discussion_text = systemMessages and 'Please discuss changes ' or 'Consider discussing changes '
if args[2] ~= nil and args[2] ~= '' and yesno(args[2]) == nil then
discussion_text = string.format('%sat [[%s]]', discussion_text, args[2])
else
discussion_text = string.format('%son the [[%s|talk page]]', discussion_text, title.talkPageTitle.fullText)
end
return used_on_text .. sandbox_text .. discussion_text .. ' before implementing them.' .. bot_text
end


{{edit template-protected|Module:High-use|answered=yes}}
-- used by [[Template:R from high-use template]]
This change appears to have caused {{tl|Taxonomy/Salticidae}} to transclude {{tl|Taxonomy/Salticidae/testcases}}, which does not exist. This new issue is happening at a few hundred or more Taxonomy templates. See [[Wikipedia:Database reports/Transclusions of non-existent templates]] for the list. It is also happening at some non-Taxonomy templates, like {{tl|Tab/Number of defined parameters}}. – [[User:Jonesey95|Jonesey95]] ([[User talk:Jonesey95|talk]]) 18:09, 8 October 2025 (UTC)
-- count argument retained for backwards compatibility
function p.text(frame, count)
return p._text(getArgs(frame), count)
end


:We can fix that by using <code>exists</code> instead of <code>getContent</code>. I think that'll be OK even though it's an expensive function, since the template is only called once per page, and [[Template:High-use/testcases]] is fine even though it calls the template a lot. @[[User:Ahecht|Ahecht]], could you copy over my changes from [[Module:High-use/sandbox]]? —[[User:CalendulaAsteraceae|CalendulaAsteraceae]] ([[User talk:CalendulaAsteraceae|talk]] • [[Special:Contributions/CalendulaAsteraceae|contribs]]) 20:20, 8 October 2025 (UTC)
-- nocat argument retained for backwards compatibility
:{{done}}<!-- Template:ETp --> <span class="nowrap">--[[User:Ahecht|Ahecht]] ([[User talk:Ahecht|<b style="color:#FFF;background:#04A;display:inline-block;padding:1px;vertical-align:middle;font:bold 50%/1 sans-serif;text-align:center">TALK<br />PAGE</b>]])</span> 20:24, 8 October 2025 (UTC)
function p._main(args, nocat)
::It looks like that worked. There are about half a dozen fully protected pages still causing /testcases transclusions to show up on the report, but they will clear on their own. – [[User:Jonesey95|Jonesey95]] ([[User talk:Jonesey95|talk]]) 16:00, 9 October 2025 (UTC)
args.count = count_from_args(args)
::It's also fixed [[Wikipedia:Database reports/Broken WikiProject templates]]. --[[User:Redrose64|<span style="color:#a80000; background:#ffeeee; text-decoration:inherit">Red</span>rose64]] &#x1f339; ([[User talk:Redrose64|talk]]) 16:06, 10 October 2025 (UTC)
args.risk = risk_boolean(args)
 
args.title = (args.demo and args.demo ~= '' and mw.title.new(args.demo, 'Template')) or mw.title.getCurrentTitle()
== Edit request 27 September 2025 ==
 
local image = 'Ambox warning yellow.svg'
{{Edit template-protected|answered=yes}}
local type_param = 'style'
 
local epilogue = ''
'''Description of suggested change:''' can we get a {{para|testcase}} that will allow you to supply a link to where the testcases are located that will replace the default of {{code|''base_template''/testcase}}? The reason for this is Modules. The testcases cannot be located at {{code|Module:Person height/testcases}} (for example) and are more likely to be located at [[Template:Infobox person/height/testcases]]. —'''[[User:Zackmann08|<span style="color:#00ced1">Zack</span><span style="color:#007F94">mann</span>]]''' (<sup>[[User_talk:Zackmann08|Talk to me]]</sup>/<sub>[[Special:Contributions/Zackmann08|<span style="color:orange;">What I been doing</span>]]</sub>) 08:42, 27 September 2025 (UTC)
: Actually they can be located at [[Module:Person height/testcases]]; you can use [[Special:ChangeContentModel]] to create a wikitext page there, or move an existing wikitext page there (and click through the edit filter warning). I'd be more inclined to just do so and create a redirect rather than convoluting up the template, but if another TPE wants to code and implement this I guess they can do so. [[User:Pppery|* Pppery *]] [[User talk:Pppery|<sub style="color:#800000">it has begun...</sub>]] 16:24, 27 September 2025 (UTC)
if args['system'] and args['system'] ~= '' then
::{{ping|Pppery}} well… You learn something new everyday! Thanks a ton. Didn’t know about Change Context Model. '''[[User:Zackmann08|<span style="color:#00ced1">Zack</span><span style="color:#007F94">mann</span>]]''' (<sup>[[User_talk:Zackmann08|Talk to me]]</sup>/<sub>[[Special:Contributions/Zackmann08|<span style="color:orange;">What I been doing</span>]]</sub>) 18:21, 27 September 2025 (UTC)
image = 'Ambox important.svg'
:::@[[User:Zackmann08|Zackmann08]] You don't even have to change the content model. The default used by the {{tl|documentation}} template (used by nearly all modules) is to locate the testcases at <code>Module:Foo/testcases</code>, and it prepopulates that module page with [[Template:Documentation/preload-module-testcases]] which uses [[Module:UnitTests]] to create the testcases. You then run it by going to <code>Module talk:Foo/testcases</code>. <span class="nowrap">--[[User:Ahecht|Ahecht]] ([[User talk:Ahecht|<b style="color:#FFF;background:#04A;display:inline-block;padding:1px;vertical-align:middle;font:bold 50%/1 sans-serif;text-align:center">TALK<br />PAGE</b>]])</span> 18:55, 27 September 2025 (UTC)
type_param = 'content'
::::{{ping|Ahecht}} that seems complicated…{{sarcasm}}. Thanks for the info though!!! —'''[[User:Zackmann08|<span style="color:#00ced1">Zack</span><span style="color:#007F94">mann</span>]]''' (<sup>[[User_talk:Zackmann08|Talk to me]]</sup>/<sub>[[Special:Contributions/Zackmann08|<span style="color:orange;">What I been doing</span>]]</sub>) 19:03, 27 September 2025 (UTC)
if yesno(nocat or args['nocat']) ~= true and not args.title.isRedirect then
 
local protection_action = (args.title:inNamespace('File') and 'upload') or 'edit'
== Used in system ==
local protection_level = require('Module:Effective protection level')._main(protection_action, args.title.fullText)
 
There is a discussion over at [[Template talk:Used in system#documentation out of date%3F]] you might be interested in. Regards [[User:CapnZapp|CapnZapp]] ([[User talk:CapnZapp|talk]]) 11:05, 5 October 2025 (UTC)
if protection_level ~= 'sysop' and protection_level ~= 'templateeditor' and protection_level ~= 'interfaceadmin' then
 
epilogue = mw.getCurrentFrame():expandTemplate {
== Updating the icon ==
title = 'sandbox other',
{{Edit template-protected|Template:High-use|answered=yes}}
args = {
 
[2] = '[[Category:' .. system_messages_cat .. ']]'
The icon for the {{Tl|Used in system}} is generic so it can be confused with any other warnings hardcoded in the /doc, even though the fact that a template is used in system messages is very important. I think it should at least use the same icon as {{Tl|High-use}} when set to {{Parameter|risk}} to better catch the attention of editors used to seeing a riangular warning for templates that have many transclusions.
}
}
end
end
elseif args.risk then
image = 'Ambox warning orange.svg'
type_param = 'content'
end
image = '[[File:' .. image .. '|40px|alt=Warning|link=]]'
if args['form'] == 'editnotice' then
return mw.getCurrentFrame():expandTemplate{
title = 'editnotice',
args = {
['image'] = image,
['text'] = p._text(args),
['expiry'] = (args['expiry'] or '')
}
} .. epilogue
else
return require('Module:Message box').main('ombox', {
type = type_param,
image = image,
text = p._text(args),
expiry = (args['expiry'] or '')
}) .. epilogue
end
end


Line {{Section link|Module:High-use#L-218}} should be changed to:
function p.main(frame)
{| class="diff diff-editfont-monospace" style="margin: auto; font-size: small; overflow-wrap: break-word;"
return p._main(getArgs(frame))
|-
end
| class="diff-lineno" | Line 216:
| class="diff-lineno" | Line 216:
|-
| class="diff-context diff-side-deleted" | <nowiki> </nowiki>
| class="diff-context diff-side-added" | <nowiki> </nowiki>
|-
| class="diff-context diff-side-deleted" | <nowiki> if args['system'] and args['system'] ~= '' then</nowiki>
| class="diff-context diff-side-added" | <nowiki> if args['system'] and args['system'] ~= '' then</nowiki>
|-
| class="diff-deletedline diff-side-deleted" | <nowiki> image = 'Ambox </nowiki><del class="diffchange diffchange-inline"><nowiki>important</nowiki></del><nowiki>.svg'</nowiki>
| class="diff-addedline diff-side-added" | <nowiki> image = 'Ambox </nowiki><ins class="diffchange diffchange-inline"><nowiki>warning orange</nowiki></ins><nowiki>.svg'</nowiki>
|-
| class="diff-context diff-side-deleted" | <nowiki> type_param = 'content'</nowiki>
| class="diff-context diff-side-added" | <nowiki> type_param = 'content'</nowiki>
|-
| class="diff-context diff-side-deleted" | <nowiki> if yesno(nocat or args['nocat']) ~= true and not args.title.isRedirect then</nowiki>
| class="diff-context diff-side-added" | <nowiki> if yesno(nocat or args['nocat']) ~= true and not args.title.isRedirect then</nowiki>
|} [[User:FaviFake|FaviFake]] ([[User talk:FaviFake|talk]]) 18:33, 11 October 2025 (UTC)
:Example of two templates looking the same in the /doc: {{Tl|Clickable button}} [[User:FaviFake|FaviFake]] ([[User talk:FaviFake|talk]]) 18:53, 11 October 2025 (UTC)
::Please link to the discussion that prompted the use of {{tl|tper}} here. The template is for edit requests that are uncontroversial or supported by consensus. – [[User:Jonesey95|Jonesey95]] ([[User talk:Jonesey95|talk]]) 20:11, 11 October 2025 (UTC)
:::I assumed it would be uncontroversial. Why do you oppose the change? [[User:FaviFake|FaviFake]] ([[User talk:FaviFake|talk]]) 20:14, 11 October 2025 (UTC)
::::Why would you assume that? Did you look in the page history to see [https://en.wikipedia.org/w/index.php?title=Module%25252525252525253AHigh-use&diff=1016517265&oldid=1016181392 that the change was made in April 2021] and the image has been stable since [[Template_talk:High-use/Archive_1#Suggestion: merge with Used in system|that change was discussed]]? You appear to be proposing to change the image back without discussion. – [[User:Jonesey95|Jonesey95]] ([[User talk:Jonesey95|talk]]) 00:08, 12 October 2025 (UTC)
:::::And you appear not to be discussing. I asked why you oppose the change. [[User:FaviFake|FaviFake]] ([[User talk:FaviFake|talk]]) 07:29, 12 October 2025 (UTC)
::::::I oppose your abuse of the edit request template, which comes with clear instructions. You continue to waste the time of editors, especially those with template editor permissions. – [[User:Jonesey95|Jonesey95]] ([[User talk:Jonesey95|talk]]) 01:40, 13 October 2025 (UTC)
:::::::So you don't oppose the actual change I'm proposing? Seems the template was entirely justified then. [[User:FaviFake|FaviFake]] ([[User talk:FaviFake|talk]]) 04:16, 13 October 2025 (UTC)
:::::::@[[User:Jonesey95|Jonesey95]] Just know that I will add it back in a few weeks if nobody actually opposes the change. Which hopefully won't happen because it is minor. [[User:FaviFake|FaviFake]] ([[User talk:FaviFake|talk]]) 17:23, 13 October 2025 (UTC)
:@[[User:FaviFake|FaviFake]], I concur with @[[User:Jonesey95|Jonesey95]] that edit requests should be implemented for uncontroversial changes, and that design changes like this are potentially controversial (something you should know after having just prompted 40+ editors to spend months debating which color to use for the village pump header...)
:You can make a proposal on a template talk page, and if no one responds after a while (particularly if you put a {{t|Please see}} invite somewhere more prominent), then you'll have [[WP:SILENTCONSENSUS|silent consensus]] to add the request (at which point the template editor will serve as the second opinion). But just jumping to the request is short-circuiting the process.
:To comment on the actual proposal, I don't have a strong view. There is [[Template:Ombox#Other_pages_message_box_types|somewhat of a system]] for which notices warrant which level of caution, and we should try to adhere to that (and build it out/formalize it) to prevent [[banner blindness]]. On the one hand, a template having many transclusions is absolutely a good reason to be significantly more cautious editing it, which argues for a more prominent notice. On the other, there isn't any concrete action that this is cautioning about (e.g. something editors might be tempted to do that this is warning against) and many high-use templates are already TE-protected (and TEs should know that protected templates they edit likely have many transclusions/require care). <span style="border:3px outset;border-radius:8pt 0;padding:1px 5px;background:linear-gradient(6rad,#86c,#2b9)">[[User:Sdkb|<span style="color:#FFF;text-decoration:inherit;font:1em Lucida Sans">Sdkb</span>]]</span> <sup>[[User talk:Sdkb|'''talk''']]</sup> 17:51, 13 October 2025 (UTC)
::@[[User:Sdkb|Sdkb]] I do oftentimes create a discussion first. It seems I have misjudged the "uncontroversiality" of this specific change, but I definitely welcome a discussion based on non-procedural arguments. [[Template talk:Documentation#Update sandbox icon to match all other templates|Here's an instance where it seems the "discussion time" was unnecessary, for example]].{{pb}}[[Banner blindness]] is actually the reason I proposed the change in the first place. In the example of {{Tl|Clickable button}}'s /doc I gave above, these two mssages look the same:{{pb}}{{warning|This template is used in system messages, and on approximately 1,120,000 pages, or roughly 2% of all pages}}{{warning|Buttons should not be used in the article namespace. If the desire is to "navigate" a reader to a new page...}}{{Pb}}Despite the first one being ''significantly'' more important than the second one. The {{Tl|Warning}} template in particular is very frequently used in /docs, especially for higher-risk templates, so I think the templae for "used in system" should ''at least'' match the icon of {{Tl|High-use}} when set to <code>|risk=</code>{{pb}}And in general, we try to use a non-default icon for widely used templates. [[User:FaviFake|FaviFake]] ([[User talk:FaviFake|talk]]) 19:11, 13 October 2025 (UTC)
:::We're in an unfortunate arms race, which is exactly how you get a bunch of bloated screaming notices, which is the exact bad outcome banner blindness warns against. I'd much prefer to see less important notices appropriately deemphasized rather than more important ones shouting ever louder (since everyone thinks that their notice is important and thus should shout, so the arms race never ends).
:::For notices like the second one, there are often better solutions. For instance, have editors considered adjusting the template code so that it produces an error if used in mainspace? That'd solve the problem and allow the notice to be removed (or at least converted to just a normal text part of the documentation). <span style="border:3px outset;border-radius:8pt 0;padding:1px 5px;background:linear-gradient(6rad,#86c,#2b9)">[[User:Sdkb|<span style="color:#FFF;text-decoration:inherit;font:1em Lucida Sans">Sdkb</span>]]</span> <sup>[[User talk:Sdkb|'''talk''']]</sup> 19:23, 13 October 2025 (UTC)
::::I agree, but since this is the current state of template documentation banners, I think this template should distinguish itself in the same way that its sister template does, with a triangular warning icon. As long as we use the default icon, banner blindness is bound to happen. [[User:FaviFake|FaviFake]] ([[User talk:FaviFake|talk]]) 04:14, 14 October 2025 (UTC)
::::[[User:Sdkb|Sdkb]] since unfortunately we can't change all the {{tl|warning}} templates placed on documentation pages into {{tl|notice}} all at once, would you support the change from the default icon to the icon used by the same family of templates? For consistency, I think that if this template's icon isn't changed, then the other triangular icons of the High-use template should be reverted back to the default {{tl|warning}} icon, as they basically say the same thing: this template is widely used. But this would create even more binder blindness, which is why I think we should stop using the default icon on just this template. Thoughts? [[User:FaviFake|FaviFake]] ([[User talk:FaviFake|talk]]) 07:46, 25 October 2025 (UTC)
:Does anyone else have opinions on keepeing these icons consistent? [[User:FaviFake|FaviFake]] ([[User talk:FaviFake|talk]]) 16:23, 17 November 2025 (UTC)
::I think you are entirely too worried about [[WP:BIKESHED|the colour of the bike shed]]. If banner blindness is an issue no one will pay attention to the icon on the banner, and if people are paying attention to the banners then it doesn't matter what icon we use. I agree with sdkb that we should instead focus on ''which'' banners get used, and ''why'' we use certain banners over others. There are definitely some warnings that really aren't needed, for example {{t|Intricate template}} could probably stand to be deleted since almost all intricate templates are likely template-protected anyway (i.e. those who cannot edit the template directly don't need to worry about the complexity of the code). [[User:Primefac|Primefac]] ([[User talk:Primefac|talk]]) 01:35, 23 November 2025 (UTC)


==Template space alias==
return p
This page seems to get good watchage, so in case you haven't noticed yet, the template space alias was changed to "TM:". Just as [[WP:PAGENAME]] can be used as a shortcut for [[Wikipedia:PAGENAME]], [[TM:PAGENAME]] is a shortcut for [[Template:PAGENAME]]. [[WP:NAMESPACE#Aliases|Just spreading the word]]. '''''[[User:Paine Ellsworth|<span style="font-size:92%;color:darkblue;font-family:Segoe Script">P.I.&nbsp;Ellsworth</span>]]'''''&thinsp;,&nbsp;[[Editor|<span style="color:black">ed.</span>]]&nbsp;–&nbsp;[[User talk:Paine Ellsworth|''welcome!'']]&nbsp;–&nbsp;<small>12:39, 26 November 2025 (UTC)</small>
:{{tq|1=the template space alias was changed to "TM:".}}<br>Thanks! What was it changed from? [[User:FaviFake|FaviFake]] ([[User talk:FaviFake|talk]]) 17:02, 19 December 2025 (UTC)
::It was changed from a [[Wikipedia:Shortcut#List of prefixes|pseudo-namespace prefix]], "T:", (ambiguous with talkspace). '''''[[User:Paine Ellsworth|<span style="font-size:92%;color:darkblue;font-family:Segoe Script">P.I.&nbsp;Ellsworth</span>]]'''''&thinsp;,&nbsp;[[Editor|<span style="color:black">ed.</span>]]&nbsp;–&nbsp;[[User talk:Paine Ellsworth|''welcome!'']]&nbsp;–&nbsp;<small>08:05, 20 December 2025 (UTC)</small>
:::Thanks! [[User:FaviFake|FaviFake]] ([[User talk:FaviFake|talk]]) 09:07, 20 December 2025 (UTC)
::::''Happy to help!''&nbsp;'''''[[User:Paine Ellsworth|<span style="font-size:100%;color:darkblue;font-family:Segoe Script">Paine</span>]]'''''&nbsp;&nbsp;<small>19:18, 20 December 2025 (UTC)</small>

Latest revision as of 16:57, 26 December 2025

Template:Module rating

Implements {{High-use}}. Uses bot-updated values from subpages of Module:Transclusion_count/data/ when available.

Usage

Template:Mlx

  • number of transclusions: The first parameter is either a static number of times the template has been transcluded, or the word "risk" (without quotes) to display "a very large number of" instead of the actual value. This value will be ignored if transclusion data is available for the current page.
  • discussion page, or use + notation: The second parameter is overloaded. It will cause the number of transclusions to display as "#,###+" instead of "approximately #,###" when set equal to "yes" (without quotes). When used in this manner, values will be rounded down, instead of rounded to the nearest number with the appropriate number of significant figures. When set to any other non-blank value, it will replace the link to the template's talk page to the value of the parameter (for example, 2=WP:VPT will insert a link to WP:VPT),
  • |info=extra information: When set to non-blank, will insert extra information into the template text if the template has more than 100,000 transclusions or parameter 1 is set to "risk".
  • |demo=Template_name: Will use the transclusion count for the template at Template:Template_name instead of detecting what template it is being used on. Capitalization must exactly match the value used in Special:PrefixIndex/Module:Transclusion_count/data/.
  • |form=: When set to "editnotice", will display the message using {{editnotice}} instead of {{ombox}}.
  • |expiry=: Sets the |expiry= parameter for {{editnotice}}.
  • |system=in system messages: if set, this module looks like {{Used in system}}. Use that template directly as it performs some checks.
  • |fetch=: if set to false, the module will not attempt to fetch transclusion counts using Module:Transclusion count

Other functions

num
Produces the text and and link to toolforge surrounding the amount of transclusions.
risk
With this function, if risk is passed into the first unnamed parameter, or there are more than 100k transclusions, this will return risk.
text
Returns the body text of this template, with nil or a number of transclusions.

require('strict')

local p = {}
local getArgs = require('Module:Arguments').getArgs

local _fetch = require('Module:Transclusion_count')._fetch -- _fetch looks at the 'demo' argument
local yesno = require('Module:Yesno')

local lang_obj = mw.getContentLanguage() -- this here because the language object is used multiple places in the module
local large_count_cutoff = 100000
local approx_num_total_pages = 63000000

local user_subpage_info_page = 'Wikipedia:User pages#SUB'
local sandbox_module_page = 'Module:Sandbox'
local system_messages_cat = 'Pages used in system messages needing protection'
local sandbox_word = 'sandbox'
local testcases_word = 'testcases'
local doc_word = 'doc'

local function count_from_args(args)
	if tonumber(args.count) then -- check if function has already been used
		return tonumber(args.count) -- early exit if so
	end
	
	local count
	
	if yesno(args['fetch']) ~= false then
		count = _fetch(args) -- fetch transclusion count
	end
	
	-- use explicitly-provided count when fetch fails
	if count == nil and args[1] ~= nil and args[1] ~= '' then
		-- convert local language number string to a number understandable by Lua
		count = mw.ustring.gsub(args[1], '+$', '')
		count = lang_obj:parseFormattedNumber(args[1])
	end
	
	-- in case someone writes a non-positive number
	if count and count > 0 then
		return count
	end
	
	return nil
end

-- Actions if there is a large (greater than or equal to 100,000) transclusion count
local function risk_boolean(args)
	if args.risk == true or args.risk == false then
		return args.risk
	elseif args[1]  == 'risk' then
		return true
	else
		local count = count_from_args(args)
		if count and count >= large_count_cutoff then
			return true
		end
	end
	return false
end

-- function retained for backwards compatibility
function p._risk(args)
	return risk_boolean(args) and 'risk' or ''
end

-- function retained for backwards compatibility
function p.risk(frame)
	return p._risk(getArgs(frame))
end

-- count and no_percent arguments retained for backwards compatibility
function p._num(args, count, no_percent)
	if count == nil then
		count = count_from_args(args)
	end
	args.count = count
	args.risk = risk_boolean(args)
	
	-- Build output string
	local return_value = ''
	if args.count == nil and args.risk then
		return 'a very large number of'
	elseif args.count == nil then
		return 'many'
	else
		-- Use 2 significant figures for smaller numbers and 3 for larger ones
		local sigfig = 2
		if args.count >= large_count_cutoff then
			sigfig = 3
		end
		
		-- Prepare to round to appropriate number of sigfigs
		local f = math.floor(math.log10(args.count)) - sigfig + 1
		
		-- Round and insert 'approximately' or '+' when appropriate
		if yesno(args[2]) == true or (type(args[1]) == 'string' and (mw.ustring.sub(args[1], -1) == '+')) then
			-- Round down
			return_value = string.format('%s+', lang_obj:formatNum(math.floor( (args.count / 10^(f)) ) * (10^(f))) )
		else
			-- Round to nearest
			return_value = string.format('approximately&#x20;%s', lang_obj:formatNum(math.floor( (args.count / 10^(f)) + 0.5) * (10^(f))) )
		end
		
		-- Insert percentage of pages if that is likely to be >= 1% and when |no-percent= not set to yes
		no_percent = yesno(no_percent or args['no-percent'])
		if args.count and args.count >= approx_num_total_pages/100 and not no_percent then
			local num_total_pages = mw.getCurrentFrame():callParserFunction('NUMBEROFPAGES', 'R')
			local total_percent = math.floor( ( ( args.count/num_total_pages ) * 100) + 0.5)
			
			if total_percent >= 1 then
				return_value = string.format('%s&#x20;pages, or roughly %s%% of all', return_value, total_percent)
			end
		end	
	end
	
	return return_value
end

-- used by [[Template:Stub documentation]] and other pages
-- count argument retained for backwards compatibility
function p.num(frame, count)
	return p._num(getArgs(frame), count)
end

-- count argument retained for backwards compatibility
function p._text(args, count)
	--[=[
		Only show the information about how this template gets updated
		if someone is actually editing the page and maybe trying to update the count.
	]=]
	local bot_text = (mw.getCurrentFrame():preprocess('{{REVISIONID}}') == '') and ("\n\n----\n'''Preview message''':" .. ' Transclusion count updated automatically ([[Template:High-use/doc#Technical details|see documentation]]).') or ''
	
	if count == nil then
		count = count_from_args(args)
	end
	args.count = count
	args.risk = risk_boolean(args)
	
	-- trim /doc, /sandbox and /testcases
	local title = args.title or (args.demo and args.demo ~= '' and mw.title.new(args.demo, 'Template')) or mw.title.getCurrentTitle()
	if title.subpageText == doc_word or title.subpageText == sandbox_word or title.subpageText == testcases_word then
		title = title.basePageTitle
	end
	
	-- use /testcases of base template
	local testcases_page = mw.title.new(title.prefixedText .. '/' .. testcases_word)
	-- exists is expensive
	while testcases_page.basePageTitle.isSubpage and not testcases_page.exists do
		testcases_page = mw.title.new(testcases_page.basePageTitle.basePageTitle.prefixedText .. '/' .. testcases_word)
	end
	
	local systemMessages = (args['system'] or '') ~= ''
	
	-- This retrieves the project URL automatically to simplify localization.
	local templateCount = ('on [https://linkcount.toolforge.org/?project=%s&page=%s#transclusions %s pages]'):format(
		title:fullUrl():gsub('//(.-)/.*', '%1'),
		mw.uri.encode(title.fullText), p._num(args))
	local used_on_text = "'''This " .. (title:inNamespace('Module') and 'Lua module' or 'template') .. ' is used '
	if systemMessages then
		used_on_text = used_on_text .. args['system'] ..
			((args.count and args.count > 2000) and ("''', and " .. templateCount) or ("'''"))
	else
		used_on_text = used_on_text .. templateCount .. "'''"
	end
	
	local sandbox_text = ('%s\'s [[%s/sandbox|/sandbox]] or [[%s|/testcases]] subpages, or in your own [[%s]]. '):format(
		title:inNamespace('Module') and 'module' or 'template',
		title.fullText,
		testcases_page.fullText,
		title:inNamespace('Module') and (sandbox_module_page .. '|module sandbox') or (user_subpage_info_page .. '|user subpage')
	)
	
	local infoArg = args['info'] ~= '' and args['info']
	if (systemMessages or args.risk) then
		local info = '.'
		if systemMessages then
			info = info .. '<br />Changes to it can cause immediate changes to the ' .. mw.site.namespaces.Project.name .. ' user interface.'
		end
		if infoArg then
			info = info .. '<br />' .. infoArg
		end
		sandbox_text = info .. '<br /> To avoid major disruption' ..
			(args.count and args.count >= large_count_cutoff and ' and server load' or '') .. -- should this use args.risk?
			', any changes should be tested in the ' .. sandbox_text ..
			'The tested changes can be added to this page in a single edit. '
	else
		sandbox_text = (infoArg and ('.<br />' .. infoArg .. ' C') or ' and c') ..
			'hanges may be widely noticed. Test changes in the ' .. sandbox_text
	end
	
	local discussion_text = systemMessages and 'Please discuss changes ' or 'Consider discussing changes '
	if args[2] ~= nil and args[2] ~= '' and yesno(args[2]) == nil then
		discussion_text = string.format('%sat [[%s]]', discussion_text, args[2])
	else
		discussion_text = string.format('%son the [[%s|talk page]]', discussion_text, title.talkPageTitle.fullText)
	end
	
	return used_on_text .. sandbox_text .. discussion_text .. ' before implementing them.' .. bot_text
end

-- used by [[Template:R from high-use template]]
-- count argument retained for backwards compatibility
function p.text(frame, count)
	return p._text(getArgs(frame), count)
end

-- nocat argument retained for backwards compatibility
function p._main(args, nocat)
	args.count = count_from_args(args)
	args.risk = risk_boolean(args)
	args.title = (args.demo and args.demo ~= '' and mw.title.new(args.demo, 'Template')) or mw.title.getCurrentTitle()
	
	local image = 'Ambox warning yellow.svg'
	local type_param = 'style'
	local epilogue = ''
	
	if args['system'] and args['system'] ~= '' then
		image = 'Ambox important.svg'
		type_param = 'content'
		if yesno(nocat or args['nocat']) ~= true and not args.title.isRedirect then
			local protection_action = (args.title:inNamespace('File') and 'upload') or 'edit'
			local protection_level = require('Module:Effective protection level')._main(protection_action, args.title.fullText)
			
			if protection_level ~= 'sysop' and protection_level ~= 'templateeditor' and protection_level ~= 'interfaceadmin' then
				epilogue = mw.getCurrentFrame():expandTemplate {
					title = 'sandbox other',
					args = {
						[2] = '[[Category:' .. system_messages_cat .. ']]'
					}
				}
			end
		end
	elseif args.risk then
		image = 'Ambox warning orange.svg'
		type_param = 'content'
	end
	
	image = '[[File:' .. image .. '|40px|alt=Warning|link=]]'
	if args['form'] == 'editnotice' then
		return mw.getCurrentFrame():expandTemplate{
				title = 'editnotice',
				args = {
						['image'] = image,
						['text'] = p._text(args),
						['expiry'] = (args['expiry'] or '')
				}
		} .. epilogue
	else
		return require('Module:Message box').main('ombox', {
			type = type_param,
			image = image,
			text = p._text(args),
			expiry = (args['expiry'] or '')
		}) .. epilogue
	end
end

function p.main(frame)
	return p._main(getArgs(frame))
end

return p