Module:Editnotice load
Appearance
This module is rated as beta, and is ready for widespread use. It is still new and should be used with some caution to ensure the results are as expected. |
This module depends on the following other modules: |
Description | This module is an advanced editnotice loader. |
---|---|
Author(s) | User:Awesome Aasim |
Code source | Editnotice load |
Status | Beta |
Dependencies | |
License | CC BY-SA |
This module is an advanced editnotice loader. WIP
An enhanced editnotice loader.
Features:
- Category editnotices
- Editnotices based on page ID
- Group notices by prefixes
Relevant pages:
- Template:Editnotice/notice
- MediaWiki:Noarticletext-nopermission
- MediaWiki:Protectedpagetext
- MediaWiki:Cascadeprotected
- Template:Editnotices/Group/Template:Editnotices
- MediaWiki:Titleblacklist-custom-editnotice
Documentation
Package items
Editnotice_load.editnotice(frame)
(function)- Gets the editnotice type
- Parameter:
frame
the preprocessing frame (table) - Returns: type the string corresponding to the type (string)
Editnotice_load.main(frame)
(function)- The main entry point for the editnotice loader
- Parameter:
frame
the preprocessing frame (table) - Returns: output the output of the module (string)
--- This module is an advanced editnotice loader.
--
-- WIP
-- @module Editnotice_load
-- @alias p
-- @require Module:Arguments
-- @require Module:Yesno
-- @require Module:Effective_protection_level
-- @author [[User:Awesome Aasim]]
-- @attribution [[wikipedia:Module:Editnotice load]]
-- @release beta
local p = {}
local getArgs = require('Module:Arguments').getArgs
local cfg = require("Module:Editnotice_load/config_loader")
local pseudoNs = mw.title.new(cfg.pseudo_ns_name)
local enTypes = cfg.editnotice_types
local enNames = cfg.editnotice_names
local protLevel = require("Module:Effective protection level")._main
local yn = require("Module:Yesno")
function fillStringWithArgs(text, valArray)
if not valArray then
return text
end
local function getVal(match)
match = tonumber(match)
return valArray[match] or ''
end
return mw.ustring.gsub(text, '$([1-9][0-9]*)', getVal) .. ''
end
local function detectParameters(text)
return text and mw.ustring.find(text, '$([1-9][0-9]*)') and true or false
end
--- Gets the notice content of any editnotice.
-- @function getNoticeContent
-- @param {table} frame the current frame
-- @param {table} title the title of the page
-- @param {table} args the processing args
-- @param {boolean} hide whether to hide the notice
-- @return {string} the contents of the editnotice
local function getNoticeContent(frame, title, args, hide)
if hide then return '' end
local t = mw.title.new(title)
if t == nil or t.id == 0 or not t.exists then
return ''
end
local result = frame:expandTemplate{ title = title, args = args }
result = mw.text.trim(result)
if result ~= '' and result ~= '-' then
return result
end
return ''
end
p.getNoticeContent = getNoticeContent
--- Builds a link to any editnotice
-- @function makeLink
-- @param {table} builder the main editnotice builder
-- @param {table} links the editnotice builder containing the links
-- @param {string} target the target of the editnotice
-- @param {string} text the text to use for displaying the editnotice
-- @param {string} contents the contents of the editnotice
local function makeLink(builder, links, target, text, contents)
local builderLinksNodeSame = builder == links
if (contents == '' or contents == nil) and not builderLinksNodeSame then
builder = links
builder = builder
:tag('li')
else
builder = builder:tag('span')
end
builder = builder
:addClass('editnotice-link')
:css('clear', 'both')
:css('margin', '0px 0.8em')
:css('padding', 0)
:css('line-height', '1em')
:css('font-size', '90%')
if not ((contents == '' or contents == nil) and not builderLinksNodeSame) then
builder = builder:css('float', 'right')
end
builder:wikitext(string.format('[[%s|%s]] ', target, text))
end
p.makeLink = makeLink
-- Displays any editnotice
-- @function displayEditnotice
-- @param {table} builder the main editnotice builder
-- @param {string} class the classes to add to the editnotice
-- @param {string} content the contents of the editnotice
local function displayEditnotice(builder, class, content)
if content ~= nil and content ~= '' then
return builder:tag('div')
:addClass(class)
:css('clear', 'both')
:css('width', '100%')
:wikitext(content)
end
end
p.displayEditnotice = displayEditnotice
-- Gets the editnotice type of any editnotice
-- @function getEditnoticeType
-- @param {table} title a title object for the editnotice
-- @return {string} the editnotice type
function getEditnoticeType(title)
if title.baseText == title.rootText then
return title.subpageText
else
return getEditnoticeType(title.basePageTitle)
end
end
p.getEditnoticeType = getEditnoticeType
-- Gets the page that the editnotice is stored
-- @function getEditnoticeMainPage
-- @param {table} currPage the page the editnotice is being displayed on
-- @param {table} editnoticeType the editnotice type
-- @return {string} the page which has the editnotice
function getEditnoticeMainPage(currPage, editnoticeType)
return mw.ustring.sub(currPage.fullText, mw.ustring.len(pseudoNs.fullText .. "/" .. editnoticeType .. "/") + 1) .. ""
end
p.getEditnoticeMainPage = getEditnoticeMainPage
-- Gets the page the editnotice belongs to
-- @function p.page
-- @param {table} the calling frame
-- @return {string} the page by which the editnotice belongs
function p.page(frame)
local args = getArgs(frame)
local currPage = args['title'] and mw.title.new(args['title']) or mw.title.getCurrentTitle()
local editnoticeType = p.editnotice(frame)
local titleName = mw.ustring.sub(currPage.fullText, mw.ustring.len(pseudoNs.fullText .. "/" .. enTypes[editnoticeType] .. "/") + 1) .. ""
if editnoticeType == "page" or editnoticeType == "protection_id" then
local page = mw.title.new(tonumber(titleName))
return page and page.fullText or ""
else
return enTypes[editnoticeType] ~= nil and titleName .. "" or ''
end
end
function key(title, var, name)
return title ~= nil and title ~= 0 and (var[name] or name) or nil
end
-- Gets any editnotice and its associated data
-- @function p.getEditnotice
-- @param {table} frame the processing frame
-- @param {table} noticeArgs the arguments to pass to the editnotice
-- @param {string} title the string for the page the editnotice belongs to
-- @param {string} type the editnotice type
-- @return {table} a table with the editnotice name and contents
function p.getEditnotice(frame, noticeArgs, title, type, hide)
--- return a table of values with the editnotice
local noticeName = pseudoNs.prefixedText .. "/" .. type .. "/" .. title
local noticeContent = getNoticeContent(frame, noticeName, noticeArgs, hide)
return {
["title"] = noticeName,
["content"] = noticeContent
}
end
-- Shows any editnotice
-- @function p.showEditnotice
-- @param {table} builder the builder for the editnotice
-- @param {table} links a container for all the links
-- @param {table} editnoticeData a table with editnotice data from p.getEditnotice
-- @param {string} editnoticeName the name of the editnotice
-- @param {string} editnoticeClass the class to add to the editnotice
function p.showEditnotice(builder, links, editnoticeData, editnoticeName, editnoticeClass)
makeLink(builder, links, editnoticeData.title, editnoticeName, editnoticeData.content)
displayEditnotice(builder, editnoticeClass, editnoticeData.content)
end
-- Generates only the contents for protection editnotices
-- @function p.protectionEditnotice
-- @param {table} frame the preprocessing frame
-- @return {string} builder the editnotice contents
function p.protectionEditnotice(frame)
local args = getArgs(frame)
local noticeAction = args['notice action']
local noticeArgs = {['notice action'] = noticeAction}
local currentTitle = args['title'] and mw.title.new(args['title']) or mw.title.getCurrentTitle()
local builder = mw.html.create('div')
:attr('id', 'editnotice-area')
:addClass('editnotice-area mw-parser-output')
:css('clear', 'both')
:css('width', '100%')
local protectionTitleNoticeData = p.getEditnotice(frame, noticeArgs, currentTitle.prefixedText, enTypes["protection"])
if protectionTitleNoticeData.content ~= "" then
p.showEditnotice(builder, builder, protectionTitleNoticeData, enNames["protection"], 'editnotice-protection-title')
end
local protectionNoticeData = p.getEditnotice(frame, noticeArgs, currentTitle.id .. '', enTypes["protection_id"])
if protectionNoticeData.content ~= "" then
p.showEditnotice(builder, builder, protectionNoticeData, enNames["protection_id"], 'editnotice-protection')
end
builder:tag('div')
:css('clear', 'both')
if protectionNoticeData.content == "" and protectionTitleNoticeData.content == "" then
return ""
end
return builder
end
--- Gets the editnotice type
-- @function p.editnotice
-- @param {table} frame the preprocessing frame
-- @return {string} type the string corresponding to the type
function p.editnotice(frame)
local args = getArgs(frame)
local currPage = args['title'] and mw.title.new(args['title']) or mw.title.getCurrentTitle()
if currPage.rootText == pseudoNs.text and currPage.nsText == pseudoNs.nsText then
local editNoticeType = getEditnoticeType(currPage)
local title = mw.title.new(getEditnoticeMainPage(currPage, editNoticeType))
if editNoticeType == enTypes["protection"] then
return key(title, args, "protection") or args["#default"] or ''
elseif editNoticeType == enTypes["protection_id"] then
title = mw.title.new(tonumber(getEditnoticeMainPage(currPage, editNoticeType)) or 0)
return key(title, args, "protection_id") or args["#default"] or ''
elseif editNoticeType == enTypes["title"] then
return key(title, args, "title") or args["#default"] or ''
elseif editNoticeType == enTypes["page"] then
title = mw.title.new(tonumber(getEditnoticeMainPage(currPage, editNoticeType)) or 0)
return key(title, args, "page") or args["#default"] or ''
elseif editNoticeType == enTypes["group"] then
return key(title, args, "group") or args["#default"] or ''
elseif editNoticeType == enTypes["category"] then
return key(title, args, "category") or args["#default"] or ''
elseif editNoticeType == enTypes["namespace"] then
return key(title, args, "namespace") or args["#default"] or ''
else
return args["#default"] or ''
end
end
end
--- The main entry point for the editnotice loader
-- @function p.main
-- @param {table} frame the preprocessing frame
-- @return {string} output the output of the module
function p.main(frame)
local args = getArgs(frame)
local noticeAction = args['notice action']
local noticeArgs = {['notice action'] = noticeAction}
local noText = yn(args['notext']) or false
local currentTitle = args['title'] and mw.title.new(args['title']) or mw.title.getCurrentTitle()
local builder = mw.html.create('div')
:attr('id', 'editnotice-area')
:addClass('editnotice-area mw-parser-output')
:css('clear', 'both')
:css('width', '100%')
local hide = noText
if noText then
local editNoticePage = mw.title.new("MediaWiki:Editnotice-" .. tostring(currentTitle.namespace))
if not editNoticePage.exists then
builder
:tag("span")
:addClass("sysop-show")
:tag("strong")
:addClass("error")
:wikitext(frame:preprocess(fillStringWithArgs(cfg.noEditnoticePage, {'[[' .. editNoticePage.fullText .. ']]', '<code><nowiki>{{</nowiki>#invoke:[[Module:Editnotice load|editnotice load]]|main<nowiki>}}</nowiki></code>'})))
hide = false
end
end
local links = builder:tag("table")
:addClass('wikitable editnotice-links mw-collapsible mw-collapsed')
:addClass(cfg.editnotice_classes)
:css("width", "100%")
:tag("tr")
:tag("th")
:wikitext(cfg.links):done():done()
:tag("td")
:tag("ul")
:attr("id", "editnotice-links")
:css("display", "block")
:addClass('hlist')
local editnotices = ''
if noticeAction ~= 'view' and noticeAction ~= 'protect' then
local namespace = currentTitle.nsText
if namespace == '' then namespace = (cfg.mainspace or mw.site.namespaces[0].displayName) end
local nsNoticeData = p.getEditnotice(frame, noticeArgs, namespace, enTypes["namespace"], hide)
p.showEditnotice(builder, links, nsNoticeData, enNames["namespace"], 'editnotice-namespace')
editnotices = editnotices .. nsNoticeData.content
end
if protLevel("edit", currentTitle.fullText) or
protLevel("move", currentTitle.fullText) or
protLevel("create", currentTitle.fullText) or
protLevel("upload", currentTitle.fullText) then
local protectionTitleNoticeData = p.getEditnotice(frame, noticeArgs, currentTitle.prefixedText, enTypes["protection"], hide)
if noticeAction ~= "protect" then protectionTitleNoticeData.content = "" end
p.showEditnotice(builder, links, protectionTitleNoticeData, enNames["protection"], 'editnotice-protection-title')
editnotices = editnotices .. protectionTitleNoticeData.content
if currentTitle.id ~= 0 then
local protectionNoticeData = p.getEditnotice(frame, noticeArgs, currentTitle.id .. '', enTypes["protection_id"], hide)
if noticeAction ~= "protect" then protectionNoticeData.content = "" end
p.showEditnotice(builder, links, protectionNoticeData, enNames["protection_id"], 'editnotice-protection')
editnotices = editnotices .. protectionNoticeData.content
end
end
if mw.site.namespaces[currentTitle.namespace].hasSubpages then
local splitTitle = mw.text.split(currentTitle.prefixedText, "/")
local groupTitle = ''
for k,v in ipairs(splitTitle) do
groupTitle = groupTitle .. v
local groupNoticeData = p.getEditnotice(frame, noticeArgs, groupTitle, enTypes["group"], hide)
p.showEditnotice(builder, links, groupNoticeData, enNames["group"] .. " (" .. groupTitle .. ")", "editnotice-group")
editnotices = editnotices .. groupNoticeData.content
groupTitle = groupTitle .. '/'
end
end
if cfg.user_editnotice ~= nil and ((currentTitle:hasSubjectNamespace(2) or currentTitle:hasSubjectNamespace(3)) and not currentTitle.isSubpage) then
--- display user page notice
local userPageNoticeName = currentTitle.prefixedText .. '/' .. cfg.user_editnotice
local userPageNoticeContent = getNoticeContent(frame, userPageNoticeName, noticeArgs, hide)
makeLink(builder, builder, userPageNoticeName, enNames["user"], userPageNoticeContent)
displayEditnotice(builder, 'usernotice-page', userPageNoticeContent)
editnotices = editnotices .. userPageNoticeContent
end
local titleNoticeData = p.getEditnotice(frame, noticeArgs, currentTitle.prefixedText, enTypes["title"], hide)
p.showEditnotice(builder, links, titleNoticeData, enNames["title"], "editnotice-title")
editnotices = editnotices .. titleNoticeData.content
if currentTitle.id ~= 0 then
local pageNoticeData = p.getEditnotice(frame, noticeArgs, currentTitle.prefixedText, enTypes["page"], hide)
p.showEditnotice(builder, links, pageNoticeData, enNames["page"], "editnotice-page")
editnotices = editnotices .. pageNoticeData.content
end
local categories = currentTitle.categories or {}
mw.logObject(categories)
for k,v in ipairs(categories) do
local categoryNoticeData = p.getEditnotice(frame, noticeArgs, v, enTypes["category"], hide)
p.showEditnotice(builder, links, categoryNoticeData, enNames["category"] .. " (" .. v .. ")", "editnotice-page")
editnotices = editnotices .. categoryNoticeData.content
end
if editnotices == '' and not noText then return '' end
builder:tag('div')
:css('clear', 'both')
local success, templateStyles = pcall(function(frame)
return frame:callParserFunction('#tag:templatestyles', {'', src = cfg.templateStyles})
end, frame)
if not success then return builder end
return tostring( builder ) .. templateStyles
end
p.cfg = cfg
return p