Module:Protected edit request/active
Appearance
From Wikipedia, the free encyclopedia
This module depends on the following other modules:
This module is rated as ready for general use. It has reached a mature state, is considered relatively stable and bug-free, and may be used wherever appropriate. It can be mentioned on help pages and other Wikipedia resources as an option for new users. To minimise server load and avoid disruptive output, improvements should be developed through sandbox testing rather than repeated trial-and-error editing.
Page semi-protected Editing of this module by new or unregistered users is currently disabled.
See the protection policy and protection log for more details. If you cannot edit this module and you wish to make a change, you can submit an edit request , discuss changes on the talk page, request unprotection, log in, or create an account.
See the protection policy and protection log for more details. If you cannot edit this module and you wish to make a change, you can submit an edit request , discuss changes on the talk page, request unprotection, log in, or create an account.
This module is used internally by Module:Protected edit request and is not useful elsewhere.
The above documentation is transcluded from Module:Protected edit request/active/doc. (edit | history)
Editors can experiment in this module's sandbox (edit | diff) and testcases (create) pages.
Subpages of this module.
Editors can experiment in this module's sandbox (edit | diff) and testcases (create) pages.
Subpages of this module.
require('strict') localyesno,makeMessageBox-- passed in from Module:Protected edit request localmakeToolbar=require('Module:Toolbar')._main localgetPagetype=require('Module:Pagetype')._main localeffectiveProtectionLevel=require('Module:Effective protection level')._main ---------------------------------------------------------------------- -- Helper functions ---------------------------------------------------------------------- localfunctionmakeWikilink(page,display) ifdisplaythen returnmw.ustring.format('[[%s|%s]]',page,display) else returnmw.ustring.format('[[%s]]',page) end end ---------------------------------------------------------------------- -- Title class ---------------------------------------------------------------------- -- This is basically the mw.title class with some extras thrown in. localtitle={} title.__index=title functiontitle.getProtectionLevelText(protectionLevel) -- Gets the text to use in anchors and urn links. locallevels={unprotected='editunprotected',autoconfirmed='editsemiprotected',extendedconfirmed='editextendedprotected',templateeditor='edittemplateprotected',sysop='editprotected',interfaceadmin='editinterfaceprotected'} returnlevels[protectionLevel] end functiontitle.new(...) localsuccess,obj=pcall(mw.title.new,...) ifnot(successandobj)thenreturnend title.init(obj) returnobj end functiontitle.init(obj) -- Add a protectionLevel property. obj.protectionLevel=effectiveProtectionLevel(obj.existsand'edit'or'create',obj) ifobj.protectionLevel=='*'then -- Make unprotected pages return "unprotected". obj.protectionLevel='unprotected' elseifobj.protectionLevel=='user'then -- If we just need to be registered, pretend we need to be autoconfirmed, since it's the closest thing we have. obj.protectionLevel='autoconfirmed' end -- Add a pagetype property. obj.pagetype=getPagetype{page=obj.prefixedText,defaultns='all'} -- Add link-making methods. functionobj:makeUrlLink(query,display) returnmw.ustring.format('[%s %s]',self:fullUrl(query),display) end functionobj:makeViewLink(display) returnself:makeUrlLink({redirect='no'},display) end functionobj:makeEditLink(display) returnself:makeUrlLink({action='edit'},display) end functionobj:makeHistoryLink(display) returnself:makeUrlLink({action='history'},display) end functionobj:makeLastEditLink(display) returnself:makeUrlLink({diff='cur',oldid='prev'},display) end functionobj:makeWhatLinksHereLink(display) returnmakeWikilink('Special:WhatLinksHere/'..self.prefixedText,display) end functionobj:makeCompareLink(otherTitle,display) display=displayor'diff' localcomparePagesTitle=title.new('Special:ComparePages') returncomparePagesTitle:makeUrlLink({page1=self.prefixedText,page2=otherTitle.prefixedText},display) end functionobj:makeLogLink(logType,display) locallogTitle=title.new('Special:Log') returnlogTitle:makeUrlLink({type=logType,page=self.prefixedText},display) end functionobj:urlEncode() returnmw.uri.encode(self.prefixedText,'WIKI') end functionobj:makeUrnLink(boxProtectionLevel) -- Outputs a urn link. The protection level is taken from the template, rather than detected from page itself, -- as the detection may be inaccurate for cascade-protected and title-blacklisted pages as of Nov 2013. localprotectionLinkText=title.getProtectionLevelText(boxProtectionLevel) returnmw.ustring.format('[urn:x-wp-%s:%s <span></span>]',protectionLinkText,self:urlEncode()) end -- Get a subpage title object, but go through pcall rather than use the unprotected mw.title:subPageTitle. functionobj:getSubpageTitle(subpage) returntitle.new(self.prefixedText..'/'..subpage) end functionobj:getSandboxTitle() ifself.isSubpageandself.contentModel=='sanitized-css'then localsuccess2,obj2=pcall(mw.title.makeTitle,self.namespace,self.baseText..'/sandbox/'..self.subpageText) ifsuccess2andobj2then title.init(obj2) returnobj2 end end returnself:getSubpageTitle('sandbox') end end ---------------------------------------------------------------------- -- TitleTable class ---------------------------------------------------------------------- localtitleTable={} titleTable.__index=titleTable functiontitleTable.new(args) -- Get numerical arguments and make title objects for each of them. localnums={} fork,vinpairs(args)do iftype(k)=='number'then table.insert(nums,k) end end table.sort(nums) localtitles={} for_,numinipairs(nums)do localtitle=title.new(args[num]) table.insert(titles,title) end -- Get the current title, and get the subject title if no titles were specified. titles.currentTitle=mw.title.getCurrentTitle() if#titles<1then localsubjectNs=titles.currentTitle.subjectNsText ifsubjectNs~=''then subjectNs=subjectNs..':' end table.insert(titles,title.new(subjectNs..titles.currentTitle.text)) end -- Set the metatable. setmetatable(titles,titleTable) returntitles end functiontitleTable:memoize(memoField,func,...) ifself[memoField]~=nilthen returnself[memoField] else self[memoField]=func(...) returnself[memoField] end end functiontitleTable:titleIterator() locali=0 localn=#self returnfunction() i=i+1 ifi<=nthen returnself[i] end end end functiontitleTable:hasSameProperty(memoField,getPropertyFunc) -- If the titles table has more than one title in it, check if they have the same property. -- The property is found using the getPropertyFunc function, which takes a title object as its single argument. localfunctionhasSameProperty(getPropertyFunc) localproperty fori,objinipairs(self)do ifi==1then property=getPropertyFunc(obj) elseifgetPropertyFunc(obj)~=propertythen returnfalse end end returntrue end returnself:memoize(memoField,hasSameProperty,getPropertyFunc) end functiontitleTable:hasSameExistenceStatus() -- Returns true if all the titles exist, or if they all don't exist. Returns false if there is a mixture of existence statuses. returnself:hasSameProperty('sameExistenceStatus',function(title)returntitle.existsend) end functiontitleTable:hasSameProtectionStatus() -- Checks if all the titles have the same protection status (either for creation protection or for edit-protection - the two are not mixed). localsameExistenceStatus=self:hasSameExistenceStatus() ifsameExistenceStatusthen returnself:hasSameProperty('sameProtectionStatus',function(title)returntitle.protectionLevelend) else returnsameExistenceStatus end end functiontitleTable:hasSamePagetype() -- Checks if all the titles have the same pagetype. returnself:hasSameProperty('samePagetype',function(title)returntitle.pagetypeend) end functiontitleTable:propertyExists(memoField,getPropertyFunc) -- Checks if a title with a certain property exists. -- The property is found using the getPropertyFunc function, which takes a title object as its single argument -- and should return a boolean value. localfunctionpropertyExists(getPropertyFunc) fortitleObjinself:titleIterator()do ifgetPropertyFunc(titleObj)then returntrue end end returnfalse end returnself:memoize(memoField,propertyExists,getPropertyFunc) end functiontitleTable:hasNonInterfacePage() returnself:propertyExists('nonInterfacePage',function(titleObj)returntitleObj.namespace~=8end) end functiontitleTable:hasTemplateOrModule() returnself:propertyExists('templateOrModule',function(titleObj)returntitleObj.namespace==10ortitleObj.namespace==828end) end functiontitleTable:hasNonTemplateOrModule() returnself:propertyExists('nontemplateormodule',function(titleobj)returntitleobj.namespace~=10andtitleobj.namespace~=828end) end functiontitleTable:hasOtherProtectionLevel(level) fortitleObjinself:titleIterator()do iftitleObj.protectionLevel~=levelthen returntrue end end returnfalse end functiontitleTable:getProtectionLevels() localfunctiongetProtectionLevels() locallevels={} fortitleObjinself:titleIterator()do locallevel=titleObj.protectionLevel levels[level]=true end returnlevels end returnself:memoize('protectionLevels',getProtectionLevels) end ---------------------------------------------------------------------- -- Blurb class definition ---------------------------------------------------------------------- localblurb={} blurb.__index=blurb functionblurb.new(titleTable,boxProtectionLevel) localobj={} obj.titles=titleTable obj.boxProtectionLevel=boxProtectionLevel obj.linkCount=0-- Counter for the number of total items in the object's link lists. setmetatable(obj,blurb) returnobj end -- Static methods -- functionblurb.makeParaText(name,val) localpipe=mw.text.nowiki('|') localequals=mw.text.nowiki('=') val=valand("''"..val.."''")or'' returnmw.ustring.format('<code style="white-space: nowrap;">%s%s%s%s</code>',pipe,name,equals,val) end functionblurb.makeTemplateLink(s) returnmw.ustring.format('%s[[Template:%s|%s]]%s',mw.text.nowiki('{{'),s,s,mw.text.nowiki('}}')) end functionblurb:makeProtectionText() localboxProtectionLevel=self.boxProtectionLevel locallevels={['*']='unprotected',autoconfirmed='semi-protected',extendedconfirmed='extended-confirmed-protected',templateeditor='template-protected',sysop='fully protected',interfaceadmin='interface-protected'} forlevel,protectionTextinpairs(levels)do iflevel==boxProtectionLevelthen returnmw.ustring.format('[[Help:Protection|%s]]',protectionText) end end error('Unknown protection level '..boxProtectionLevel) end functionblurb.getPagetypePlural(title) localpagetype=title.pagetype ifpagetype=='category'then return'categories' else returnpagetype..'s' end end -- Normal methods -- functionblurb:makeLinkList(title) localtbargs={}-- The argument list to pass to Module:Toolbar tbargs.style='font-size: smaller;' tbargs.separator='dot' -- Page links. table.insert(tbargs,title:makeEditLink('edit')) table.insert(tbargs,title:makeHistoryLink('history')) table.insert(tbargs,title:makeLastEditLink('last')) table.insert(tbargs,title:makeWhatLinksHereLink('links')) -- Sandbox links. localsandboxTitle=title:getSandboxTitle() ifsandboxTitleandsandboxTitle.existsthen table.insert(tbargs,sandboxTitle:makeViewLink('sandbox')) table.insert(tbargs,sandboxTitle:makeEditLink('edit sandbox')) table.insert(tbargs,sandboxTitle:makeHistoryLink('sandbox history')) table.insert(tbargs,sandboxTitle:makeLastEditLink('sandbox last edit')) table.insert(tbargs,title:makeCompareLink(sandboxTitle,'sandbox diff')) end -- Test cases links. localtestcasesTitle=title:getSubpageTitle('testcases') iftestcasesTitleandtestcasesTitle.existsthen table.insert(tbargs,testcasesTitle:makeViewLink('test cases')) end -- Transclusion count link. iftitle.namespace==10ortitle.namespace==828then-- Only add the transclusion count link for templates and modules. localtclink=mw.uri.new{ host='templatecount.toolforge.org', path='/index.php', query={ lang='en', name=title.text, namespace=title.namespace, }, fragment='bottom' } tclink=string.format('[%s transclusion count]',tostring(tclink)) table.insert(tbargs,tclink) end -- Protection log link. iftitle.namespace~=8then-- MediaWiki pages don't have protection log entries. table.insert(tbargs,title:makeLogLink('protect','protection log')) end self.linkCount=self.linkCount+#tbargs-- Keep track of the number of total links created by the object. returnmakeToolbar(tbargs) end functionblurb:makeLinkLists() localtitles=self.titles if#titles==1then returnself:makeLinkList(titles[1]) else localret={} table.insert(ret,'<ul>') fori,titleObjinipairs(titles)do table.insert(ret,mw.ustring.format('<li>%s %s</li>',titleObj:makeViewLink(titleObj.prefixedText),self:makeLinkList(titleObj))) end table.insert(ret,'</ul>') returntable.concat(ret) end end functionblurb:makeIntro() localtitles=self.titles localrequested='It is [[Wikipedia:Edit requests|requested]] that' localprotectionText iftitles:hasNonInterfacePage()then protectionText=' '..self:makeProtectionText() else protectionText=''-- Interface pages cannot be unprotected, so we don't need to explicitly say they are protected. end -- Deal with cases where we are passed multiple titles. if#titles>1then localpagetype iftitles:hasSamePagetype()then pagetype=blurb.getPagetypePlural(titles[1]) else pagetype='pages' end returnmw.ustring.format("'''%s edits be made to the following%s %s''':",requested,protectionText,pagetype) end -- Deal with cases where we are passed only one title. localtitle=titles[1] localstringToFormat iftitle.existsthen stringToFormat='%s an edit be made to the%s %s at %s.' else stringToFormat='%s the%s %s at %s be created.' end stringToFormat="'''"..stringToFormat.."'''" returnmw.ustring.format(stringToFormat,requested,protectionText,title.pagetype,title:makeViewLink(title.prefixedText)) end functionblurb:makeBody() localtitles=self.titles localprotectionLevels=titles:getProtectionLevels() localboxProtectionLevel=self.boxProtectionLevel localhasNonInterfacePage=titles:hasNonInterfacePage() localisPlural=false if#titles>1then isPlural=true end localdescriptionText="This template must be followed by a '''complete and specific description''' of the request, " ifboxProtectionLevel=='sysop'orboxProtectionLevel=='templateeditor'then localeditText='edit' ifisPluralthen editText=editText..'s' end localdescriptionCompleteText=mw.ustring.format('so that an editor unfamiliar with the subject matter could complete the requested %s immediately.',editText) descriptionText=descriptionText..descriptionCompleteText else descriptionText=descriptionText..'that is, specify what text should be removed and a verbatim copy of the text that should replace it. ' ..[["Please change ''X''" is <strong>not acceptable</strong> and will be rejected; the request <strong>must</strong> be of the form "please change ''X'' to ''Y''".]] end localsmallText='' ifboxProtectionLevel=='sysop'orboxProtectionLevel=='templateeditor'then localtemplateFullText ifboxProtectionLevel=='sysop'then templateFullText='fully protected' elseifboxProtectionLevel=='templateeditor'then templateFullText='template-protected' end smallText='Edit requests to '..templateFullText.." pages should only be used for edits that are either <strong>uncontroversial</strong> or supported by [[Wikipedia:Consensus|consensus]]." .." If the proposed edit might be controversial, discuss it on the protected page's talk page <strong>before</strong> using this template." else localuserText localresponseTemplate ifboxProtectionLevel=='extendedconfirmed'then userText='[[Wikipedia:User access levels#Extended confirmed users|extended confirmed]] user' responseTemplate=blurb.makeTemplateLink('EEp') elseifboxProtectionLevel=='autoconfirmed'then userText='[[Wikipedia:User access levels#Autoconfirmed|autoconfirmed]] user' responseTemplate=blurb.makeTemplateLink('ESp') elseifboxProtectionLevel=='interfaceadmin'then userText='[[Wikipedia:User access levels#Interface administrators|interface administrator]]' responseTemplate=blurb.makeTemplateLink('EIp') else userText='user' responseTemplate=blurb.makeTemplateLink('ESp') end localansweredPara=blurb.makeParaText('answered','no') localstringToFormat='The edit may be made by any %s. ' ..[[Remember to change the %s parameter to "'''yes'''" when the request has been accepted, rejected or on hold awaiting user input. ]] .."This is so that inactive or completed requests don't needlessly fill up the edit requests category. " ..'You may also wish to use the %s template in the response.' smallText=mw.ustring.format(stringToFormat,userText,answeredPara,responseTemplate) end ifnotisPluralthen localtitle=titles[1] iftitle.namespace==10ortitle.namespace==828then localsandboxTitle=title:getSubpageTitle('sandbox') ifsandboxTitleandsandboxTitle.existsthen smallText=smallText..' Consider making changes first to the ' ..sandboxTitle:makeViewLink(title.pagetype.."'s sandbox") localtestcasesTitle=title:getSubpageTitle('testcases') iftestcasesTitleandtestcasesTitle.existsthen smallText=smallText..' and '..testcasesTitle:makeViewLink('test them thoroughly here') end smallText=smallText..' before submitting an edit request.' end end end ifhasNonInterfacePagethen smallText=smallText..' To request that a page be protected or unprotected, make a [[Wikipedia:Requests for page protection|protection request]].' end ifboxProtectionLevel=='sysop'orboxProtectionLevel=='templateeditor'orboxProtectionLevel=='interfaceadmin'then smallText=smallText..' When the request has been completed or denied, please add the '..blurb.makeParaText('answered','yes')..' parameter to deactivate the template.' end returnmw.ustring.format('%s\n<p style="font-size:smaller; line-height:1.3em;">\n%s\n</p>',descriptionText,smallText) end functionblurb:export() localintro=self:makeIntro() locallinkLists=self:makeLinkLists() localbody=self:makeBody() -- Start long links lists on a new line. locallinkListSep=' ' ifself.linkCount>5then linkListSep='<br />' end returnmw.ustring.format('%s%s%s\n\n%s',intro,linkListSep,linkLists,body) end ---------------------------------------------------------------------- -- Subclass of Module:Protected edit request's box class for active boxes ---------------------------------------------------------------------- localbox={} box.__index=box functionbox.new(protectionType,args) -- In the inheritance system used here, an object's metatable is its class, and a class's metatable is its superclass localobj=getmetatable(box).new(protectionType,args) setmetatable(obj,box) localboxProtectionLevels={semi='autoconfirmed',extended='extendedconfirmed',template='templateeditor',full='sysop',interface='interfaceadmin'} obj.boxProtectionLevel=boxProtectionLevels[protectionType] obj.demo=yesno(args.demo) -- Set dependent objects. obj.titles=titleTable.new(args) ifnotyesno(args.force)andobj.titles:hasSameProperty('sameProtectionStatus',function(title)returntitle.protectionLevelend)andobj.titles[1].protectionLevel~='unprotected'then obj.boxProtectionLevel=obj.titles[1].protectionLevel end obj.blurb=blurb.new(obj.titles,obj.boxProtectionLevel) returnobj end functionbox:setImage() localtitles=self.titles localboxProtectionLevel=self.boxProtectionLevel localpadlock ifboxProtectionLevel=='sysop'then padlock='Full-protection-shackle.svg' elseifboxProtectionLevel=='interfaceadmin'then padlock='Interface-protection-shackle.svg ' elseifboxProtectionLevel=='templateeditor'then padlock='Template-protection-shackle.svg' elseifboxProtectionLevel=='autoconfirmed'then padlock='Semi-protection-shackle.svg' elseifboxProtectionLevel=='extendedconfirmed'then padlock='Extended-protection-shackle.svg' else padlock='Padlock-bronze-open.svg' end localstringToFormat='[[File:%s|%dpx|alt=|link=]]' localsmallPadlock=mw.ustring.format(stringToFormat,padlock,25) locallargePadlock=mw.ustring.format(stringToFormat,padlock,60) self:setArg('smallimage',smallPadlock) self:setArg('image',largePadlock) end functionbox:buildUrnLinks() localret={} localboxProtectionLevel=self.boxProtectionLevel fortitleObjinself.titles:titleIterator()do table.insert(ret,titleObj:makeUrnLink(boxProtectionLevel)) end returnmw.ustring.format('<span class="plainlinks" style="display:none">%s</span>',table.concat(ret)) end functionbox:setBlurbText() self:setArg('text',self.blurb:export()..self:buildUrnLinks()) end functionbox:exportRequestTmbox() self:setImage() self:setBlurbText() self:setArg('class','editrequest') self:setArg('id',title.getProtectionLevelText(self.boxProtectionLevel))-- for anchor. yes, this leads to multiple elements with the same ID. we should probably fix this at some point returnmakeMessageBox('tmbox',self.tmboxArgs) end functionbox:exportRequestCategories() localcats={} localboxProtectionLevel=self.boxProtectionLevel localfunctionaddCat(cat) table.insert(cats,mw.ustring.format('[[Category:%s]]',cat)) end localprotectionCats={ autoconfirmed='Wikipedia semi-protected edit requests', extendedconfirmed='Wikipedia extended-confirmed-protected edit requests', templateeditor='Wikipedia template-protected edit requests', sysop='Wikipedia fully protected edit requests', interfaceadmin='Wikipedia interface-protected edit requests' } addCat(protectionCats[boxProtectionLevel]) ifself.titles:hasOtherProtectionLevel(boxProtectionLevel)then addCat('Wikipedia edit requests possibly using incorrect templates') end returntable.concat(cats) end functionbox:export() localtitle=self.titles.currentTitle ifnottitle.isTalkPageandnotself.demoandnotyesno(self.args.skiptalk)then return'<span class="error">Error: Protected edit requests can only be made on the talk page.</span>[[Category:Non-talk pages with an edit request template]]' end localret={} table.insert(ret,self:exportRequestTmbox()) ifnotself.demothen table.insert(ret,self:exportRequestCategories()) end returntable.concat(ret) end ---------------------------------------------------------------------- -- Function exported to Module:Protected edit request ---------------------------------------------------------------------- returnfunction(superclass,yn,mb) yesno=yn makeMessageBox=mb returnsetmetatable(box,superclass) end