Module:PageSwitcher

This module is used by Template:PageSwitcher.

{{PageSwitcher
|page1=Module:PageSwitcher
|page2=Module:PageSwitcher/doc
|label2=Docs
|page3=Codex:
|page4=/subpage
}}

require('strict')

local PageSwitcher = {}
local metatable = {}
local methods = {}

local libraryUtil = require('libraryUtil')
local checkType = libraryUtil.checkType
local checkTypeMulti = libraryUtil.checkTypeMulti

metatable.__index = methods

metatable.__tostring = function(self)
	return tostring(self:render())
end

--------------------------------------------------
-- constructor
--------------------------------------------------

function PageSwitcher.new(config)

	local instance = {
		config = config or {},
		entries = {},
		categories = {}
	}

	setmetatable(instance, metatable)
	return instance
end

--------------------------------------------------
-- page button
--------------------------------------------------

function methods:addButton(data)

	checkType('PageSwitcher.addButton', 1, self, 'table')
	checkType('PageSwitcher.addButton', 2, data, 'table')

	local button = mw.html.create('div')
		:addClass('pageswitcher__button')

	if data.first then button:addClass('pageswitcher__button--first') end
	if data.last then button:addClass('pageswitcher__button--last') end
	if data.current then button:addClass('pageswitcher__button--current') end

	button:wikitext(string.format("'''[[%s|%s]]'''", data.path, data.label))

	table.insert(self.entries, tostring(button))
end

--------------------------------------------------
-- render container
--------------------------------------------------

function methods:render(inner)

	checkType('PageSwitcher.render', 1, self, 'table')
	checkTypeMulti('PageSwitcher.render', 2, inner, {'string','table','nil'})

	if type(inner) == 'table' then
		inner = table.concat(inner)
	elseif inner == nil then
		inner = table.concat(self.entries)
	end

	local outer = mw.html.create('div')
		:addClass('pageswitcher__container')

	outer:tag('div')
		:addClass('pageswitcher__row')
		:wikitext(inner)

	local frame = mw.getCurrentFrame()

	return frame:extensionTag{
		name = 'templatestyles',
		args = { src = 'Module:PageSwitcher/styles.css' }
	}
	.. tostring(outer)
	.. table.concat(self.categories)
end

--------------------------------------------------
-- path resolver
--------------------------------------------------

local function resolvePath(basePage, pageArg)

	if pageArg:sub(-1) == ':' then
		local _, page = basePage:match("^(.-):(.*)$")
		return pageArg .. (page or basePage)

	elseif pageArg:sub(1,1) == '/' then
		return basePage .. pageArg
	end

	return pageArg
end

--------------------------------------------------
-- build from template args
--------------------------------------------------

function PageSwitcher.fromArgs(frame)

	local args = require('Module:Arguments').getArgs(frame)
	local instance = PageSwitcher.new()

	local current = args['current full']
	local pages = {}

	local i = 1
	while args['page' .. i] do

		local rawPath = args['page' .. i]
		local path = resolvePath(current, rawPath)

		local label = args['label' .. i]
			or rawPath:gsub("^/",""):gsub(":$","")

		table.insert(pages,{
			label = label,
			path = path,
			current = (path == current)
		})

		i = i + 1
	end

	for index, page in ipairs(pages) do
		instance:addButton{
			label = page.label,
			path = page.path,
			first = (index == 1),
			last = (index == #pages),
			current = page.current
		}
	end

	return instance:render()
end

return PageSwitcher