Module:Listbox: Difference between revisions
Jump to navigation
Jump to search
Want an adless experience? Log in or Create an account.
(extra is limited to 255 chars, so grabbing metadata from the page content instead) |
m (fix a couple errors) |
||
Line 23: | Line 23: | ||
local groups = { default = {} } | local groups = { default = {} } | ||
for _, page in ipairs( pages ) do | for _, page in ipairs( pages ) do | ||
page.group = page.extra or 'default' | page.args.group = page.extra or 'default' | ||
-- remove extra from sortkey | -- remove extra from sortkey | ||
if page.extra then page.sortkey = string.sub( page.sortkey, 1, -string.len( page.extra ) - 2 ) end | if page.extra then page.sortkey = string.sub( page.sortkey, 1, -string.len( page.extra ) - 2 ) end | ||
Line 29: | Line 29: | ||
if getPageProps then | if getPageProps then | ||
local pageContent = mw.title.new( page.text ):getContent() | local pageContent = mw.title.new( page.text ):getContent() | ||
page.args = Lazy. | page.args = Lazy.load( 'Module:Args' ).Args.fromPageContent( pageContent, 'Cat%s*|%s*' .. categoryName ) | ||
else | else | ||
page.args = {} | page.args = {} |
Revision as of 06:21, 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, 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 page.args.group = page.extra or 'default' -- 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' ).Args.fromPageContent( pageContent, 'Cat%s*|%s*' .. categoryName ) else page.args = {} end -- add page to group 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.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, 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.extra.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 )