Module:Listbox: Difference between revisions
Jump to navigation
Jump to search
Want an adless experience? Log in or Create an account.
(respect 'exclude' extra property, and put the json error tooltip on the right property) |
m (add result to json error message, hopefully it's helpful) |
||
Line 33: | Line 33: | ||
else | else | ||
page.extra = { | page.extra = { | ||
name = page.text .. mw.getCurrentFrame():expandTemplate{ title = 'Tt', args = { 'PARSING ERROR: Please ensure the argument to \'extra\' in this page\'s invocation of \'Cat\' is valid JSON' } } | name = page.text .. mw.getCurrentFrame():expandTemplate{ title = 'Tt', args = { 'PARSING ERROR: Please ensure the argument to \'extra\' in this page\'s invocation of \'Cat\' is valid JSON. Error: ' .. result } } | ||
} | } | ||
end | end |
Revision as of 00:47, June 26, 2020
Documentation for this module may be created at Module:Listbox/doc
local Box = require( 'Module:Box' ).Box local Lazy = require( 'Module:Lazy' ) -- may load: Tabs, Gallery function getCategoryProps( categoryName ) local categoryContent = mw.title.new( categoryName, 'Category' ):getContent() local props = {} for match in string.gmatch( categoryContent, '{{Prop|([^}]*)}}' ) do local prop, value = unpack(mw.text.split( match, '|' )) -- table if multiple values, value if one value, true if no values (i.e. flag) props[prop] = value and string.match( value, ',' ) and mw.text.split( value, ',' ) or value or true end return props end function getPageTree( categoryName, expandVariants ) -- get all pages in the category local pages = mw.ext.dpl.getPages{ category = categoryName, ordermethod = 'sortkey', order = 'ascending' } -- organize them according to metadata local pageTree = { default = {} } for _, page in ipairs( pages ) do -- get metadata if page.extra then -- remove extra from sortkey page.sortkey = string.sub( page.sortkey, 1, -string.len( page.extra ) - 2 ) local success, result = pcall( mw.text.jsonDecode, page.extra ) if success then page.extra = result else page.extra = { name = page.text .. mw.getCurrentFrame():expandTemplate{ title = 'Tt', args = { 'PARSING ERROR: Please ensure the argument to \'extra\' in this page\'s invocation of \'Cat\' is valid JSON. Error: ' .. result } } } end else page.extra = {} end -- add page to group page.__index = page -- allow variants to fall back to page page.extra.__index = page.extra -- allow variants' extra to fall back to page's extra local variants = expandVariants and page.extra.variants or {{}} -- that's a table containing a single table (variant) with no properties (overrides) for _, variant in ipairs( variants ) do setmetatable( variant, page.extra ) if not variant.exclude then if not variant.group then variant.group = 'default' end if not pageTree[variant.group] then pageTree[variant.group] = {} end pageTree[variant.group][#pageTree[variant.group] + 1] = setmetatable( { extra = variant }, page ) end end end return pageTree end function buildGallery( pages ) local Gallery = Lazy.load( 'Module:Gallery' ).Gallery local gallery = Gallery.new{ widths = '62px', heights = '62px' } for _, page in ipairs( pages ) do gallery:addFile( page.extra.image or 'No Image.png', '[[' .. page.text .. '|' .. (page.extra.name or page.text) .. ']]', { link = page.text, alt = page.extra.name or page.text } ) end return gallery:render() end function buildGalleries( categoryProps, pageTree ) local Gallery = Lazy.load( 'Module:Gallery' ).Gallery local defaultGallery = nil if pageTree.default then defaultGallery = buildGallery( pageTree.default ) end if categoryProps.groups then local Tabs = Lazy.load( 'Module:Tabs' ).Tabs local tabs = Tabs.new() if defaultGallery then tabs:addTabTopWithContent{ contentId = 'General', content = defaultGallery } end -- coerce it to a table for easier processing local groups = type( categoryProps.groups ) == 'table' and categoryProps.groups or { categoryProps.groups } for index, group in ipairs( groups ) do if pageTree[group] then tabs:addTabTopWithContent{ contentId = group, content = buildGallery( pageTree[group] ) } end end return tabs:render() end return defaultGallery end function renderHList( parent, pages ) local list = parent:addClass( 'hlist' ) :tag( 'ul' ) for _, page in ipairs( pages ) do list:tag( 'li' ) :wikitext( '[[' .. page.text .. '|' .. (page.extra.name or page.text) .. ']]' ) end end function buildTable( categoryProps, pageTree ) local content = mw.html.create( 'table' ) if #pageTree.default then local defaultCell = content:tag( 'tr' ) :tag( 'td' ) :addClass( 'odd' ) :attr( 'colspan', '2' ) :css( 'text-align', 'center' ) renderHList( defaultCell, pageTree.default ) end if categoryProps.groups then -- coerce it to a table for easier processing local groups = type( categoryProps.groups ) == 'table' and categoryProps.groups or { categoryProps.groups } for index, group in ipairs( groups ) do if pageTree[group] then local row = content:tag( 'tr' ) row:tag( 'th' ) :addClass( 'label' ) :wikitext( group ) local cell = row:tag( 'td' ) :addClass( (index + (#pageTree.default and 1 or 0)) % 2 == 0 and 'even' or 'odd' ) renderHList( cell, pageTree[group] ) end end end return content end local Navbox = Box.new() Navbox.__index = Navbox setmetatable( Navbox, Box ) function Navbox.new( format, args ) local subject = args[1] .. ' ' .. args[2] args.class = 'navbox' args.title = subject args.edit = subject args.hide = 'show' -- TODO count number of navboxes, hide after the second or third (could relegate to the calling template) local obj = Box.new( 'light', args ) obj.format = format obj.subject = subject obj.categories = { args[1], subject, args[2] } return setmetatable( obj, Navbox ) end function Navbox:renderContent() local categoryProps = getCategoryProps( self.subject ) local pageTree = getPageTree( self.subject, self.format == 'gallery' ) local build = setmetatable( { gallery = buildGalleries }, { __index = function() return buildTable end -- default } ) return build[self.format]( categoryProps, pageTree ) end local p, mt = {}, {} function p._main( format, args ) local navbox = Navbox.new( format, args ) return navbox:render() end -- translates p.function( frame ) to p._main( function, args ) function mt.__index( table, key ) return function ( frame ) return table._main( key, frame.args ) end end -- for use in the debug console: -- =p.list(p.debugframe) p.debugframe = { args = { [1] = "The Legend of Zelda", [2] = "Enemies", } } return setmetatable( p, mt )