Module:Portal navigation

require('strict')
local p = {}
local getArgs = require('Module:Arguments').getArgs
local yesno = require("Module:Yesno")

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

local function luminance(color)
	-- 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(color, '#', '')
	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)
	
	return 0.2126 * r + 0.7152 * g + 0.0722 * b
end

local function generate_header(root, args)
	local header = root:tag('div')
	header:css('font-size','1.6875em')
	header:css('border-radius','2px')
	header:css('font-weight','bold')
	header:css('padding','0.25em')
	header:css('background',args.themecolor)
	header:css('color',luminance(args.themecolor) > 0.1791 and '#000' or '#fff')
	header:cssText(args.headerstyle)
	header:wikitext(args.portalname)
	if args.portalicon then
		local span = header:tag('span')
		span:css('padding','0.3em')
		span:css('display','inline-block')
		span:css('margin-right','0.5em')
		span:wikitext(portalicon)
	end
	return header
end

local function generate_tab(body, index, args)
	local container = body:tag('li')
	container:css('display','inline-block')
	container:css('position','relative')
	container:css('vertical-align','top')
	container:css('margin','0')
			
	-- Create the tab itself
			
	local entry = container:tag('span')
	entry:css('display','inline-block')
	entry:css('margin','1em')
	entry:css('padding-bottom','0.5em')
	entry:css('font-weight','bold')
	if index == args.active then
		if not args.subtabs[index] or args.hidesubnav then
			entry:css('border-bottom','0.3em solid '..args.themecolor)
		else
			entry:css('margin-bottom','0')
		end
	else
		entry:css('border-bottom','0.3em solid #c8ccd1')
	end
			
	if args.tabsicons[index] then
		local icon = entry:tag('span')
		icon:css('margin-right','0.75em')
		icon:wikitext(args.tabsicons[index])
	end
	entry:wikitext(args.tabs[index])
	
	-- If the tab is active, show the subnav if there is any
			
	if index == args.active and args.subtabs[index] and not args.hidesubnav then
		local subnav = container:tag('ul')
		subnav:css('font-size','95%')
		subnav:css('margin','0 1em')
		subnav:css('padding','1.125em 0')
		local borderColor = '0.35em solid '..args.themecolor
		subnav:css('border-top',borderColor)
		subnav:css('border-bottom',borderColor)
		subnav:css('list-style','none')
		for _, subpagelink in ipairs(args.subtabs[index]) do
			local link = subnav:tag('li')
			link:css('margin','0')
			link:wikitext(subpagelink)
		end
	end
	return container
end

function p._render(args)
	local tabs = {}
	local subtabs = {}
	local tabsicons = {}
    -- Default values
	args.portalname = args.portalname or 'Portal'
	args.themecolor = args.themecolor or '#54595d'
	for _, key in ipairs({'wrc','hidenav','hidesubnav'}) do
		args[key] = yesno(args[key])
	end
	args.active = tonumber(args.active)
	for key, value in pairs(args) do
		local id = tonumber(mw.ustring.match(key,'^tab(%d+)$'))
		if id then
			tabs[id] = value
		else
			id = tonumber(mw.ustring.match(key,'^icon(%d+)$'))
			if id then
				tabsicons[id] = value
			else
				local primetab, subtab = mw.ustring.match(key,'^subtab(%d+)-(%d+)$')
				if primetab and subtab then
					primetab = tonumber(primetab)
					subtab = tonumber(subtab)
					if not subtabs[primetab] then
						subtabs[primetab] = {}
					end
					subtabs[primetab][subtab] = value
				end
			end
		end
	end
	args.tabs = tabs
	args.subtabs = subtabs
	args.tabsicons = tabsicons
		
	-- Constructing header
	
	local root = mw.html.create('div')
	if args.wrc then
		local badgeargs = {}
		if wrcadditional then
			badgeargs['additional'] = args.wrcadditional
		end

		root:wikitext(frame:expandTemplate{
			title = 'Wikimedia Resource Center badge',
			args = badgeargs })
	end
	generate_header(root, args)
	
	-- Constructing the rest
	
	if not args.hidenav then
		local body = root:tag('ul')
		body:css('font-size','1.125em')
		body:css('list-style','none')
		body:css('margin','0 0 1.125em 0')
		
		local tabindex = {}
		for index, _ in pairs(tabs) do
			table.insert(tabindex,index)
		end
		table.sort(tabindex)
		
		for _, index in ipairs(tabindex) do
			generate_tab(body, index, args)
		end
	end
	local clear = root:tag('div')
	clear:css('clear','both')
	return tostring(root)
end

function p.render(frame)
	local args = getArgs(frame)
	return p._render(args)
end

return p

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.