Please note that some information on this wiki is still based on the demo version.
If you notice any errors, feel free to correct them.

Module:Main page: Difference between revisions

From Super Fantasy Kingdom Official Wiki
imported>Cadaei
from https://defaultloadout.wiki.gg/wiki/Module:Main_page
 
dlw>Mr Pie 5
Ported modification from Untitled7 that forces the boxes to appear in order of appearance in the HTML.
Line 1: Line 1:
local trim = mw.text.trim
local p = {}
local p = {}
local h = {}
-- merge args from frame and frame:getParent()
function h.mergeArgs(frame)
local inputArgs = {}
for k, v in pairs(frame.args) do
v = mw.text.trim(tostring(v))
if v ~= '' then
inputArgs[k] = v
end
end
for k, v in pairs(frame:getParent().args) do
v = mw.text.trim(v)
if v ~= '' then
inputArgs[k] = v
end
end
return inputArgs
end
--------------------------------------------------------------------


function p.main(frame)
function p.main(frame)
local args = h.mergeArgs(frame)
-- DEBUG
-- use the rootpage parameter if given, otherwise use the current page name
-- local frame = mw.getCurrentFrame()
local rootpage = args['rootpage'] or mw.title.getCurrentTitle().fullText
-- frame.args['desktop'] = '\nwelcome welcome welcome\nabout about links\n'
-- frame.args['tablet'] = '\nwelcome welcome\nabout links\n'
-- frame.args['mobile'] = '\nwelcome\nabout\nlinks\n'
-- END DEBUG
 
local sitename = frame:preprocess(mw.message.new('mainpage'):plain())
-- parse the arguments into CSS variables that contain legal syntax for grid-template-areas
-- parse the arguments into CSS variables that contain legal syntax for grid-template-areas
local desktop = "--main-page-layout--desktop: '" .. string.gsub(trim(frame.args['desktop']), '\n', "' '") .. "';"
local desktop = "--main-page-layout--desktop: '" .. string.gsub(args['desktop'], '\n', "' '") .. "';"
local tablet =  "--main-page-layout--tablet: '"  .. string.gsub(trim(frame.args['tablet' ]), '\n', "' '") .. "';"
local tablet =  "--main-page-layout--tablet: '"  .. string.gsub(args['tablet' ], '\n', "' '") .. "';"
local mobile =  "--main-page-layout--mobile: '"  .. string.gsub(trim(frame.args['mobile' ]), '\n', "' '") .. "';"
local mobile =  "--main-page-layout--mobile: '"  .. string.gsub(args['mobile' ], '\n', "' '") .. "';"
-- grid-template-columns
local desktop_cols = trim(string.gsub(frame.args['desktop-columns'] or '', ';', ''))
-- grid-template-columns overrides
local  tablet_cols = trim(string.gsub(frame.args[ 'tablet-columns'] or '', ';', ''))
local desktop_cols = mw.text.trim(string.gsub(args['desktop-columns'] or '', ';', ''))
local  mobile_cols = trim(string.gsub(frame.args[ 'mobile-columns'] or '', ';', ''))
local  tablet_cols = mw.text.trim(string.gsub(args[ 'tablet-columns'] or '', ';', ''))
local  mobile_cols = mw.text.trim(string.gsub(args[ 'mobile-columns'] or '', ';', ''))
-- set the variables used by grid-template-columns
if desktop_cols ~= '' then
if desktop_cols ~= '' then
desktop = desktop .. '--main-page-layout-columns--desktop: '.. desktop_cols ..';'
desktop = desktop .. '--main-page-layout-columns--desktop: '.. desktop_cols ..';'
Line 31: Line 53:
end
end


local boxes = {}
local boxes = {} -- list of all boxes as a simple list, used to set the order of appearance
local seen_boxes = {} -- list of all boxes as a k:v pair, used to filter out duplicates
local boxes_in_layout = {} -- list of layouts, then list of all boxes in that layout
local missing_boxes = {} -- list of layouts, then list of boxes that are *not* included in that layout
-- helper function for the next part, checks if an array-like table contains a value
-- add every box referenced in the layout rules once
function contains(t, entry)
function parse_layout(layout)
for _,value in pairs(t) do
for _,name in pairs(mw.text.split(mw.text.trim(args[layout]), '%s')) do
if value == entry then
if not seen_boxes[name] then
return true
boxes[#boxes+1] = name -- table with numerical keys for set html order
seen_boxes[name] = true
end
end
boxes_in_layout[layout][name] = true
end
end
return false
end
end
-- add every box referenced in the layout rules once
local layouts = {'desktop', 'tablet', 'mobile'}
-- we check all 3 layouts so that typos or other errors will clearly surface
for _,value in pairs(mw.text.split(mw.text.trim(frame.args['desktop'] .. '\n' .. frame.args['tablet'] .. '\n' .. frame.args['mobile']), '%s')) do
-- loop through the layouts the first time to set up the box lists
if not (value == "" or contains(boxes, value)) then
for _,layout in pairs(layouts) do
table.insert(boxes, value)
boxes_in_layout[layout] = {}
missing_boxes[layout] = {}
parse_layout(layout)
end
-- then loop through the layouts a second time because we need to compare those completed lists to check for missing boxes
for _,layout in pairs(layouts) do
for _,name in pairs(boxes) do
if boxes_in_layout[layout][name] ~= true then
mw.addWarning( 'WARNING: the \"' .. name .. '\" box is missing in the ' .. layout .. ' layout. If this is intentional, you can ignore this warning.')
missing_boxes[layout][name] = true
end
end
end
end
end
-- mw.logObject(boxes)
-- start our mp-container wrapper, and add our variables from earlier as inline styles to declare them
-- start our mp-container wrapper, and add our variables from earlier as inline styles to declare them
-- the sitename is added to the dataset so it's easily accessible by mp-edit-links.js and it doesn't need to make its own API call
-- the rootpage is added to the dataset so it's easily accessible by mp-edit-links.js and it doesn't need to make its own API call
local output = '<div id="mp-container" style="' .. desktop .. tablet .. mobile .. '" data-sitename="' .. sitename .. '">'
local output = mw.html.create()
local container = output:tag('div'):attr('id', 'mp-container'):cssText(desktop .. tablet .. mobile):attr('data-rootpage', rootpage)
-- loop through boxes and add the relevant main page subpages into the output
-- loop through boxes and add the relevant main page subpages into the output
for _,box in pairs(boxes) do
for _,box in pairs(boxes) do
if mw.title.new(sitename .. '/' .. box).exists then
mw.ext.VariablesLua.vardefine('imp-variable-id', box) -- using a vardefine lets us pass this directly to the template without going through the user-facing box
output = output .. frame:expandTemplate{ title = ':' .. sitename .. '/' .. box}
local pre_vardefine = ''
for _,layout in pairs(layouts) do
pre_vardefine = pre_vardefine .. (missing_boxes[layout][box] and '0' or '1') .. ','
end
-- formatted as a psuedo-bitmask to reduce variable usage, "<display-on-destop>, <display-on-tablet>, <display-on-mobile>," each value is 0 or 1 (trailing comma is insignificant)
-- expected to be used with #explode in the template receiving the variable
mw.ext.VariablesLua.vardefine('imp-variable-display-box', pre_vardefine)
if mw.title.new(rootpage .. '/' .. box).exists then
container:wikitext(frame:expandTemplate{ title = ':' .. rootpage .. '/' .. box})
else
else
output = output .. frame:expandTemplate{ title = 'Main page box/missing', args = { box } } -- See [[Template:Main page box/missing]]
container:wikitext(frame:expandTemplate{ title = 'Main page box/missing', args = { box, rootpage = rootpage}}) -- See [[Template:Main page box/missing]]
end
end
end
end
output = output .. '</div>'
return output
return output

Revision as of 00:32, 5 April 2025

Documentation for this module may be created at Module:Main page/doc

local p = {}
local h = {}

-- merge args from frame and frame:getParent()
function h.mergeArgs(frame)
	local inputArgs = {}
	
	for k, v in pairs(frame.args) do
		v = mw.text.trim(tostring(v))
		if v ~= '' then
			inputArgs[k] = v
		end
	end
	
	for k, v in pairs(frame:getParent().args) do
		v = mw.text.trim(v)
		if v ~= '' then
			inputArgs[k] = v
		end
	end
	
	return inputArgs
end

--------------------------------------------------------------------

function p.main(frame)

	local args = h.mergeArgs(frame)
	
	-- use the rootpage parameter if given, otherwise use the current page name
	local rootpage = args['rootpage'] or mw.title.getCurrentTitle().fullText
	
	-- parse the arguments into CSS variables that contain legal syntax for grid-template-areas
	local desktop = "--main-page-layout--desktop: '" .. string.gsub(args['desktop'], '\n', "' '") .. "';"
	local tablet =  "--main-page-layout--tablet: '"  .. string.gsub(args['tablet' ], '\n', "' '") .. "';"
	local mobile =  "--main-page-layout--mobile: '"  .. string.gsub(args['mobile' ], '\n', "' '") .. "';"
	
	-- grid-template-columns overrides
	local desktop_cols = mw.text.trim(string.gsub(args['desktop-columns'] or '', ';', ''))
	local  tablet_cols = mw.text.trim(string.gsub(args[ 'tablet-columns'] or '', ';', ''))
	local  mobile_cols = mw.text.trim(string.gsub(args[ 'mobile-columns'] or '', ';', ''))
	
	-- set the variables used by grid-template-columns
	if desktop_cols ~= '' then
		desktop = desktop .. '--main-page-layout-columns--desktop: '.. desktop_cols ..';'
	end
	if tablet_cols ~= '' then
		tablet = tablet .. '--main-page-layout-columns--tablet: '.. tablet_cols ..';'
	end
	if mobile_cols ~= '' then
		mobile = mobile .. '--main-page-layout-columns--mobile: '.. mobile_cols ..';'
	end

	local boxes = {} -- list of all boxes as a simple list, used to set the order of appearance
	local seen_boxes = {} -- list of all boxes as a k:v pair, used to filter out duplicates
	local boxes_in_layout = {} -- list of layouts, then list of all boxes in that layout
	local missing_boxes = {} -- list of layouts, then list of boxes that are *not* included in that layout
	
	-- add every box referenced in the layout rules once
	function parse_layout(layout)
		for _,name in pairs(mw.text.split(mw.text.trim(args[layout]), '%s')) do
			if not seen_boxes[name] then
				boxes[#boxes+1] = name -- table with numerical keys for set html order
				seen_boxes[name] = true
			end
			boxes_in_layout[layout][name] = true
		end
	end
	
	local layouts = {'desktop', 'tablet', 'mobile'}
	
	-- loop through the layouts the first time to set up the box lists
	for _,layout in pairs(layouts) do
		boxes_in_layout[layout] = {}
		missing_boxes[layout] = {}
		parse_layout(layout)
	end
	
	-- then loop through the layouts a second time because we need to compare those completed lists to check for missing boxes
	for _,layout in pairs(layouts) do
		for _,name in pairs(boxes) do
			if boxes_in_layout[layout][name] ~= true then
				mw.addWarning( 'WARNING: the \"' .. name .. '\" box is missing in the ' .. layout .. ' layout. If this is intentional, you can ignore this warning.')
				missing_boxes[layout][name] = true	
			end
		end
	end
	
	-- start our mp-container wrapper, and add our variables from earlier as inline styles to declare them
	-- the rootpage is added to the dataset so it's easily accessible by mp-edit-links.js and it doesn't need to make its own API call
	local output = mw.html.create()
	local container = output:tag('div'):attr('id', 'mp-container'):cssText(desktop .. tablet .. mobile):attr('data-rootpage', rootpage)
	
	-- loop through boxes and add the relevant main page subpages into the output
	for _,box in pairs(boxes) do
		mw.ext.VariablesLua.vardefine('imp-variable-id', box) -- using a vardefine lets us pass this directly to the template without going through the user-facing box
		
		local pre_vardefine = ''
		for _,layout in pairs(layouts) do
			pre_vardefine = pre_vardefine .. (missing_boxes[layout][box] and '0' or '1') .. ','
		end
		-- formatted as a psuedo-bitmask to reduce variable usage, "<display-on-destop>, <display-on-tablet>, <display-on-mobile>," each value is 0 or 1 (trailing comma is insignificant)
		-- expected to be used with #explode in the template receiving the variable
		mw.ext.VariablesLua.vardefine('imp-variable-display-box', pre_vardefine)
		
		if mw.title.new(rootpage .. '/' .. box).exists then
			container:wikitext(frame:expandTemplate{ title = ':' .. rootpage .. '/' .. box})
		else
			container:wikitext(frame:expandTemplate{ title = 'Main page box/missing', args = { box, rootpage = rootpage}}) -- See [[Template:Main page box/missing]]
		end
	end
	
	return output
end

return p