Module:Listbox
Want an adless experience? Log in or Create an account.
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, Args 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 getPageGroups( categoryName, getPageProps ) -- get all pages in the category local pages = mw.ext.dpl.getPages{ category = categoryName, ordermethod = 'sortkey', order = 'ascending' } -- organize them by group local groups = { default = {} } for _, page in ipairs( pages ) do -- remove extra from sortkey if page.extra then page.sortkey = string.sub( page.sortkey, 1, -string.len( page.extra ) - 2 ) end if getPageProps then local pageContent = mw.title.new( page.text ):getContent() page.args = Lazy.load( 'Module:Args' ).fromPageContent( pageContent, 'Cat%s*|%s*' .. categoryName ) else page.args = {} end -- add page to group page.args.group = page.extra or 'default' page.__index = page -- allow variants to fall back to page page.args.__index = page.args -- allow variants' args to fall back to page's args local variants = page.args.variant or {{}} -- that's a table containing a single table (variant) with no properties (overrides) for _, variant in ipairs( variants ) do setmetatable( variant, page.args ) if not variant.exclude then groups[variant.group] = groups[variant.group] or {} groups[variant.group][#groups[variant.group] + 1] = setmetatable( { args = variant }, page ) end end end return groups 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.args.image or 'No Image.png', '[[' .. page.text .. '|' .. (page.args.name or page.text) .. ']]', { link = page.text, alt = page.args.name or page.text } ) end return gallery:render() end function buildGalleries( categoryProps, pageGroups ) local Gallery = Lazy.load( 'Module:Gallery' ).Gallery local defaultGallery = nil if pageGroups.default then defaultGallery = buildGallery( pageGroups.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 pageGroups[group] then tabs:addTabTopWithContent{ contentId = group, content = buildGallery( pagegroups[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.args.name or page.text) .. ']]' ) end end function buildTable( categoryProps, pageGroups ) local content = mw.html.create( 'table' ) if #pageGroups.default then local defaultCell = content:tag( 'tr' ) :tag( 'td' ) :addClass( 'odd' ) :attr( 'colspan', '2' ) :css( 'text-align', 'center' ) renderHList( defaultCell, pageGroups.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 pageGroups[group] then local row = content:tag( 'tr' ) row:tag( 'th' ) :addClass( 'label' ) :wikitext( group ) local cell = row:tag( 'td' ) :addClass( (index + (#pageGroups.default and 1 or 0)) % 2 == 0 and 'even' or 'odd' ) renderHList( cell, pageGroups[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 pageGroups = getPageGroups( self.subject, self.format == 'gallery' ) local build = setmetatable( { gallery = buildGalleries }, { __index = function() return buildTable end -- default } ) return build[self.format]( categoryProps, pageGroups ) 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 )