Module:Portal navigation/sandbox
Appearance
![]() | This is the module sandbox page for Module:Portal navigation (diff). |
This module has one method, render: {{#invoke:Portal navigation|render| ... }}
.
For more information, see Template:Portal navigation/doc. For test cases, see Template:Portal navigation/testcases.
require('strict')
local p = {}
local yesno = require("Module:Yesno")
local function get_portalicon(root, portalicon)
if portalicon then
local span = root:node('span')
span:css('padding','0.3em')
span:css('display','inline-block')
span:css('margin-right','0.5em')
span:wikitext(portalicon)
end
return root
end
local function converttolinearrgb(c)
c = tonumber(c, 16)
c = c / 255.0
if c <= 0.03928 then
c = c/12.92321 -- Correct constant from sRGB standard
else
c = ((c+0.055)/1.055) ^ 2.4
end
return c
end
function p.render(frame)
-- Default values
local portalname = 'Portal'
local tabs = {}
local subtabs = {}
local wrc = 0
-- Default values (customizations)
local themecolor = '#54595d'
local headerstyle = nil
local tabsicons = {}
local wrcadditional = nil
local id = nil
local active = nil
-- Populating variables
for key, value in pairs(frame:getParent().args) do
if key == 'portalname' then
portalname = value
elseif key == 'portalicon' then
portalicon = value
elseif key == 'active' then
active = tonumber(value)
elseif key == 'wrc' then
wrc = value
elseif key == 'themecolor' then
themecolor = value
elseif key == 'headerstyle' then
headerstyle = value
elseif key == 'hidenav' then
hidenav = yesno(value)
elseif key == 'hidesubnav' then
hidesubnav = yesno(value)
elseif key == 'wrcadditional' then
wrcadditional = value
elseif string.find(key, 'tab') ~= nil
and string.find(key, 'subtab') == nil then -- matches tab1, tab2, ...
id = string.gsub(key, 'tab', '')
id = tonumber(id)
tabs[id] = value
elseif string.find(key, 'icon') ~= nil then -- matches icon1, icon2, etc.
id = string.gsub(key, 'icon', '')
id = tonumber(id)
tabsicons[id] = value
elseif string.find(key, 'subtab') ~= nil then -- matches subtab1-1, etc.
id = string.gsub(key, 'subtab', '')
-- Subtab params take the form [prime tab]-[sub tab]
id = mw.text.split(id, '-')
primetab = tonumber(id[1])
subtab = tonumber(id[2])
if subtabs[primetab] == nil then
subtabs[primetab] = {}
end
subtabs[primetab][subtab] = value
end
end
-- Constructing header
-- Relevant variables: portalname, wrc, themecolor, headerstyle
-- The text color in the header is automatically chosen based on the best contrast
-- https://stackoverflow.com/questions/3942878/how-to-decide-font-color-in-white-or-black-depending-on-background-color
local rgb = string.gsub(themecolor, '#', '')
rgb = mw.text.split(rgb, '')
local r, g, b
if #rgb == 6 then
r = rgb[1] .. rgb[2]
g = rgb[3] .. rgb[4]
b = rgb[5] .. rgb[6]
elseif #rgb == 3 then
r = rgb[1] .. rgb[1]
g = rgb[2] .. rgb[2]
b = rgb[3] .. rgb[3]
end
r = converttolinearrgb(r)
g = converttolinearrgb(g)
b = converttolinearrgb(b)
local luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b
local root = mw.html.create('div')
if wrc == '1' or wrc == 1 or wrc == 'true' or wrc == true or wrc == 'yes' then
badgeargs = {}
if wrcadditional ~= nil then
badgeargs['additional'] = wrcadditional
end
root:wikitext(frame:expandTemplate{
title = 'Wikimedia Resource Center badge',
args = badgeargs })
end
local header = root:node('div')
header:css('font-size','1.6875em')
header:css('border-radius','2px')
header:css('padding','0.25em')
header:css('background',themecolor)
header:css('color',luminance > 0.179 and '#000' or '#fff')
header:cssText(headerstyle)
-- Applying customizations to headerstyle
if headerstyle ~= '' then
headerstyle = ' ' .. headerstyle
end
header:wikitext(portalname)
get_portalicon(portalicon, header)
-- Constructing the rest
-- Relevant variables: themecolor tabs tabsicons active subtabs
if hidenav ~= true then
local body = root:node('div')
body:css('font-size','1.125em')
body:css('margin-bottom','1.125em')
for index, pagelink in ipairs(tabs) do
local container = body:node('div')
container:css('display','inline-block')
container:css('position','relative')
container:css('vertical-align','top')
local entry = container:node('div')
entry:css('display','inline-block')
entry:css('margin','1em')
entry:css('padding-bottom','0.5em')
entry:css('font-weight','bold')
-- Create the tab itself
if index == active then
if subtabs[index] == nil or hidesubnav == true then
entry:css('border-bottom','0.3em solid '..themecolor)
else
entry:css('margin-bottom','0')
end
else
entry:css('border-bottom','0.3em solid #c8ccd1')
end
if tabsicons[index] ~= nil then
local icon = entry:node('span')
icon:css('margin-right','0.75em')
icon:wikitext(tabsicons[index])
end
entry:wikitext(pagelink)
-- If the tab is active, show the subnav if there is any
if index == active and subtabs[index] ~= nil and hidesubnav ~= true then
local subnav = container:node('ul')
subnav:css('font-size','95%')
subnav:css('margin','0 1em')
subnav:css('padding','1.125em 0')
local borderColor = '0.35em solid'..themecolor
subnav:css('border-top',borderColor)
subnav:css('border-bottom',borderColor)
subnav:css('list-style','none')
for _, subpagelink in ipairs(subtabs[index]) do
local link = subnav:node('li')
link:wikitext(subpagelink)
end
end
end
end
local clear = root:node('div')
clear:css('clear','both')
return tostring(root)
end
return p