m 1 revision imported
No edit summary
 
(3 intermediate revisions by 2 users not shown)
Line 1: Line 1:
local getPortalImage = require('Module:Portal').image
require('strict')


local p = {}
local getArgs = require('Module:Arguments').getArgs
local yesNo = require('Module:Yesno')


local function getArgNums(prefix, args)
-- Determine whether we're being called from a sandbox
    -- Returns a table containing the numbers of the arguments that exist for the specified prefix. For example, if the
local isSandbox = mw.getCurrentFrame():getTitle():find('sandbox', 1, true)
    -- prefix was 'data', and 'data1', 'data2', and 'data5' exist, it would return {1, 2, 5}.
local sandbox = isSandbox and '/sandbox' or ''
    local nums = {}
    for k, v in pairs(args) do
        local num = tostring(k):match('^' .. prefix .. '([1-9]%d*)$')
        if num then table.insert(nums, tonumber(num)) end
    end
    table.sort(nums)
    return nums
end


local function makeHorizontalRule()
local p = {}
    local row = mw.html.create('tr')
    row
        :tag('td')
            :attr('colspan', '2')
            :tag('hr', {selfClosing = true})
    return tostring(row)
end


local function makeItem(image, text)
local sisters = {'commons','species','voy','n','wikt','b','q','s','v','iw','iw1','iw2','d','f'}
    local root = mw.html.create('li')
    root
        :css('float', 'left')
        :css('margin-left', '0.3em')
        :css('height', '3.6em')
        :tag('span')
            :css('display', 'inline-block')
            :css('margin-right', '0.3em')
            :css('width', '30px')
            :css('line-height', '3.6em')
            :css('text-align', 'center')
            :wikitext(image)
            :done()
        :tag('span')
            :css('display', 'inline-block')
            :css('width', '11em')
            :css('vertical-align', 'middle')
            :wikitext(text)
    return tostring(root)
end


local function makeRow(items, heading, subheading, options)
local function findNumericArgs(key, args)
    if #items < 1 then return end
local pattern = "^"..key.."_?(%d+)$"  -- pattern to match
    local swapHeadingSize = type(options) == 'table' and options.swapHeadingSize or false
local values = {}
    local row = mw.html.create('tr')
for k, v in pairs(args) do --- loop through all arguments
    row
local ord = tonumber(mw.ustring.match(k,pattern)) --- if "foo_?%d+", extract number
        :tag('td')
if ord then
            :css('width', '125px')
values[ord] = v
            :cssText('border-right:solid 1px black; padding-left:3px; padding-right:3px;')
end
            :tag('span')
                :css('font-size', swapHeadingSize and '90%' or '125%')
                :wikitext(heading)
                :done()
            :tag('br', {selfClosing = true})
                :done()
            :tag('span')
                :css('font-size', swapHeadingSize and '125%' or '90%')
                :wikitext(subheading)
    local list = row:tag('td'):css('text-align', 'left'):tag('ul')
    for i, item in ipairs(items) do
        local image = item[1]
        local text = item[2]
        list
            :wikitext(makeItem(image, text))
    end
    return tostring(row)
end
 
local function makeNumberedRow(prefix, args, heading, subheading, getItemValsFunc, options)
    if args[prefix] then
        args[prefix .. '1'] = args[prefix]
    end
    local argNums = getArgNums(prefix, args)
    local items = {}
    for i, argNum in ipairs(argNums) do
        local image, text = getItemValsFunc(args[prefix .. tostring(argNum)])
        table.insert(items, {image, text})
    end
    return makeRow(items, heading, subheading, options)
end
 
local function checkPortalExists(portal)
return not (mw.title.makeTitle(100, portal).id == 0)
end
 
local trackingEnabled = true
 
-- Check whether to do tracking in this namespace
-- Returns true unless the page is one of the banned namespaces
local function checkTrackingNamespace()
local thisPage = mw.title.getCurrentTitle()
if (thisPage.namespace == 1) -- Talk
or (thisPage.namespace == 2) -- User
or (thisPage.namespace == 3) -- User talk
or (thisPage.namespace == 5) -- Wikipedia talk
or (thisPage.namespace == 7) -- File talk
or (thisPage.namespace == 11) -- Template talk
or (thisPage.namespace == 15) -- Category talk
or (thisPage.namespace == 101) -- Portal talk
or (thisPage.namespace == 118) -- Draft
or (thisPage.namespace == 119) -- Draft talk
or (thisPage.namespace == 829) -- Module talk
then
return false
end
return true
end
 
-- Check whether to do tracking on this pagename
-- Returns false if the page title matches one of the banned strings
-- Otherwise returns true
local function checkTrackingPagename()
local thisPage = mw.title.getCurrentTitle()
local thisPageLC = mw.ustring.lower(thisPage.text)
if (string.match(thisPageLC, "/archive") ~= nil) then
return false
end
if (string.match(thisPageLC, "/doc") ~= nil) then
return false
end
end
if (string.match(thisPageLC, "/test") ~= nil) then
if args[key] ~= nil then
return false
values[1] = args[key]
end
end
return true
local compressSparseArray = require('Module:TableTools').compressSparseArray
values = compressSparseArray(values)  --- squeeze out gaps/nils in values, keep ordering
return values
end
end
local redlinkedportal = ""


function p._main(args)
function p._main(args)
-- Tracking is on by default.
local result = ""
-- It is disabled if any of the following is true
-- 1/ the parameter "tracking" is set to 'no, 'n', or 'false'
local hasPortal = false
-- 2/ the current page fails the namespace tests in checkTrackingNamespace()
for key, _ in pairs(args) do
-- 3/ the current page fails the pagename tests in checkTrackingPagename()
if mw.ustring.sub(key,1,6) == 'portal' or tonumber(key) then
if (args.tracking == 'no') or (args.tracking == 'n') or (args.tracking == 'false') then
hasPortal = true
trackingEnabled = false
break
end
end
end
if (checkTrackingNamespace() == false) then
trackingEnabled = false
local hasSister = yesNo(args.auto,true) or yesNo(args.author,true) or yesNo(args.cookbook,true)
for _, sister in ipairs(sisters) do
if hasSister then
break
end
if yesNo(args[sister],true) or yesNo(args[sister..'-search'],true) then
hasSister = true
end
end
end
if (checkTrackingPagename() == false) then
 
trackingEnabled = false
if hasPortal then
local portalList = findNumericArgs("portal",args)
for _, positional in ipairs(args) do
table.insert(portalList, positional)
end
local portalBar = require('Module:Portal bar'..sandbox)._main
result = result..portalBar(portalList, {tracking=args.tracking, qid=args.qid})
end
end
 
    local rows = {}
if hasSister then
    --[=[ disabled per [[Wikipedia:Village pump (technical)/Archive 176#Suppress rendering of Template:Wikipedia books]]
local sisterArgs = {auto=1, bar=1, trackSingle=not hasPortal}
    -- Get the book row text.
sisterArgs[1] = args.search
    local bookHeading = "'''[[Wikipedia:Books|Books]]'''"
for _, k in ipairs({'author','commonscat','cookbook','display','tracking','qid'}) do
    local bookSubheading = 'View or order collections of articles'
sisterArgs[k] = args[k]
    local function getBookItemVals(book)
        local image = '[[File:Office-book.svg|30px|alt=|link=]]'
        local text = mw.ustring.format("'''''[[Book:%s|%s]]'''''", book, book)
        return image, text
    end
    local bookRow = makeNumberedRow('book', args, bookHeading, bookSubheading, getBookItemVals)
    table.insert(rows, bookRow)
    ]=]
    -- Get the portal row text
    local portalHeading = "'''[[Wikipedia:Contents/Portals|Portals]]'''"
    local portalSubheading = 'Access related topics'
    local function getPortalItemVals(portal)
        local image = mw.ustring.format('[[File:%s|30x30px]]', getPortalImage{portal})
        local text = mw.ustring.format("'''''[[Portal:%s|%s portal]]'''''", portal, portal)
if not pcall(checkPortalExists, portal) or not checkPortalExists(portal) then
-- Getting here means a redlinked portal has been found
if trackingEnabled then
redlinkedportal = '[[Category:Subject bar templates with redlinked portals]]'
end
end
end
        return image, text
    for _, t in ipairs(sisters) do
    end
    sisterArgs[t] = args[t..'-search'] or args[t]
    local portalRow = makeNumberedRow('portal', args, portalHeading, portalSubheading, getPortalItemVals)
    end
    table.insert(rows, portalRow)
    local sisterBar = require('Module:Sister project links'..sandbox)._main
 
result = result..sisterBar(sisterArgs)
    -- Get the sister projects row text.
end
    local sisters = {
        {arg = 'commons', image = 'Commons-logo.svg', prefix = 'commons', display = 'Media', from = 'Commons'},
return result
        {arg = 'species', image = 'Wikispecies-logo.svg', prefix = 'wikispecies', display = 'Species directories', from = 'Wikispecies'},
        {arg = 'voy', image = 'Wikivoyage-Logo-v3-icon.svg', prefix = 'voy', display = 'Travel guides', from = 'Wikivoyage'},
        {arg = 'n', image = 'Wikinews-logo.svg', prefix = 'wikinews', display = 'News stories', from = 'Wikinews'},
        {arg = 'wikt', image = 'Wiktionary-logo-v2.svg', prefix = 'wiktionary', postfix = 'English', display = 'Definitions', from = 'Wiktionary'},
        {arg = 'b', image = 'Wikibooks-logo.svg', prefix = 'wikibooks', display = 'Textbooks', from = 'Wikibooks'},
        {arg = 'q', image = 'Wikiquote-logo.svg', prefix = 'wikiquote', display = 'Quotations', from = 'Wikiquote'},
        {arg = 's', image = 'Wikisource-logo.svg', prefix = 'wikisource', display = 'Source texts', from = 'Wikisource'},
        {arg = 'v', image = 'Wikiversity logo 2017.svg', prefix = 'wikiversity', display = 'Learning resources', from = 'Wikiversity'},
        {arg = 'd', image = 'Wikidata-logo.svg', prefix = 'wikidata', display = 'Data', from = 'Wikidata'},
        {arg = 'spoken', image = 'Sound-icon.svg', prefix = 'spoken wikipedia', display = 'Listen to this page', from = 'Spoken Wikipedia'},
    }
    local sisterItems = {}
    for i, t in ipairs(sisters) do
        if args[t.arg] then
            -- Get the image value.
            local image = mw.ustring.format('[[File:%s|30x30px|alt=|link=]]', t.image)
            -- Get the text value.
            local prefix = t.prefix
            local search = args[t.arg .. '-search'] or mw.title.getCurrentTitle().text
            local postfix = t.postfix
            postfix = postfix and ('#' .. postfix) or ''
            local display = t.display
            local from = t.from
            local text = mw.ustring.format(
                '[[%s:Special:Search/%s%s|%s]]<br />from %s',
                prefix,    search,    postfix, display, from
            )
            if t.arg == 'spoken' then
            text = mw.ustring.format('%s on %s<br />[[File:%s]]',
                display, from, args[t.arg]  
                )
            end
            -- Add the values to the items table.
            table.insert(sisterItems, {image, text})
        end
    end
    local sisterHeading = "Find out more on<br />Wikipedia's"
    local sisterSubheading = "'''[[Wikipedia:Wikimedia sister projects|Sister projects]]'''"
    local sisterRow = makeRow(sisterItems, sisterHeading, sisterSubheading, {swapHeadingSize = true})
    table.insert(rows, sisterRow)
 
    -- Make the table.
    local root = mw.html.create('table')
    root
        :attr('role', 'presentation')
        :addClass('subjectbar')
        :addClass('noprint')
        :addClass('metadata')
        :addClass('plainlist')
        :wikitext(table.concat(rows, makeHorizontalRule()))
 
    return tostring(root)
end
end


function p.main(frame)
function p.main(frame)
     -- If called via #invoke, use the args passed into the invoking template, or the args passed to #invoke if any exist. Otherwise
     -- If called via #invoke, use the args passed into the invoking template,
     -- assume args are being passed directly in from the debug console or from another Lua module.
    -- or the args passed to #invoke if any exist. Otherwise assume args are
     local origArgs
     -- being passed directly in from the debug console or from another Lua module.
    if frame == mw.getCurrentFrame() then
     local args = getArgs(frame)
        origArgs = frame:getParent().args
     return p._main(args)
        for k, v in pairs(frame.args) do
            origArgs = frame.args
            break
        end
    else
        origArgs = frame
    end
    -- Remove blank arguments.
    local args = {}
    for k, v in pairs(origArgs) do
        if v ~= '' then
            args[k] = v
        end
    end
     return frame:extensionTag{ name = 'templatestyles', args = { src = 'Subject bar/styles.css'} } .. p._main(args) .. redlinkedportal
end
end


return p
return p

Latest revision as of 14:08, 14 October 2026

Documentation for this module may be created at Module:Subject bar/doc

require('strict')

local getArgs = require('Module:Arguments').getArgs
local yesNo = require('Module:Yesno')

-- Determine whether we're being called from a sandbox
local isSandbox = mw.getCurrentFrame():getTitle():find('sandbox', 1, true)
local sandbox = isSandbox and '/sandbox' or ''

local p = {}

local sisters = {'commons','species','voy','n','wikt','b','q','s','v','iw','iw1','iw2','d','f'}

local function findNumericArgs(key, args)
	local pattern = "^"..key.."_?(%d+)$"  -- pattern to match
	local values = {}
	for k, v in pairs(args) do  --- loop through all arguments
		local ord = tonumber(mw.ustring.match(k,pattern)) --- if "foo_?%d+", extract number
		if ord then
			values[ord] = v
		end
	end
	if args[key] ~= nil then
		values[1] = args[key]
	end
	local compressSparseArray = require('Module:TableTools').compressSparseArray
	values = compressSparseArray(values)  --- squeeze out gaps/nils in values, keep ordering
	return values
end

function p._main(args)
	local result = ""
		
	local hasPortal = false
	for key, _ in pairs(args) do
		if mw.ustring.sub(key,1,6) == 'portal' or tonumber(key) then
			hasPortal = true
			break
		end
	end
	
	local hasSister = yesNo(args.auto,true) or yesNo(args.author,true) or yesNo(args.cookbook,true)
	for _, sister in ipairs(sisters) do
		if hasSister then
			break
		end
		if yesNo(args[sister],true) or yesNo(args[sister..'-search'],true) then
			hasSister = true
		end
	end

	if hasPortal then
		local portalList = findNumericArgs("portal",args)
		for _, positional in ipairs(args) do
			table.insert(portalList, positional)
		end
		local portalBar = require('Module:Portal bar'..sandbox)._main
		result = result..portalBar(portalList, {tracking=args.tracking, qid=args.qid})
	end
	
	if hasSister then
		local sisterArgs = {auto=1, bar=1, trackSingle=not hasPortal}
		sisterArgs[1] = args.search
		for _, k in ipairs({'author','commonscat','cookbook','display','tracking','qid'}) do
			sisterArgs[k] = args[k]
		end
    	for _, t in ipairs(sisters) do
    		sisterArgs[t] = args[t..'-search'] or args[t]
    	end
    	local sisterBar = require('Module:Sister project links'..sandbox)._main
		result = result..sisterBar(sisterArgs)
	end
	
	return result
end

function p.main(frame)
    -- If called via #invoke, use the args passed into the invoking template,
    -- or the args passed to #invoke if any exist. Otherwise assume args are
    -- being passed directly in from the debug console or from another Lua module.
    local args = getArgs(frame)
    return p._main(args)
end

return p