Module:Main page: Difference between revisions
Jump to navigation
Jump to search
No edit summary Tag: Reverted |
No edit summary Tags: Manual revert Reverted |
||
| Line 1: | Line 1: | ||
local p = {} | local p = {} | ||
local h = {} | |||
-- | -- merge args from frame and frame:getParent() | ||
function | 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 | |||
local layouts = {'desktop', 'tablet', 'mobile'} | |||
for _,layout in pairs(layouts) do | |||
-- collapse consecutive line breaks and spaces, then trim | |||
-- we need to check for permutations of " \n" because trim can't clean that up if it's in the middle of the string | |||
args[layout] = mw.text.trim(args[layout]):gsub("\n\n+", "\n"):gsub(" +", " "):gsub(" \n", "\n"):gsub("\n ", "\n") | |||
-- check if columns are consistent in this layout | |||
local warn = false | |||
local last_column_count = 0 | |||
local current_column_count = 0 | |||
for _,row in pairs(mw.text.split(mw.text.trim(args[layout]), '\n')) do | |||
current_column_count = #mw.text.split(row, '%s') --count elements in this row | |||
if last_column_count == 0 then | |||
last_column_count = current_column_count | |||
elseif last_column_count ~= current_column_count then | |||
warn = true | |||
end | |||
end | |||
if warn then | |||
mw.addWarning( 'ERROR: the ' .. layout .. ' layout does not have a consistent number of columns in each row. This will result in all the boxes merging into one.') | |||
end | |||
end | |||
-- parse the arguments into CSS variables that contain legal syntax for grid-template-areas | |||
local desktop_var = "--main-page-layout--desktop: '" .. string.gsub(args['desktop'], '\n', "' '") .. "';" | |||
local tablet_var = "--main-page-layout--tablet: '" .. string.gsub(args['tablet' ], '\n', "' '") .. "';" | |||
local mobile_var = "--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_var = desktop_var .. '--main-page-layout-columns--desktop: '.. desktop_cols ..';' | |||
end | |||
if tablet_cols ~= '' then | |||
tablet_var = tablet_var .. '--main-page-layout-columns--tablet: '.. tablet_cols ..';' | |||
end | |||
if mobile_cols ~= '' then | |||
mobile_var = mobile_var .. '--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 | |||
-- 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_var .. tablet_var .. mobile_var):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 | end | ||
return p | return p | ||
Revision as of 04:14, 13 November 2025
Script error: The function "show" does not exist.
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
local layouts = {'desktop', 'tablet', 'mobile'}
for _,layout in pairs(layouts) do
-- collapse consecutive line breaks and spaces, then trim
-- we need to check for permutations of " \n" because trim can't clean that up if it's in the middle of the string
args[layout] = mw.text.trim(args[layout]):gsub("\n\n+", "\n"):gsub(" +", " "):gsub(" \n", "\n"):gsub("\n ", "\n")
-- check if columns are consistent in this layout
local warn = false
local last_column_count = 0
local current_column_count = 0
for _,row in pairs(mw.text.split(mw.text.trim(args[layout]), '\n')) do
current_column_count = #mw.text.split(row, '%s') --count elements in this row
if last_column_count == 0 then
last_column_count = current_column_count
elseif last_column_count ~= current_column_count then
warn = true
end
end
if warn then
mw.addWarning( 'ERROR: the ' .. layout .. ' layout does not have a consistent number of columns in each row. This will result in all the boxes merging into one.')
end
end
-- parse the arguments into CSS variables that contain legal syntax for grid-template-areas
local desktop_var = "--main-page-layout--desktop: '" .. string.gsub(args['desktop'], '\n', "' '") .. "';"
local tablet_var = "--main-page-layout--tablet: '" .. string.gsub(args['tablet' ], '\n', "' '") .. "';"
local mobile_var = "--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_var = desktop_var .. '--main-page-layout-columns--desktop: '.. desktop_cols ..';'
end
if tablet_cols ~= '' then
tablet_var = tablet_var .. '--main-page-layout-columns--tablet: '.. tablet_cols ..';'
end
if mobile_cols ~= '' then
mobile_var = mobile_var .. '--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
-- 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_var .. tablet_var .. mobile_var):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