Jump to content
Wikipedia The Free Encyclopedia

Module:Sister project links

From Wikipedia, the free encyclopedia
Module documentation[view] [edit] [history] [purge]
Warning This Lua module is used on approximately 20,000 pages and changes may be widely noticed. Test changes in the module's /sandbox or /testcases subpages, or in your own module sandbox. Consider discussing changes on the talk page before implementing them.

Implements {{Sister project links }}

See {{Sister project links/testcases }} for test cases for box, {{Sister bar/testcases }} for bar.

Note: in order to make the test cases work, the Sandbox CSS classes have "-sand" appended to their names. If you wish to update the CSS, copy the contents of each class from Module:Sister project links/sandbox/styles.css to Module:Sister project links/styles.css, but do not alter the class names, nor just copy-paste the entire CSS file. For the current difference in CSS between Sandbox and Main, see here.

The above documentation is transcluded from Module:Sister project links/doc. (edit | history)
Editors can experiment in this module's sandbox (edit | diff) and testcases (edit) pages.
Subpages of this module.

 require('strict')

 -- Module to create sister project link box
 localgetArgs=require('Module:Arguments').getArgs
 localsideBox=require('Module:Side box')._main
 localp={}

 localinSandbox=mw.getCurrentFrame():getTitle():find('sandbox',1,true)

 -- Function to add "-sand" to classes when called from sandbox
 localfunctionsandbox(s)
 returninSandboxands.."-sand"ors
 end

 -- Information about how to handle each sister lives in separate data file
 localcfg=mw.loadData(sandbox('Module:Sister project links/config'))
 locallogo=cfg.logo
 localdarkOnLight=cfg.darkOnLight
 localPDicon=cfg.PDicon
 localprefixList=cfg.prefixList
 localsisterName=cfg.sisterName
 localsisterInfo=cfg.sisterInfo
 localdefaultSisters=cfg.defaultSisters
 localsisterDb=cfg.sisterDb
 localtrackingType=cfg.trackingType

 -- Function to canonicalize string
 -- search for variants of "yes", and "no", and transform
 -- them into a standard form (like [[Template:YesNo]])
 -- Argument:
 -- s --- input string
 -- Result:
 -- {x,y} list of length 2
 -- x = nil if s is canonicalized, otherwise has trimmed s
 -- y = canonical form of s (true if "yes" or other, false if "no", nil if blank)
 localfunctioncanonicalize(s)
 ifs==nilthen
 return{nil,nil}
 end
 -- if s is table/list, then assume already canonicalized and return unchanged
 iftostring(type(s))=="table"then
 returns
 end
 s=mw.text.trim(tostring(s))
 ifs==""then
 return{nil,nil}
 end
 locallowerS=s:lower()
 -- Check for various forms of "yes"
 iflowerS=='yes'orlowerS=='y'orlowerS=='t'
 orlowerS=='1'orlowerS=='true'orlowerS=='on'then
 return{nil,true}
 end
 -- Check for various forms of "no"
 iflowerS=='no'orlowerS=='n'orlowerS=='f'
 orlowerS=='0'orlowerS=='false'orlowerS=='off'then
 return{nil,false}
 end
 -- Neither yes nor no recognized, leave string trimmed
 return{s,true}
 end

 -- Merge two or more canonicalized argument lists
 -- Arguments:
 -- argList = list of canonicalized arguments
 -- noAll = if true, return no when all argList is no.
 -- otherwise, return blank when all argList is blank
 localfunctionmergeArgs(argList,noAll)
 localtest=nil-- default, return blank if all blank
 ifnoAllthen
 test=false-- return no if all no
 end
 localallSame=true
 -- Search through string for first non-no or non-blank
 for_,arginipairs(argList)do
 ifarg[2]then
 returnarg-- found non-no and non-blank, return it
 end
 -- test to see if argList is all blank / no
 allSame=allSameand(arg[2]==test)
 end
 -- if all blank / no, return blank / no
 ifallSamethen
 return{nil,test}-- all match no/blank, return it
 end
 -- otherwise, return no / blank
 ifnoAllthen
 return{nil,nil}
 end
 return{nil,false}
 end

 -- Function to determine whether to suppress link to icon
 -- Arguments:
 -- prefix = sister wiki prefix
 localfunctionsuppressLink(prefix)
 returnprefixandPDicon[prefix]and'|link='or''
 end

 -- Function to get sitelink for a wiki
 -- Arguments:
 -- wiki = db name of wiki to lookup
 -- qid = QID of entity to search for, current page entity by default
 localfunctiongetSitelink(wiki,qid)
 -- return nil if some sort of lookup failure
 returnqidandmw.wikibase.getSitelink(qid,wiki)
 end

 -- Function to get sitelink for a wiki
 -- Arguments:
 -- prefix = prefix string for wiki to lookup
 -- qid = QID of entity to search for, current page entity by default
 localfunctionfetchWikidata(prefix,qid)
 localsisterDbName=sisterDb[prefix]
 returnsisterDbNameandgetSitelink(sisterDbName,qid)
 end

 -- Function to generate the sister link itself
 -- Arguments:
 -- args = argument table for function
 -- args[1] = page to fetch
 -- args.default = link when blank
 -- args.auto = new auto mode (don't fall back to search)
 -- args.sitelink = wikidata sitelink (if available)
 -- args.qid = QID of entity
 -- args.search = fallback string to search for
 -- args.sisterPrefix = wikitext prefix for sister site
 -- args.information = type of info sister site contains
 -- tracking = tracking table
 localfunctiongenSisterLink(args,tracking)
 ifargs[1][2]==falseor(notargs.defaultandargs[1][2]==nil)then
 returnnil--- either editor specified "no", or "blank" (and default=no), then skip this sister
 end
 localsitelink=args.sitelinkorfetchWikidata(args.sisterPrefix,args.qid)
 ifargs.autoandnotsitelinkandargs[1][2]==nilthen
 returnnil--- in auto mode, if link is blank and no sitelink, then skip
 end
 -- fallback order of sister link: first specified page, then wikidata, then search
 locallink=args[1][1]orsitelinkor(args.searchand"Special:"..args.search)
 ifnotlinkthen
 returnnil--- no link found, just skip
 end
 iftrackingthen
 -- update state for tracking categories
 ifargs[1][1]andsitelinkthen
 -- transform supplied page name to be in wiki-format
 localpage=mw.ustring.gsub(args[1][1],"_"," ")
 page=mw.ustring.sub(page,1,1):upper()..mw.ustring.sub(page,2)
 localpageNS=mw.ustring.match(page,"^([^:]+):")
 localsitelinkNS=mw.ustring.match(sitelink,"^([^:]+):")
 ifpage==sitelinkthen
 tracking.wdHidden=args.sisterPrefix
 elseifpageNS~=sitelinkNSthen
 tracking.wdNamespace=args.sisterPrefix
 else
 tracking.wdMismatch=args.sisterPrefix
 end
 -- if no page link, nor a wikidata entry, and search is on, then warn
 elseifnot(args[1][2]orsitelink)andargs.searchthen
 tracking.defaultSearch=args.sisterPrefix
 end
 end
 return{prefix=args.sisterPrefix,link=link,logo=args.logo,class=args.class,
 name=args.name,information=args.information,prep=args.prep}
 end

 -- Function to handle special case of commons link
 localfunctioncommonsLinks(args,commonsPage)
 -- use [[Module:Commons link]] to determine best commons link
 localcommonsLink=require('Module:Commons link')
 localcLink=(notargs.commonscat)andcommonsLink._hasGallery(args.qid)
 orcommonsLink._hasCategory(args.qid)
 ifcommonsPage[1]andnotmw.ustring.match(commonsPage[1]:lower(),"^category:")then
 commonsPage[1]=(args.commonscatand"Category:"or"")..commonsPage[1]
 end
 localcommonsSearch="Search/"..(args.commonscatand"Category:"or"")..args[1]
 return{link=cLink,search=commonsSearch}
 end

 -- Function to handle special case for "author" and "cookbook"
 localfunctionhandleSubtype(args)
 localns=args.ns
 localns_len=mw.ustring.len(ns)
 localresult={}
 result.sitelink=fetchWikidata(args.prefix,args.qid)
 localsubtype=false
 ifargs.pagethen
 ifmw.ustring.sub(args.page,1,ns_len)==nsthen
 subtype=true
 elseifargs.subtypethen
 result.page=ns..args.page
 subtype=true
 end
 elseifresult.sitelinkthen
 subtype=mw.ustring.sub(result.sitelink,1,ns_len)==ns
 elseifargs.subtypethen
 result.search="Search/"..ns..args.default
 subtype=true
 end
 ifsubtypethen
 result.info=args.info
 end
 returnresult
 end

 -- Function to create a sister link, by prefix
 -- Arguments:
 -- prefix = sister prefix (e.g., "c" for commons)
 -- args = arguments for this sister (see p._sisterLink above)
 -- tracking = tracking table
 localfunctionsisterLink(prefix,args,tracking)
 -- determine arguments to genSisterLink according to prefix
 ifprefix=='species_author'andnotargs.species[1]andargs.species[2]andnotargs.species_author[1]andargs.species_author[2]then
 returnnil
 end
 localdefault=defaultSisters[prefix]
 ifdefault=='auto'then
 default=args.auto
 end
 -- Handle exceptions by prefix
 localsearch=((prefix=='d'and"ItemByTitle/enwiki/")or"Search/")..args[1]
 localsitelink=prefix=='d'andargs.qid
 localpage=args[prefix]
 localinfo=sisterInfo[prefix]
 -- special case handling of author and cookbook
 localsubtype=nil
 ifprefix=='s'then
 subtype=handleSubtype({prefix='s',qid=args.qid,subtype=args.author,page=page[1],
 ns='Author:',info=nil,default=args[1]})
 elseifprefix=='b'then
 subtype=handleSubtype({prefix='b',qid=args.qid,subtype=args.cookbook,page=page[1],
 ns='Cookbook:',info='Recipes',default=args[1]})
 end
 ifsubtypethen
 page[1]=subtype.pageorpage[1]
 search=subtype.searchorsearch
 sitelink=subtype.sitelinkorsitelink
 info=subtype.infoorinfo
 end
 ifprefix=='voy'then
 ifnotargs.barthen
 info="Travel information"
 end
 ifpage[1]then
 ifmw.ustring.match(page[1],"phrasebook")then
 info="Phrasebook"
 end
 elseifpage[2]orargs.autothen
 sitelink=sitelinkorfetchWikidata('voy',args.qid)
 ifsitelinkandmw.ustring.match(sitelink,"phrasebook")then
 info="Phrasebook"
 end
 end
 end
 info=args.informationorinfo
 ifprefix=='c'then
 localcommons=commonsLinks(args,page)
 search=commons.search
 sitelink=commons.link
 end
 prefix=(prefix=='species_author'and'species')orprefix
 locallogo=logo[prefix]
 localclass="noviewer"..(darkOnLight[prefix]and" skin-invert-image"or"")
 localname=sisterName[prefix]
 localprep="from"
 ifmw.ustring.sub(prefix,1,2)=='iw'then
 locallang=nil
 localiw_arg=args[prefix]
 ifiw_arg[1]then
 lang=iw_arg[1]
 elseifiw_arg[2]then
 localP424=mw.wikibase.getBestStatements(args.qid,"P424")[1]
 ifP424andP424.mainsnak.datavaluethen
 lang=P424.mainsnak.datavalue.value
 end
 end
 iflang==nilthen
 returnnil
 end
 prefix=':'..lang
 page[1]=""
 page[2]=true
 locallangname=mw.language.fetchLanguageName(lang,'en')
 ifnotlangnameor#langname==0then
 returnnil
 end
 info=langname..' '..info
 prep="of"
 end
 returngenSisterLink({
 page,
 auto=args.auto,
 qid=args.qid,
 logo=logo,
 class=class,
 name=name,
 prep=prep,
 sitelink=sitelink,
 default=default,
 sisterPrefix=prefix,
 search=search,
 information=info},tracking)
 end

 localfunctiontemplatestyles_page(is_bar)
 localsandbox=inSandboxand'sandbox/'or''
 ifis_barthen
 returnmw.ustring.format(
 'Module:Sister project links/bar/%sstyles.css',
 sandbox
 )
 end
 returnmw.ustring.format(
 'Module:Sister project links/%sstyles.css',
 sandbox
 )
 end

 -- Function to create html containers for sister project link list
 -- Arguments:
 -- args = table of arguments
 -- args.position: if 'left', position links to left
 -- args.collapsible: if non-empty, make box collapsible. If 'collapse', start box hidden
 -- args.style: CSS style string appended to end of default CSS
 -- args.display: boldface name to display
 localfunctioncreateSisterBox(sisterList,args)

 locallist=mw.html.create('ul')
 fori,linkinipairs(sisterList)do
 localli=list:tag('li')
 -- html element for 27px-high logo
 locallogoSpan=li:tag('span')
 logoSpan:addClass(sandbox("sister-logo"))
 logoSpan:wikitext("[[File:"..link.logo.."|class="..link.class.."|27x27px|middle"..suppressLink(link.prefix).."|alt=]]")
 -- html element for link
 locallinkspan=li:tag('span')
 linkspan:addClass(sandbox("sister-link"))
 locallinkText="[["..link.prefix..":"..link.link.."|"..link.information.."]] "..link.prep.." "..link.name
 linkspan:wikitext(linkText)
 end
 list:allDone()

 returnsideBox({
 role='navigation',
 labelledby='sister-projects',
 class=sandbox("sister-box")..' sistersitebox plainlinks',
 position=args.position,
 style=args.style,
 abovestyle=args.collapsibleand'clear: both'ornil,
 above=mw.ustring.format(
 "<b>%s</b> at Wikipedia's [[Wikipedia:Wikimedia sister projects|<span id=\"sister-projects\">sister projects</span>]]",
 args.displayorargs[1]
 ),
 text=tostring(list),
 collapsible=args.collapsible,
 templatestyles=templatestyles_page()
 })
 end

 localfunctioncreateSisterBar(sisterList,args)
 localnav=mw.html.create('div')
 nav:addClass('noprint')
 nav:addClass('metadata')
 nav:addClass(sandbox('sister-bar'))
 nav:attr('role','navigation')
 nav:attr('aria-label','sister-projects')
 localheader=nav:tag('div')
 header:addClass(sandbox('sister-bar-header'))
 localpagename=header:tag('b')
 pagename:wikitext(args.displayorargs[1])
 localheaderText=" at Wikipedia's [[Wikipedia:Wikimedia sister projects|"
 headerText=headerText..'<span id="sister-projects" style="white-space:nowrap;">sister projects</span>]]:'
 header:wikitext(headerText)
 if#sisterList==1andargs.trackSinglethen
 header:wikitext("[[Category:Pages with single-entry sister bar]]")
 end
 localcontainer=nav:tag('ul')
 container:addClass(sandbox('sister-bar-content'))
 for_,linkinipairs(sisterList)do
 localitem=container:tag('li')
 item:addClass(sandbox('sister-bar-item'))
 locallogoSpan=item:tag('span')
 logoSpan:addClass(sandbox('sister-bar-logo'))
 logoSpan:wikitext("[[File:"..link.logo.."|class="..link.class.."|21x19px"..suppressLink(link.prefix).."|alt=]]")
 locallinkSpan=item:tag('span')
 linkSpan:addClass(sandbox('sister-bar-link'))
 linkSpan:wikitext("<b>[["..link.prefix..":"..link.link.."|"..link.information.."]]</b> "..link.prep.." "..link.name)
 end
 returnnav
 end

 functionp._main(args)
 localtitleObject=mw.title.getCurrentTitle()
 localns=titleObject.namespace
 -- find qid, either supplied with args, from search string, or from current page
 args.qid=args.qidormw.wikibase.getEntityIdForTitle(args[1]or"")ormw.wikibase.getEntityIdForCurrentPage()
 args.qid=args.qidandargs.qid:upper()
 -- search string defaults to PAGENAME
 args[1]=args[1]ormw.wikibase.getSitelink(args.qidor"")ortitleObject.text
 -- handle redundant "commons"/"c" prefix
 args.c=args.corargs.commons
 -- Canonicalize all sister links (handle yes/no/empty)
 for_,kinipairs(prefixList)do
 args[k]=canonicalize(args[k])
 end
 -- Canonicalize cookbook
 args.cookbook=canonicalize(args.cookbook)
 args.b=mergeArgs({args.b,args.cookbook})
 args.cookbook=args.cookbook[2]
 -- handle trackSingle parameter
 ifargs.trackSingle==nilthen
 args.trackSingle=true
 end
 ifns~=0andns~=14then
 args.trackSingle=false
 end
 -- Canonicalize general parameters
 for_,kinpairs({"auto","commonscat","author","bar","tracking","sandbox","trackSingle"})do
 args[k]=canonicalize(args[k])[2]
 end
 -- Initialize tracking categories if main namespace
 localtracking=(args.trackingorns==0)and{}
 localsisterList={}
 localprefix
 -- Loop through all sister projects, generate possible links
 for_,prefixinipairs(prefixList)do
 locallink=sisterLink(prefix,args,tracking)
 iflinkthen
 table.insert(sisterList,link)
 end
 end
 localbox=mw.html.create()
 ifargs.barand#sisterList>0then
 box:wikitext(mw.getCurrentFrame():extensionTag{
 name='templatestyles',args={src=templatestyles_page(true)}
 })
 box:node(createSisterBar(sisterList,args))
 elseif#sisterList==1then
 -- Use single sister box instead of multi-sister box
 localsister=sisterList[1]
 locallink="[["..sister.prefix..":"..sister.link.."|<b><i>"..(args.displayorargs[1]).."</i></b>]]"
 ifsister.name=='Commons'then
 sister.name='Wikimedia Commons'-- make single sister commons box look like {{Commons}}
 end
 localtext=sister.name.." has "..mw.ustring.lower(sister.information).." related to "..link.."."
 ifsister.name=='Wikipedia'then-- make single sister interwiki box look like {{InterWiki}}
 text="[["..sister.prefix..":"..sister.link.."|<b><i>"..sister.information.."</i></b>]] "..sister.prep.." [[Wikipedia]], the free encyclopedia"
 end
 box:wikitext(sideBox({
 role='navigation',
 position=args.position,
 image="[[File:"..sister.logo.."|class="..sister.class.."|40x40px|alt="..suppressLink(sister.prefix).."]]",
 metadata='no',
 class='plainlinks sistersitebox',
 text=text,
 templatestyles=templatestyles_page()
 }))
 elseif#sisterList>0then
 -- else use sister box if non-empty
 box:wikitext(createSisterBox(sisterList,args))
 end
 if#sisterList==0andargs.autothen
 localgenerateWarning=require('Module:If preview')._warning
 box:wikitext(generateWarning({"No sister project links found in Wikidata. Try auto=0"}))
 end
 -- Append tracking categories to container div
 -- Alpha ordering is by sister prefix
 iftrackingthen
 fork,vinpairs(tracking)do
 box:wikitext("[[Category:"..trackingType[k].."|"..v.."]]")
 end
 if#sisterList==0then
 box:wikitext("[[Category:Pages with empty sister project links]]")
 end
 end
 returntostring(box)
 end

 -- Main entry point for generating sister project links box
 functionp.main(frame)
 localargs=getArgs(frame,{frameOnly=false,parentOnly=false,parentFirst=false})
 returnp._main(args)
 end

 -- Lua entry point for generate one sister link
 functionp._sisterlink(args)
 localprefix=args.prefix
 -- Canonicalize all sister links (handle yes/no/empty)
 for_,kinipairs(prefixList)do
 args[k]=canonicalize(args[k])
 end
 -- Canonicalize cookbook
 args.cookbook=canonicalize(args.cookbook)
 args.b=mergeArgs({args.b,args.cookbook})
 args.cookbook=args.cookbook[2]
 -- Canonicalize general parameters
 for_,kinpairs({"auto","commonscat","author"})do
 args[k]=canonicalize(args[k])[2]
 end
 args[1]=args[1]ormw.title.getCurrentTitle().text
 args.qid=args.qidormw.wikibase.getEntityIdForCurrentPage()
 args.qid=args.qidandargs.qid:upper()
 locallink=sisterLink(prefix,args,nil)
 ifnotlinkthen
 return""
 end
 return"[["..link.prefix..":"..link.link.."|"..link.information.."]] "..link.prep.." "..link.name
 end

 -- Template entry point for generating one sister link
 functionp.link(frame)
 localargs=getArgs(frame)
 returnp._sisterlink(args)
 end

 returnp

AltStyle によって変換されたページ (->オリジナル) /