Module:Listbox: Difference between revisions
Jump to navigation
Jump to search
Want an adless experience? Log in or Create an account.
(saving WIP for gallery layout. realized this will be much easier if I first convert Tab (and maybe Gallery too)) |
(implement gallery mode (has a few bugs I think)) |
||
Line 1: | Line 1: | ||
local Box = require( 'Module:Box' ).Box | local Box = require( 'Module:Box' ).Box | ||
local Lazy = require( 'Module:Lazy' ) -- may load: Tabs, Gallery | |||
function getCategoryProps( categoryName ) | function getCategoryProps( categoryName ) | ||
Line 52: | Line 53: | ||
end | end | ||
function buildGallery( | function buildGallery( pages ) | ||
local | local Gallery = Lazy.load( 'Module:Gallery' ).Gallery | ||
local gallery = Gallery.new() -- TODO define appropriate args. CD/Header has: {{Gallery|size={{#ifeq:{{{size|}}}|large|95|62}}|pad=1|square={{{square|true}}}}} | |||
for _, page in ipairs( pages ) do | |||
defaultGallery:addFile( '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 | |||
return | |||
end | end | ||
Line 93: | Line 109: | ||
for _, page in ipairs( pages ) do | for _, page in ipairs( pages ) do | ||
list:tag( 'li' ) | list:tag( 'li' ) | ||
:wikitext( '[[' .. page.text .. '|' .. (page.extra.name | :wikitext( '[[' .. page.text .. '|' .. (page.extra.name or page.text) .. ']]' ) | ||
end | end | ||
end | end | ||
Line 109: | Line 125: | ||
if categoryProps.groups then | if categoryProps.groups then | ||
-- coerce it to a table for easier processing | -- coerce it to a table for easier processing | ||
local groups = type(categoryProps.groups) == 'table' and categoryProps.groups or { categoryProps.groups } | local groups = type( categoryProps.groups ) == 'table' and categoryProps.groups or { categoryProps.groups } | ||
for index, group in ipairs(groups) do | for index, group in ipairs( groups ) do | ||
if | if pageTree[group] then | ||
local row = content:tag( 'tr' ) | local row = content:tag( 'tr' ) | ||
row:tag( 'th' ) | row:tag( 'th' ) |
Revision as of 02:01, June 25, 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.sortkey = 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' } } page.extra = {} 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.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 return pageTree end function buildGallery( pages ) local Gallery = Lazy.load( 'Module:Gallery' ).Gallery local gallery = Gallery.new() -- TODO define appropriate args. CD/Header has: {{Gallery|size={{#ifeq:{{{size|}}}|large|95|62}}|pad=1|square={{{square|true}}}}} for _, page in ipairs( pages ) do defaultGallery:addFile( '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 = buildGallery }, { __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 )