Jump to content

Module:Subject bar/sandbox

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Hike395 (talk | contribs) at 23:27, 3 December 2021 (experiment: call portal bar if no sister links provided). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
local getPortalImage = require('Module:Portal').image
local sisterLink = require('Module:Sister project links')._sisterlink
local portalBar = require('Module:Portal bar')._main
local compressSparseArray = require('Module:TableTools').compressSparseArray

local p = {}

local function getArgNums(prefix, args)
    -- Returns a table containing the numbers of the arguments that exist for
    -- the specified prefix. For example, if the prefix was 'data', and 'data1',
    -- 'data2', and 'data5' exist, it would return {1, 2, 5}.
    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 makeItem(image, text)
    local root = mw.html.create('div')
    root
        :addClass('subjectbar-item')
        :tag('div')
            :wikitext(image)
            :done()
        :tag('div')
            :wikitext(text)
    return tostring(root)
end

local function makeRow(items, heading, subheading, options)
    if #items < 1 then return end
    local swapHeadingSize = type(options) == 'table' and options.swapHeadingSize or false
    local row = mw.html.create('div')
    row
    	:addClass('subjectbar-row')
        :tag('div')
	        :addClass('subjectbar-heading')
            :tag('span')
                :css('font-size', swapHeadingSize and '90%' or '125%')
                :wikitext(heading)
                :done()
            :tag('span')
                :css('font-size', swapHeadingSize and '125%' or '90%')
                :wikitext(subheading)
    local list = row:tag('div'):addClass('subjectbar-cell')
    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 thisPageNS = mw.title.getCurrentTitle().namespace
	if (thisPageNS == 1) -- Talk
		or (thisPageNS == 2) -- User
		or (thisPageNS == 3) -- User talk
		or (thisPageNS == 5) -- Wikipedia talk
		or (thisPageNS == 7) -- File talk
		or (thisPageNS == 11) -- Template talk
		or (thisPageNS == 15) -- Category talk
		or (thisPageNS == 101) -- Portal talk
		or (thisPageNS == 118) -- Draft
		or (thisPageNS == 119) -- Draft talk
		or (thisPageNS == 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)
		or (string.match(thisPageLC, "/doc") ~= nil)
		or (string.match(thisPageLC, "/test") ~= nil) then
		return false
	end
	return true
end

local redlinkedportal = ""

local sisters = {
    {arg = 'commons', image = 'Commons-logo.svg', display = 'Media'},
    {arg = 'species', image = 'Wikispecies-logo.svg', display = 'Species directories'},
    {arg = 'voy', image = 'Wikivoyage-Logo-v3-icon.svg', display = 'Travel guides'},
    {arg = 'n', image = 'Wikinews-logo.svg', display = 'News stories'},
    {arg = 'wikt', image = 'Wiktionary-logo-v2.svg', display = 'Definitions'},
    {arg = 'b', image = 'Wikibooks-logo.svg', display = 'Textbooks'},
    {arg = 'q', image = 'Wikiquote-logo.svg', display = 'Quotations'},
    {arg = 's', image = 'Wikisource-logo.svg', display = 'Source texts'},
    {arg = 'v', image = 'Wikiversity logo 2017.svg', display = 'Learning resources'},
    {arg = 'd', image = 'Wikidata-logo.svg', display = 'Data'},
    {arg = 'spoken', image = 'Sound-icon.svg'},
}

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
		if k == key then    --- if argument is just "foo", put it first
			values[1] = v
		else
			ord = tonumber(mw.ustring.match(k,pattern)) --- if "foo_?%d+", extract number
			if ord then
				values[ord+2] = v  --- put value into list at number+2 (to keep "foo" first, even for foo0)
			end
		end
	end
	values = compressSparseArray(values)  --- squeeze out gaps/nils in values, keep ordering
end

function p._main(args)
	-- Tracking is on by default.
	-- It is disabled if any of the following is true
	-- 1/ the parameter "tracking" is set to 'no, 'n', or 'false'
	-- 2/ the current page fails the namespace tests in checkTrackingNamespace()
	-- 3/ the current page fails the pagename tests in checkTrackingPagename()
	if (args.tracking == 'no') or (args.tracking == 'n') or (args.tracking == 'false')
		or (checkTrackingNamespace() == false) or (checkTrackingPagename() == false) then
		trackingEnabled = false
		end

	local hasSister = false
	for _, sister in ipairs(sisters) do
		if args[sister.arg] ~= nil then
			hasSister = true
			break
		end
	end
	if not hasSister then
		local portalList = findNumericArgs("portal",args)
		return portalBar(portalList, {tracking=trackingEnabled})
	end

    local rows = {}

    -- 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
        return image, text
    end
    local portalRow = makeNumberedRow(
    	'portal', args, portalHeading, portalSubheading, getPortalItemVals
    )
    table.insert(rows, portalRow)

    -- Get the sister projects row text.
    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.
            if t.arg == 'spoken' then
            	text = mw.ustring.format('Listen to this page: [[File:%s]]',
            		args.spoken)
            else
            	local prefix = (t.arg == 'commons' and 'c') or t.arg
            	local params = {args[t.arg..'-search'], prefix=prefix, information=t.display, qid=args.qid}
            	params[prefix] = "y"
            	text = sisterLink(params)
            end
            if text and text ~= "" then
              -- Add the values to the items table.
              table.insert(sisterItems, {image, text})
            end
        end
    end
    local sisterHeading = "Find out more on 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('div')
    root
        :addClass('subjectbar')
        :addClass('noprint')
        :addClass('metadata')
        :addClass('plainlist')
        :wikitext(table.concat(rows))

    return tostring(root)
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 origArgs
    if frame == mw.getCurrentFrame() then
        origArgs = frame:getParent().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 mw.text.trim(frame:extensionTag{
		name = 'templatestyles', args = { src = 'Module:Subject bar/styles.css'}
    } .. p._main(args) .. redlinkedportal)
end

return p