|
|
(22 intermediate revisions by the same user not shown) |
Line 1: |
Line 1: |
| local Args = require( 'Module:Args' ) | | local Args = require( 'Module:Args' ) |
| local Box = require( 'Module:Box' ).Box | | local Listing = require( 'Module:Listing' ) |
| local Lazy = require( 'Module:Lazy' ) -- may load: Tabs, Gallery
| |
|
| |
|
| function getCategoryProps( categoryName ) | | function buildHList( parent, sections ) |
| local categoryContent = mw.title.new( categoryName, 'Category' ):getContent() | | local list = parent:addClass( 'hlist' ) |
| local props = {} | | :tag( 'ul' ) |
| | | for _, section in ipairs( sections ) do |
| for match in string.gmatch( categoryContent, '{{Prop|([^}]*)}}' ) do
| | -- !!!! This may break if Template:Main is modified !!!! |
| local prop, value = unpack(mw.text.split( match, '|' )) | | local expandedMainTemplate = section.summary:match( 'Main article: %[%[(.-)]]' ) |
| | | local link = expandedMainTemplate and mw.text.split( expandedMainTemplate, '|' )[1] |
| -- table if multiple values, value if one value, true if no values (i.e. flag) | | list:tag( 'li' ) |
| props[prop] = value and string.match( value, ',' ) and mw.text.split( value, ',' ) or value or true
| | :wikitext( '[[' .. (link or section.name) .. '|' .. section.name .. ']]' ) |
| end | | end |
|
| |
| return props
| |
| end | | end |
|
| |
|
| function getPageGroups( categoryName, getPageProps )
| | local Navbox = Listing.Navbox |
| -- get all pages in the category
| |
| local pages = mw.ext.dpl.getPages{ category = categoryName, ordermethod = 'sortkey', order = 'ascending' }
| |
| | |
| -- organize them by group
| |
| local groups = {}
| |
| for _, page in ipairs( pages ) do
| |
| if page.extra ~= 'exclude' then
| |
| -- 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 = 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 )
| |
| 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 Listbox = setmetatable( {}, Navbox ) |
| local Gallery = Lazy.load( 'Module:Gallery' ).Gallery
| | Listbox.__index = Listbox |
| 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() | | function Listbox.new( args ) |
| | local obj = Navbox.new( args ) |
| | return setmetatable( obj, Listbox ) |
| end | | end |
|
| |
|
| | -- override |
| | function Listbox:renderContent() |
| | local listing = Listing._parseListing( self.subject ) |
|
| |
|
| function buildGalleries( categoryProps, pageGroups )
| | -- If categories weren't set already (because caller used single arg), then use the ones parsed from the page. |
| local Gallery = Lazy.load( 'Module:Gallery' ).Gallery | | -- CODE SMELL: setting unrelated state. this only works because renderFooter is called after renderContent. |
| | | if #self.categories == 0 then self.categories = listing.categories end |
| 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' ) | | local content = mw.html.create( 'table' ) |
| if #pageGroups.default then | | if #listing.topLevelLeaves > 0 then |
| local defaultCell = content:tag( 'tr' ) | | local defaultCell = content:tag( 'tr' ) |
| :tag( 'td' ) | | :tag( 'td' ) |
Line 122: |
Line 39: |
| :attr( 'colspan', '2' ) | | :attr( 'colspan', '2' ) |
| :css( 'text-align', 'center' ) | | :css( 'text-align', 'center' ) |
| renderHList( defaultCell, pageGroups.default ) | | buildHList( defaultCell, listing.topLevelLeaves ) |
| end | | end |
| if categoryProps.groups then | | if #listing.groups > 0 then |
| -- coerce it to a table for easier processing
| | for index, group in ipairs( listing.groups ) do |
| local groups = type( categoryProps.groups ) == 'table' and categoryProps.groups or { categoryProps.groups }
| | local row = content:tag( 'tr' ) |
| for index, group in ipairs( groups ) do | | row:tag( 'th' ) |
| if pageGroups[group] then | | :addClass( 'zdw-label' ) |
| local row = content:tag( 'tr' )
| | :wikitext( group.name ) |
| row:tag( 'th' )
| | local cell = row:tag( 'td' ) |
| :addClass( 'label' )
| | :addClass( (index + (#listing.topLevelLeaves > 0 and 1 or 0)) % 2 == 0 and 'even' or 'odd' ) |
| :wikitext( group )
| | buildHList( cell, group.sections ) |
| 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 |
| end | | end |
Line 143: |
Line 56: |
| end | | end |
|
| |
|
| local Navbox = Box.new()
| | local p = {} |
| 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 = args.hide or 'show'
| |
| 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 ) | | function p.main( frame ) |
| local navbox = Navbox.new( format, args ) | | local listbox = Listbox.new( Args.fromFrame( frame ) ) |
| return navbox:render()
| | return listbox:render() |
| end
| |
| | |
| -- translates p.function( frame ) to p._main( function, args )
| |
| function mt.__index( table, key )
| |
| return function ( frame ) | |
| return table._main( key, Args.fromFrame( frame ) )
| |
| end
| |
| end | | end |
|
| |
|
| -- for use in the debug console: | | -- for use in the debug console: |
| -- =p.list(p.debugframe) | | -- =p.main(p.debugframe) |
| p.debugframe = { | | p.debugframe = { |
| args = { | | args = {}, |
| [1] = "The Legend of Zelda", | | getParent = function() return { |
| [2] = "Enemies", | | args = { |
| } | | [1] = "The Legend of Zelda Locations" |
| | } |
| | } end |
| } | | } |
|
| |
|
| return setmetatable( p, mt ) | | return p |