Module

From MB Wiki
Revision as of 08:16, 11 November 2025 by Tama07 (talk | contribs) (Created page with "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(fram...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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