Module:Sister project links: Difference between revisions
Jump to navigation
Jump to search
Richardpruen (talk | contribs) m (1 revision imported) |
(use box-style header in bar, sandbox-ify CSS) |
||
Line 1: | Line 1: | ||
require('Module:No globals') | |||
-- Module to create sister project link box | -- Module to create sister project link box | ||
local getArgs = require('Module:Arguments').getArgs | local getArgs = require('Module:Arguments').getArgs | ||
local commonsLink = require('Module:Commons link') | local commonsLink = require('Module:Commons link') | ||
local sideBox = require('Module:Side box')._main | local sideBox = require('Module:Side box')._main | ||
local generateWarning = require('Module:If preview')._warning | |||
local p = {} | local p = {} | ||
Line 18: | Line 21: | ||
m="Wikimedia Community Logo.svg", | m="Wikimedia Community Logo.svg", | ||
mw="MediaWiki-2020-icon.svg"} | mw="MediaWiki-2020-icon.svg"} | ||
local prefixList = {'wikt', 'c', 'n', 'q', 's', 'b', 'voy', 'v', 'd', | |||
'species', 'species_author', 'm', 'mw'} | |||
local sisterName = { | local sisterName = { | ||
wikt="Wiktionary", | wikt="Wiktionary", | ||
c=" | c="Commons", | ||
n="Wikinews", | n="Wikinews", | ||
q="Wikiquote", | q="Wikiquote", | ||
Line 32: | Line 38: | ||
m="Meta-Wiki", | m="Meta-Wiki", | ||
mw="MediaWiki"} | mw="MediaWiki"} | ||
local sisterInfo = { | |||
wikt="Definitions", | |||
c="Media", | |||
n="News", | |||
q="Quotations", | |||
s="Texts", | |||
b="Textbooks", | |||
voy="Travel guides", | |||
v="Resources", | |||
d="Data", | |||
species="Taxa", | |||
species_author="Authorship", | |||
m="Discussions", | |||
mw="Documentation" | |||
} | |||
local defaultSisters = { | |||
wikt=true, | |||
c=true, | |||
n=true, | |||
q=true, | |||
s=true, | |||
b=true, | |||
voy='auto', | |||
v=true, | |||
d=false, | |||
species='auto', | |||
species_author=false, | |||
m=false, | |||
mw=false | |||
} | |||
local sisterDb = { | local sisterDb = { | ||
Line 48: | Line 86: | ||
wdHidden="Pages using Sister project links with hidden wikidata", | wdHidden="Pages using Sister project links with hidden wikidata", | ||
defaultSearch="Pages using Sister project links with default search"} | defaultSearch="Pages using Sister project links with default search"} | ||
-- Function to add "-sand" to classes when called from sandbox | |||
local function sandbox(args, s) | |||
return args.sandbox and s.."-sand" or s | |||
end | |||
-- Function to canonicalize string | -- Function to canonicalize string | ||
Line 70: | Line 113: | ||
return {nil, nil} | return {nil, nil} | ||
end | end | ||
lowerS = s:lower() | local lowerS = s:lower() | ||
-- Check for various forms of "yes" | -- Check for various forms of "yes" | ||
if lowerS == 'yes' or lowerS == 'y' or lowerS == 't' | if lowerS == 'yes' or lowerS == 'y' or lowerS == 't' | ||
Line 137: | Line 180: | ||
-- args.information = type of info sister site contains | -- args.information = type of info sister site contains | ||
-- tracking = tracking table | -- tracking = tracking table | ||
local function | local function genSisterLink(args, tracking) | ||
if args[1][2] == false or (not args.default and args[1][2] == nil) then | if args[1][2] == false or (not args.default and args[1][2] == nil) then | ||
return nil --- either editor specified "no", or "blank" (and default=no), then skip this sister | return nil --- either editor specified "no", or "blank" (and default=no), then skip this sister | ||
Line 151: | Line 194: | ||
return nil --- no link found, just skip | return nil --- no link found, just skip | ||
end | end | ||
if tracking | if tracking then | ||
-- update state for tracking categories | -- update state for tracking categories | ||
if args[1][1] and sitelink then | if args[1][1] and sitelink then | ||
Line 174: | Line 217: | ||
end | end | ||
-- Function to | local function commonsLinks(args, commonsPage) | ||
-- use [[Module:Commons link]] to determine best commons link | |||
local cLink = (not args.commonscat) and commonsLink._hasGallery(args.qid) | |||
or commonsLink._hasCategory(args.qid) | |||
if commonsPage[1] and not mw.ustring.match(commonsPage[1]:lower(),"^category:") then | |||
commonsPage[1] = (args.commonscat and "Category:" or "")..commonsPage[1] | |||
end | |||
local commonsSearch = "Search/"..(args.commonscat and "Category:" or "")..args[1] | |||
return {link=cLink, search=commonsSearch} | |||
end | |||
-- Function to create a sister link, by prefix | |||
-- Arguments: | -- Arguments: | ||
-- | -- prefix = sister prefix (e.g., "c" for commons) | ||
-- args = arguments for this sister (see p._sisterLink above) | -- args = arguments for this sister (see p._sisterLink above) | ||
-- tracking = tracking table | -- tracking = tracking table | ||
local function | local function sisterLink(prefix, args, tracking) | ||
local | -- determine arguments to genSisterLink according to prefix | ||
if | if prefix == 'species_author' and not args.species[1] and args.species[2] and not args.species_author[1] and args.species_author[2] then | ||
return nil | |||
end | |||
local default = defaultSisters[prefix] | |||
if default == 'auto' then | |||
default = args.auto | |||
end | |||
-- Handle exceptions by prefix | |||
local search = ((prefix == 'd' and "ItemByTitle/enwiki/") or "Search/")..args[1] | |||
local sitelink = prefix == 'd' and args.qid | |||
local page = args[prefix] | |||
if prefix == 's' and args.author and page[1] then | |||
page[1] = "Author:"..page[1] | |||
end | end | ||
local info = sisterInfo[prefix] | |||
if prefix == 'voy' and not args.bar and not page[1] and page[2] ~= nil then | |||
info = "Travel information" | |||
end | |||
info = args.information or info | |||
if prefix == 'c' then | |||
local commons = commonsLinks(args, page) | |||
search = commons.search | |||
sitelink = commons.link | |||
end | |||
prefix = (prefix == 'species_author' and 'species') or prefix | |||
return genSisterLink({ | |||
page, | |||
auto=args.auto, | |||
qid=args.qid, | |||
sitelink=sitelink, | |||
default=default, | |||
sisterPrefix = prefix, | |||
search=search, | |||
information=info}, tracking) | |||
end | end | ||
Line 202: | Line 287: | ||
container:addClass("sistersitebox") | container:addClass("sistersitebox") | ||
container:addClass("plainlist") | container:addClass("plainlist") | ||
container:addClass(sandbox(args,"sister-box")) | |||
if args.position and args.position:lower() == "left" then | if args.position and args.position:lower() == "left" then | ||
container:addClass("mbox-small-left") | container:addClass("mbox-small-left") | ||
Line 213: | Line 299: | ||
end | end | ||
end | end | ||
container:cssText(args.style) | container:cssText(args.style) | ||
-- Div for text header | -- Div for text header | ||
local header = container:tag('div') | local header = container:tag('div') | ||
header:css("clear",args.collapsible and "both") | header:css("clear",args.collapsible and "both") | ||
-- pagename in bold as part of header | -- pagename in bold as part of header | ||
local pagename = header:tag('b') | local pagename = header:tag('b') | ||
pagename:wikitext(args.display or args[1]) | pagename:wikitext(args.display or args[1]) | ||
local headerText = "at Wikipedia's [[Wikipedia:Wikimedia sister projects|" | local headerText = "at Wikipedia's [[Wikipedia:Wikimedia sister projects|" | ||
Line 232: | Line 312: | ||
local ul = container:tag('ul') | local ul = container:tag('ul') | ||
ul:addClass(args.collapsible and "mw-collapsible-content") | ul:addClass(args.collapsible and "mw-collapsible-content") | ||
-- pass ul element back to main, so sister links can be added | -- pass ul element back to main, so sister links can be added | ||
return ul | return ul | ||
Line 241: | Line 317: | ||
local function createSisterBox(sisterList,args) | local function createSisterBox(sisterList,args) | ||
container = createContainer(args) | local container = createContainer(args) | ||
for i, link in ipairs(sisterList) do | for i, link in ipairs(sisterList) do | ||
local li = container:tag('li') | local li = container:tag('li') | ||
-- html element for 27px-high logo | -- html element for 27px-high logo | ||
local logoSpan = li:tag('span') | local logoSpan = li:tag('span') | ||
logoSpan: | logoSpan:addClass(sandbox(args,"sister-logo")) | ||
logoSpan:wikitext("[[File:"..logo[link.prefix].."|27x27px|middle|link=|alt=]]") | logoSpan:wikitext("[[File:"..logo[link.prefix].."|27x27px|middle|link=|alt=]]") | ||
-- html element for link | -- html element for link | ||
local linkspan = li:tag('span') | local linkspan = li:tag('span') | ||
linkspan: | linkspan:addClass(sandbox(args,"sister-link")) | ||
local linkText = "[["..link.prefix..":"..link.link.."|"..link.information .."]] from "..sisterName[link.prefix] | local linkText = "[["..link.prefix..":"..link.link.."|"..link.information .."]] from "..sisterName[link.prefix] | ||
linkspan:wikitext(linkText) | linkspan:wikitext(linkText) | ||
Line 265: | Line 333: | ||
end | end | ||
local function createSisterBar(sisterList,args) | |||
local nav = mw.html.create( 'div' ) | |||
nav:addClass( 'noprint') | |||
nav:addClass( 'metadata') | |||
nav:addClass( sandbox(args,'sister-bar')) | |||
nav:attr( 'role', 'navigation' ) | |||
nav:attr( 'aria-label' , 'sister-projects' ) | |||
local header = nav:tag('div') | |||
header:addClass(sandbox(args,'sister-bar-header')) | |||
local pagename = header:tag('b') | |||
pagename:wikitext(args.display or args[1]) | |||
local headerText = " at Wikipedia's [[Wikipedia:Wikimedia sister projects|" | |||
headerText = headerText..'<span id="sister-projects" style="white-space:nowrap;">sister projects</span>]]:' | |||
header:wikitext(headerText) | |||
local container = nav:tag('div') | |||
container:addClass(sandbox(args,'sister-bar-content')) | |||
for _, link in ipairs(sisterList) do | |||
local item = container:tag('div') | |||
item:addClass(sandbox(args,'sister-bar-item')) | |||
local logoSpan = item:tag('span') | |||
logoSpan:addClass(sandbox(args,'sister-bar-logo')) | |||
logoSpan:wikitext("[[File:"..logo[link.prefix].."|21x19px|link=|alt=]]") | |||
local linkSpan = item:tag('span') | |||
linkSpan:addClass(sandbox(args,'sister-bar-link')) | |||
linkSpan:wikitext("<b>[["..link.prefix..":"..link.link.."|"..link.information .."]]</b> from "..sisterName[link.prefix]) | |||
end | |||
return nav | |||
end | |||
function p._main(args) | function p._main(args) | ||
local titleObject = mw.title.getCurrentTitle() | local titleObject = mw.title.getCurrentTitle() | ||
-- | -- find qid, either supplied with args, from search string, or from current page | ||
args.qid = args.qid or mw.wikibase.getEntityIdForTitle(args[1] or "") or mw.wikibase.getEntityIdForCurrentPage() | |||
args.qid = args.qid and args.qid:upper() | |||
-- search string defaults to PAGENAME | |||
args[1] = args[1] or titleObject.text | |||
-- handle redundant "commons"/"c" prefix | |||
args.c = args.c or args.commons | |||
-- Canonicalize all sister links (handle yes/no/empty) | -- Canonicalize all sister links (handle yes/no/empty) | ||
for _, k in | for _, k in ipairs(prefixList) do | ||
args[k] = canonicalize(args[k]) | args[k] = canonicalize(args[k]) | ||
end | |||
-- Canonicalize general parameters | -- Canonicalize general parameters | ||
for _,k in pairs({"auto","commonscat","author"}) do | for _,k in pairs({"auto","commonscat","author","bar","tracking","sandbox"}) do | ||
args[k] = canonicalize(args[k])[2] | args[k] = canonicalize(args[k])[2] | ||
end | end | ||
-- Initialize tracking categories if main namespace | -- Initialize tracking categories if main namespace | ||
local tracking = | local tracking = (args.tracking or titleObject.namespace == 0) and {} | ||
local sisterList = {} | local sisterList = {} | ||
local prefix | |||
-- Loop through all sister projects, generate possible links | |||
for _, prefix in ipairs(prefixList) do | |||
local link = sisterLink(prefix, args, tracking) | |||
if link then | |||
-- | table.insert(sisterList, link) | ||
end | |||
end | end | ||
local box = mw.html.create('div') | local box = mw.html.create('div') | ||
if #sisterList == 1 then | if args.bar and #sisterList > 0 then | ||
box = createSisterBar(sisterList,args) | |||
elseif #sisterList == 1 then | |||
-- Use single sister box instead of multi-sister box | -- Use single sister box instead of multi-sister box | ||
local sister = sisterList[1] | local sister = sisterList[1] | ||
Line 373: | Line 405: | ||
-- else use sister box if non-empty | -- else use sister box if non-empty | ||
box = createSisterBox(sisterList,args) | box = createSisterBox(sisterList,args) | ||
end | |||
if #sisterList == 0 and args.auto then | |||
box:wikitext(generateWarning({"No sister project links found in Wikidata. Try auto=0"})) | |||
end | end | ||
-- Append tracking categories to container div | -- Append tracking categories to container div | ||
-- Alpha ordering is by sister prefix | -- Alpha ordering is by sister prefix | ||
if tracking | if tracking then | ||
for k, v in pairs(tracking) do | for k, v in pairs(tracking) do | ||
box:wikitext("[[Category:"..trackingType[k].."|"..v.."]]") | box:wikitext("[[Category:"..trackingType[k].."|"..v.."]]") | ||
end | |||
if #sisterList == 0 then | |||
box:wikitext("[[Category:Pages with empty sister project links]]") | |||
end | |||
end | end | ||
return box | local styleFile = 'Module:Sister project links/' | ||
styleFile = styleFile..(args.sandbox and 'sandbox/' or '') | |||
styleFile = styleFile..'styles.css' | |||
return mw.getCurrentFrame():extensionTag{ | |||
name = 'templatestyles', args = { src = styleFile } | |||
} .. tostring(box) | |||
end | end | ||
Line 387: | Line 431: | ||
function p.main(frame) | function p.main(frame) | ||
local args = getArgs(frame,{frameOnly=false,parentOnly=false,parentFirst=false}) | local args = getArgs(frame,{frameOnly=false,parentOnly=false,parentFirst=false}) | ||
return | return p._main(args) | ||
end | end | ||
-- Lua entry point for generate one sister link | -- Lua entry point for generate one sister link | ||
function p._sisterlink(args) | function p._sisterlink(args) | ||
args[ | local prefix = args.prefix | ||
args | -- Canonicalize all sister links (handle yes/no/empty) | ||
for _, k in ipairs(prefixList) do | |||
args[k] = canonicalize(args[k]) | |||
end | |||
-- Canonicalize general parameters | |||
for _,k in pairs({"auto","commonscat","author"}) do | |||
args[k] = canonicalize(args[k])[2] | |||
end | |||
args[1] = args[1] or mw.title.getCurrentTitle().text | |||
args.qid = args.qid or mw.wikibase.getEntityIdForCurrentPage() | args.qid = args.qid or mw.wikibase.getEntityIdForCurrentPage() | ||
args.qid = args.qid and args.qid:upper() | args.qid = args.qid and args.qid:upper() | ||
local link = sisterLink(args,nil) | local link = sisterLink(prefix, args,nil) | ||
if not link then | |||
return "" | |||
end | |||
return "[["..link.prefix..":"..link.link.."|"..link.information .."]] from "..sisterName[link.prefix] | return "[["..link.prefix..":"..link.link.."|"..link.information .."]] from "..sisterName[link.prefix] | ||
end | end |
Revision as of 20:21, 18 December 2021
Documentation for this module may be created at Module:Sister project links/doc
require('Module:No globals') -- Module to create sister project link box local getArgs = require('Module:Arguments').getArgs local commonsLink = require('Module:Commons link') local sideBox = require('Module:Side box')._main local generateWarning = require('Module:If preview')._warning local p = {} local logo = { wikt="Wiktionary-logo-v2.svg", c="Commons-logo.svg", n="Wikinews-logo.svg", q="Wikiquote-logo.svg", s="Wikisource-logo.svg", b="Wikibooks-logo.svg", voy="Wikivoyage-Logo-v3-icon.svg", v="Wikiversity logo 2017.svg", d="Wikidata-logo.svg", species="Wikispecies-logo.svg", m="Wikimedia Community Logo.svg", mw="MediaWiki-2020-icon.svg"} local prefixList = {'wikt', 'c', 'n', 'q', 's', 'b', 'voy', 'v', 'd', 'species', 'species_author', 'm', 'mw'} local sisterName = { wikt="Wiktionary", c="Commons", n="Wikinews", q="Wikiquote", s="Wikisource", b="Wikibooks", voy="Wikivoyage", v="Wikiversity", d="Wikidata", species="Wikispecies", m="Meta-Wiki", mw="MediaWiki"} local sisterInfo = { wikt="Definitions", c="Media", n="News", q="Quotations", s="Texts", b="Textbooks", voy="Travel guides", v="Resources", d="Data", species="Taxa", species_author="Authorship", m="Discussions", mw="Documentation" } local defaultSisters = { wikt=true, c=true, n=true, q=true, s=true, b=true, voy='auto', v=true, d=false, species='auto', species_author=false, m=false, mw=false } local sisterDb = { wikt="enwiktionary", n="enwikinews", q="enwikiquote", s="enwikisource", b="enwikibooks", voy="enwikivoyage", v="enwikiversity", species="specieswiki"} local trackingType = { wdMismatch="Pages using Sister project links with wikidata mismatch", wdNamespace="Pages using Sister project links with wikidata namespace mismatch", wdHidden="Pages using Sister project links with hidden wikidata", defaultSearch="Pages using Sister project links with default search"} -- Function to add "-sand" to classes when called from sandbox local function sandbox(args, s) return args.sandbox and s.."-sand" or s end -- 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) local function canonicalize(s) if s == nil then return {nil, nil} end -- if s is table/list, then assume already canonicalized and return unchanged if tostring(type(s)) == "table" then return s end s = mw.text.trim(tostring(s)) if s == "" then return {nil, nil} end local lowerS = s:lower() -- Check for various forms of "yes" if lowerS == 'yes' or lowerS == 'y' or lowerS == 't' or lowerS == '1' or lowerS == 'true' or lowerS == 'on' then return {nil, true} end -- Check for various forms of "no" if lowerS == 'no' or lowerS == 'n' or lowerS == 'f' or lowerS == '0' or lowerS == 'false' or lowerS == '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 local function mergeArgs(argList,noAll) local test = nil -- default, return blank if all blank if noAll then test = false -- return no if all no end local allSame = true -- Search through string for first non-no or non-blank for _, arg in ipairs(argList) do if arg[2] then return arg -- found non-no and non-blank, return it end -- test to see if argList is all blank / no allSame = allSame and (arg[2] == test) end -- if all blank / no, return blank / no if allSame then return {nil, test} -- all match no/blank, return it end -- otherwise, return no / blank if noAll then return {nil, nil} end return {nil, false} 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 local function getSitelink(wiki,qid) -- return nil if some sort of lookup failure return qid and mw.wikibase.getSitelink(qid,wiki) 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 local function genSisterLink(args, tracking) if args[1][2] == false or (not args.default and args[1][2] == nil) then return nil --- either editor specified "no", or "blank" (and default=no), then skip this sister end local sisterDbName = sisterDb[args.sisterPrefix] local sitelink = args.sitelink or (sisterDbName and getSitelink(sisterDbName,args.qid)) if args.auto and not sitelink and args[1][2] == nil then return nil --- 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 local link = args[1][1] or sitelink or (args.search and "Special:"..args.search) if not link then return nil --- no link found, just skip end if tracking then -- update state for tracking categories if args[1][1] and sitelink then -- transform supplied page name to be in wiki-format local page = mw.ustring.gsub(args[1][1],"_"," ") page = mw.ustring.sub(page,1,1):upper()..mw.ustring.sub(page,2) local pageNS = mw.ustring.match(page,"^([^:]+):") local sitelinkNS = mw.ustring.match(sitelink,"^([^:]+):") if page == sitelink then tracking.wdHidden = args.sisterPrefix elseif pageNS ~= sitelinkNS then tracking.wdNamespace = args.sisterPrefix else tracking.wdMismatch = args.sisterPrefix end -- if no page link, nor a wikidata entry, and search is on, then warn elseif not (args[1][2] or sitelink) and args.search then tracking.defaultSearch = args.sisterPrefix end end return {prefix=args.sisterPrefix, link=link, information=args.information} end local function commonsLinks(args, commonsPage) -- use [[Module:Commons link]] to determine best commons link local cLink = (not args.commonscat) and commonsLink._hasGallery(args.qid) or commonsLink._hasCategory(args.qid) if commonsPage[1] and not mw.ustring.match(commonsPage[1]:lower(),"^category:") then commonsPage[1] = (args.commonscat and "Category:" or "")..commonsPage[1] end local commonsSearch = "Search/"..(args.commonscat and "Category:" or "")..args[1] return {link=cLink, search=commonsSearch} 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 local function sisterLink(prefix, args, tracking) -- determine arguments to genSisterLink according to prefix if prefix == 'species_author' and not args.species[1] and args.species[2] and not args.species_author[1] and args.species_author[2] then return nil end local default = defaultSisters[prefix] if default == 'auto' then default = args.auto end -- Handle exceptions by prefix local search = ((prefix == 'd' and "ItemByTitle/enwiki/") or "Search/")..args[1] local sitelink = prefix == 'd' and args.qid local page = args[prefix] if prefix == 's' and args.author and page[1] then page[1] = "Author:"..page[1] end local info = sisterInfo[prefix] if prefix == 'voy' and not args.bar and not page[1] and page[2] ~= nil then info = "Travel information" end info = args.information or info if prefix == 'c' then local commons = commonsLinks(args, page) search = commons.search sitelink = commons.link end prefix = (prefix == 'species_author' and 'species') or prefix return genSisterLink({ page, auto=args.auto, qid=args.qid, sitelink=sitelink, default=default, sisterPrefix = prefix, search=search, information=info}, tracking) 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 local function createContainer(args) -- Outermost div (css from previous version of [[Template:Project sister links]]) local container = mw.html.create('div') container:attr("role","navigation") container:attr("aria-labelledby","sister-projects") container:addClass("metadata") container:addClass("plainlinks") container:addClass("sistersitebox") container:addClass("plainlist") container:addClass(sandbox(args,"sister-box")) if args.position and args.position:lower() == "left" then container:addClass("mbox-small-left") else container:addClass("mbox-small") end if args.collapsible then container:addClass("mw-collapsible") if args.collapsible == "collapsed" then container:addClass("mw-collapsed") end end container:cssText(args.style) -- Div for text header local header = container:tag('div') header:css("clear",args.collapsible and "both") -- pagename in bold as part of header local pagename = header:tag('b') pagename:wikitext(args.display or args[1]) local headerText = "at Wikipedia's [[Wikipedia:Wikimedia sister projects|" headerText = headerText..'<span id="sister-projects">sister projects</span>]]' header:wikitext(headerText) -- start the unordered list element here local ul = container:tag('ul') ul:addClass(args.collapsible and "mw-collapsible-content") -- pass ul element back to main, so sister links can be added return ul end local function createSisterBox(sisterList,args) local container = createContainer(args) for i, link in ipairs(sisterList) do local li = container:tag('li') -- html element for 27px-high logo local logoSpan = li:tag('span') logoSpan:addClass(sandbox(args,"sister-logo")) logoSpan:wikitext("[[File:"..logo[link.prefix].."|27x27px|middle|link=|alt=]]") -- html element for link local linkspan = li:tag('span') linkspan:addClass(sandbox(args,"sister-link")) local linkText = "[["..link.prefix..":"..link.link.."|"..link.information .."]] from "..sisterName[link.prefix] linkspan:wikitext(linkText) end return container:allDone() end local function createSisterBar(sisterList,args) local nav = mw.html.create( 'div' ) nav:addClass( 'noprint') nav:addClass( 'metadata') nav:addClass( sandbox(args,'sister-bar')) nav:attr( 'role', 'navigation' ) nav:attr( 'aria-label' , 'sister-projects' ) local header = nav:tag('div') header:addClass(sandbox(args,'sister-bar-header')) local pagename = header:tag('b') pagename:wikitext(args.display or args[1]) local headerText = " at Wikipedia's [[Wikipedia:Wikimedia sister projects|" headerText = headerText..'<span id="sister-projects" style="white-space:nowrap;">sister projects</span>]]:' header:wikitext(headerText) local container = nav:tag('div') container:addClass(sandbox(args,'sister-bar-content')) for _, link in ipairs(sisterList) do local item = container:tag('div') item:addClass(sandbox(args,'sister-bar-item')) local logoSpan = item:tag('span') logoSpan:addClass(sandbox(args,'sister-bar-logo')) logoSpan:wikitext("[[File:"..logo[link.prefix].."|21x19px|link=|alt=]]") local linkSpan = item:tag('span') linkSpan:addClass(sandbox(args,'sister-bar-link')) linkSpan:wikitext("<b>[["..link.prefix..":"..link.link.."|"..link.information .."]]</b> from "..sisterName[link.prefix]) end return nav end function p._main(args) local titleObject = mw.title.getCurrentTitle() -- find qid, either supplied with args, from search string, or from current page args.qid = args.qid or mw.wikibase.getEntityIdForTitle(args[1] or "") or mw.wikibase.getEntityIdForCurrentPage() args.qid = args.qid and args.qid:upper() -- search string defaults to PAGENAME args[1] = args[1] or titleObject.text -- handle redundant "commons"/"c" prefix args.c = args.c or args.commons -- Canonicalize all sister links (handle yes/no/empty) for _, k in ipairs(prefixList) do args[k] = canonicalize(args[k]) end -- Canonicalize general parameters for _,k in pairs({"auto","commonscat","author","bar","tracking","sandbox"}) do args[k] = canonicalize(args[k])[2] end -- Initialize tracking categories if main namespace local tracking = (args.tracking or titleObject.namespace == 0) and {} local sisterList = {} local prefix -- Loop through all sister projects, generate possible links for _, prefix in ipairs(prefixList) do local link = sisterLink(prefix, args, tracking) if link then table.insert(sisterList, link) end end local box = mw.html.create('div') if args.bar and #sisterList > 0 then box = createSisterBar(sisterList,args) elseif #sisterList == 1 then -- Use single sister box instead of multi-sister box local sister = sisterList[1] local frame = mw.getCurrentFrame() local link = "[["..sister.prefix..":"..sister.link.."|<b><i>"..(args.display or args[1]).."</i></b>]]" box:wikitext(sideBox({position=args.position, image="[[File:"..logo[sister.prefix].."|40x40px|class=noviewer|alt=|link=]]", metadata='no', textclass='plainlist', class='plainlinks sistersitebox', text=sisterName[sister.prefix].." has "..mw.ustring.lower(sister.information).." related to "..link})) elseif #sisterList > 0 then -- else use sister box if non-empty box = createSisterBox(sisterList,args) end if #sisterList == 0 and args.auto then 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 if tracking then for k, v in pairs(tracking) do box:wikitext("[[Category:"..trackingType[k].."|"..v.."]]") end if #sisterList == 0 then box:wikitext("[[Category:Pages with empty sister project links]]") end end local styleFile = 'Module:Sister project links/' styleFile = styleFile..(args.sandbox and 'sandbox/' or '') styleFile = styleFile..'styles.css' return mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = { src = styleFile } } .. tostring(box) end -- Main entry point for generating sister project links box function p.main(frame) local args = getArgs(frame,{frameOnly=false,parentOnly=false,parentFirst=false}) return p._main(args) end -- Lua entry point for generate one sister link function p._sisterlink(args) local prefix = args.prefix -- Canonicalize all sister links (handle yes/no/empty) for _, k in ipairs(prefixList) do args[k] = canonicalize(args[k]) end -- Canonicalize general parameters for _,k in pairs({"auto","commonscat","author"}) do args[k] = canonicalize(args[k])[2] end args[1] = args[1] or mw.title.getCurrentTitle().text args.qid = args.qid or mw.wikibase.getEntityIdForCurrentPage() args.qid = args.qid and args.qid:upper() local link = sisterLink(prefix, args,nil) if not link then return "" end return "[["..link.prefix..":"..link.link.."|"..link.information .."]] from "..sisterName[link.prefix] end -- Template entry point for generating one sister link function p.link(frame) local args = getArgs(frame,{frameOnly=false,parentOnly=false,parentFirst=false}) return p._sisterlink(args) end return p