Module:Find templates in use
| This module is rated as beta. It is considered ready for widespread use, but as it is still relatively new, it should be applied with some caution to ensure results are as expected. |
| This module depends on the following other modules: |
| This module is required by Module:Get article date format |
Usage
This module will scrape a target page for the use of one or more named templates and, by default, return if the named templates were found to be in use.
Optional modifiers, accepting "yes" or "no" (uses Module:Yesno), allow for different search behaviors and return results.
{{#invoke:Find templates in use|main
| page = <!-- required; "Example" or "Draft:Example" -->
| templates = <!-- required; "Short description" or "Use British English#Use mdy dates" -->
| inactive = <!-- "yes" to override the default "no" -->
| nestled = <!-- "yes" to override the default "no" -->
| params = <!-- "yes" to override the default "no" -->
| all = <!-- "yes" to override the default "no" -->
}}
page and templates
Required: alarming messages will be returned if:
- a value is not provided for
|page= - the provided value is not an existing page
- the page has no content (after inactive content is discarded unless
|inactive=yesis set) - a value is not provided for
|templates=
|templates= may be a # delimited list of template names.
One template named and found
{{#invoke:Find templates in use|main
| page = Draft:Example
| templates = Short description
}}
{
["Short description"] = true
}
Three templates named and found
{{#invoke:Find templates in use|main
| page = Draft:Example
| templates = Short description#Hatnote#Replace
}}
{
["Hatnote"] = true,
["Replace"] = true,
["Short description"] = true
}
Three templates named but only one found
{{#invoke:Find templates in use|main
| page = Draft:Example
| templates = Short description#Hatsune#Necklace
}}
{
["Short description"] = true
}
inactive
By default this module will ignore templates that are rendered inactive by being:
- commented out:
<!--{{Example}}--> - tagged such that expansion is prevented, e.g.
{{Ex<nowiki/>ample}}
Set |inactive=yes to include these inactive templates in the results.
nestled
By default this module will ignore templates nestled in the parameters of other templates.
Set |nestled=yes to include nestled templates in the results.
Looking for {{lorem ipsum}}
{{#invoke:Find templates in use|main
| page = Draft:Example
| templates = Lorem ipsum
}}
{}
Finding {{lorem ipsum}}
{{#invoke:Find templates in use|main
| page = Draft:Example
| templates = Lorem ipsum
| nestled = yes
}}
{
["Lorem ipsum"] = true,
}
params
By default this module will return only the existence of the templates it is tasked to find.
Set |params=yes to include the parameter content of each named template found in the results.
{{#invoke:Find templates in use|main
| page = Draft:Example
| templates = Lorem ipsum
| nestled = yes
| params = yes
}}
{
["Lorem ipsum"] = {
"2",
"link=yes"
}
}
all
By default this module will return only the first named template found.
Set |all=yes to include all of each named template found.
Without params
{{#invoke:Find templates in use|main
| page = Draft:Example
| templates = Lorem ipsum
| nestled = yes
| all = yes
}}
{
["Lorem ipsum"] = 8
}
With params
{{#invoke:Find templates in use|main
| page = Draft:Example
| templates = Lorem ipsum
| nestled = yes
| params = yes
| all = yes
}}
{
["Lorem ipsum"] = {
{
"2",
"link=yes"
},
{
"1"
},
{
"2",
"link=no"
},
{
"1"
},
{
"2",
"link=no"
},
{
"1"
},
{
"2",
"link=no"
},
{
"1"
}
}
}
All params and uses of multiple nestled templates
{{#invoke:Find templates in use|main
| page = Draft:Example
| templates = Short description#Hatnote#Replace#Lorem ipsum
| nestled = yes
| params = yes
| all = yes
}}
{
["Hatnote"] = {
{
"This is an '''example draft''' created via the [[WP:Articles for creation|Articles for creation]] process."
}
},
["Lorem ipsum"] = {
{
"2",
"link=yes"
},
{
"1"
},
{
"2",
"link=no"
},
{
"1"
},
{
"2",
"link=no"
},
{
"1"
},
{
"2",
"link=no"
},
{
"1"
}
},
["Replace"] = {
{
"{{Lorem ipsum|2|link=yes}}",
".",
".<ref name=\"lipsum\">{{Lorem ipsum|1}}</ref>",
"count=1"
},
{
"{{Lorem ipsum|2|link=no}}",
"",
".<ref name=\"lipsum\">{{Lorem ipsum|1}}</ref>",
"count=1"
},
{
"{{Lorem ipsum|2|link=no}}",
"",
".<ref name=\"lipsum\">{{Lorem ipsum|1}}</ref>",
"count=1"
},
{
"{{Lorem ipsum|2|link=no}}",
"",
".<ref name=\"lipsum\">{{Lorem ipsum|1}}</ref>",
"count=1"
},
},
["Short description"] = {
{
"Example draft page"
}
}
}
Alarming messages
Alarming messages will be returned if:
- a
|page=is not supplied- the page has no content (includes not existing)
|inactive=no(default) and the page has no active content
- there are no
|templates=to search for
local CASE_INSENSITIVE_NOWIKI = '[Nn][Oo][Ww][Ii][Kk][Ii]'
local DEADZONE_TAGS = {
'[Pp][Rr][Ee]',
CASE_INSENSITIVE_NOWIKI,
'[Ss][Oo][Uu][Rr][Cc][Ee]',
'[Ss][Yy][Nn][Tt][Aa][Xx][Hh][Ii][Gg][Hh][Ll][Ii][Gg][Hh][Tt]'
}
local function _isEmpty(value) return value == nil or value == '' end
local function _notEmpty(value) return not _isEmpty(value) end
-- Unescape functionality grabbed from https://stackoverflow.com/a/14899740/1832568
local function _unescape(str)
str = mw.ustring.gsub(str, '&#(%d+);', string.char)
str = mw.ustring.gsub(str, '&#x(%d+);', function(d) return string.char(tonumber(d, 16)) end)
return str
end
local function _hashDelimitedListIterator(list_string)
return mw.text.gsplit(_unescape(list_string), '%s-#%s-')
end
local function _alarmingMessage(message)
return '<span class="error">[[Module:Find templates in use]] '..message..'.</span>'
-- TODO ..'[[Category:Pages displaying alarming messages about Module:Find templates in use]]'
end
-- "template name" --> "[Tt]emplate[ _]+name"
local function _patternizeTemplateName(template_name)
local first_char = mw.ustring.sub(template_name, 1, 1)
return '['..mw.ustring.upper(first_char)..mw.ustring.lower(first_char)..
']'..mw.ustring.gsub(mw.ustring.sub(template_name, 2), '[ _]+', '[ _]+')
end
local function _onlyActiveContent(page_content)
page_content = mw.ustring.gsub(page_content, '<!%-%-.-%-%->', '')
for _, dz_tag in pairs(DEADZONE_TAGS) do
page_content = mw.ustring.gsub(page_content, '<'..dz_tag..'[^>]-%b></%s-'..dz_tag..'>', '')
end
return page_content
end
local function _notDeadzoneTag(template)
template = mw.ustring.lower(template)
for _, dz_tag in pairs(DEADZONE_TAGS) do
if mw.ustring.match(template, '^{{%s-#tag:%s-'..dz_tag..'%s-|') then
return false
end
end
return true
end
local function _getAllDoubleBracedBlocks(content, include_inactive, include_nestled, all_DBB)
all_DBB = all_DBB or {}
for template in content:gmatch('{%b{}}') do
if include_inactive or _notDeadzoneTag(template) then
table.insert(all_DBB, template)
if include_nestled then
content = mw.ustring.match(template, '^{{%s-[^|]+%s-|%s-(.-)%s-}}$')
if _notEmpty(content) then
_getAllDoubleBracedBlocks(content, include_inactive, include_nestled, all_DBB)
end
end
end
end
return all_DBB
end
local function _getParams(DBB_params)
local params = {}
if DBB_params then
local current = {}
local nested = 0
local cha, chacha
for i = 1, #DBB_params do
cha = mw.ustring.sub(DBB_params, i, i)
chacha = mw.ustring.sub(DBB_params, i, i+1)
if chacha == "{{" or chacha == "[[" then
nested = nested + 1
elseif (chacha == "}}" or chacha == "]]") and nested > 0 then
nested = nested - 1
end
if cha == "|" and nested == 0 then
table.insert(params, table.concat(current))
current = {}
else
table.insert(current, cha)
end
end
if #current > 0 then
table.insert(params, table.concat(current))
end
end
return params
end
local function _getTemplates(page_content, template_names, include_inactive, include_nestled, get_params, all_in_use)
local templates = {}
local template_name_patterns = {}
local template_name_pattern,
all_DBB,
params
for template_name in _hashDelimitedListIterator(template_names) do
template_name_pattern = _patternizeTemplateName(template_name)
-- Filter out duplicate template_names
if not template_name_patterns[template_name_pattern] then
template_name_patterns[template_name_pattern] = true
-- Get all double braced blocks only once, and only if necessary
all_DBB = all_DBB or _getAllDoubleBracedBlocks(page_content, include_inactive, include_nestled)
for _, DBB in pairs(all_DBB) do
local DBB_name, DBB_params = mw.ustring.match(DBB, '^{{%s-([^|]+)%s-|%s-(.-)%s-}}$')
if not DBB_name then
DBB_name = mw.ustring.match(DBB, '^{{%s-(.-)%s-}}$')
end
if include_inactive then
DBB_name = mw.ustring.gsub(
mw.ustring.gsub(DBB_name, '<'..CASE_INSENSITIVE_NOWIKI..'%s-/>', ''),
'</%s-'..CASE_INSENSITIVE_NOWIKI..'>', ''
)
end
if mw.ustring.match(DBB_name, '^'..template_name_pattern..'$') then
if get_params then
params = _getParams(DBB_params)
if all_in_use then
if not templates[template_name] then
templates[template_name] = {}
end
table.insert(templates[template_name], params)
else
templates[template_name] = params
break
end
else
if all_in_use then
templates[template_name] = (templates[template_name] or 0) + 1
else
-- Allows for a more efficient return if the use count isn't needed,
-- while also making it possible to query the table i.e. table[key].
templates[template_name] = true
break
end
end
end
end
end
end
return templates
end
local function _main(args)
local template_names = args.templates
if _isEmpty(template_names) then
return _alarmingMessage('requires a |templates= value')
end
local page_name = args.page
if _isEmpty(page_name) then
return _alarmingMessage('requires a |page= value')
end
local title_table = mw.title.new(page_name)
if _isEmpty(title_table) then
return _alarmingMessage('could not get title_table for '..page_name)
end
local page_content = title_table:getContent()
if _isEmpty(page_content) then
return _alarmingMessage('found no content at '..page_name)
end
local _yesno = require('Module:Yesno')
local include_inactive = _yesno(args.inactive)
if not include_inactive then
page_content = _onlyActiveContent(page_content)
if _isEmpty(page_content) then
return _alarmingMessage('found no active content at '..page_name)
end
end
local include_nestled = _yesno(args.nestled)
local get_params = _yesno(args.params)
local all_in_use = _yesno(args.all)
return _getTemplates(page_content, template_names, include_inactive, include_nestled, get_params, all_in_use)
end
local p = {}
function p.main(frame)
local args = require('Module:Arguments').getArgs(frame)
if _isEmpty(args) then
return _alarmingMessage('could not getArgs') -- This really would be alarming.
end
return _main(args)
end
return p
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.