Module:Listbox: Difference between revisions

From Zelda Dungeon Wiki
Jump to navigation Jump to search
Want an adless experience? Log in or Create an account.
(implement table with groups)
(couple bugfixes with table)
Line 50: Line 50:
   for _, page in ipairs( pages ) do
   for _, page in ipairs( pages ) do
     -- parse extra
     -- parse extra
     local extra = page.extra or ''
     local extra = page.extra
     page.extra = {}
     page.extra = {}
     for prop in mw.text.gsplit( extra, ',' ) do
 
      if prop then
     if extra then
        local propvalue = mw.text.split( prop, ':' )
      for prop in mw.text.gsplit( extra, ',' ) do
        page.extra[propvalue[1]] = propvalue[2] or true -- for valueless flags use true
        if prop then
          local propvalue = mw.text.split( prop, ':' )
          page.extra[propvalue[1]] = propvalue[2] or true -- for valueless flags use true
        end
       end
       end
      -- remove extra from sortkey
      page.sortkey = string.sub( page.sortkey, 1, -string.len( extra ) - 2 )
     end
     end


Line 70: Line 76:
     local defaultcell = content:tag( 'tr' )
     local defaultcell = content:tag( 'tr' )
       :tag( 'td' )
       :tag( 'td' )
      :addClass( 'odd' )
      :attr( 'colspan', '2' )
      :css( 'text-align', 'center' )
     renderHList( defaultcell, pagetree.default )
     renderHList( defaultcell, pagetree.default )
   end
   end
Line 75: Line 84:
     -- coerce it to a table for easier processing
     -- coerce it to a table for easier processing
     local groups = type(catprops.groups) == 'table' and catprops.groups or { catprops.groups }
     local groups = type(catprops.groups) == 'table' and catprops.groups or { catprops.groups }
     for _, group in ipairs(groups) do
     for index, group in ipairs(groups) do
       if( pagetree[group] ) then
       if( pagetree[group] ) then
         local row = content:tag( 'tr' )
         local row = content:tag( 'tr' )
         row:tag( 'th' )
         row:tag( 'th' )
          :addClass( 'label' )
           :wikitext( group )
           :wikitext( group )
         local cell = row:tag( 'td' )
         local cell = row:tag( 'td' )
          :addClass( (index + (#pagetree.default and 1 or 0)) % 2 == 0 and 'even' or 'odd' )
         renderHList( cell, pagetree[group] )
         renderHList( cell, pagetree[group] )
       end
       end

Revision as of 20:26, June 21, 2020

Documentation for this module may be created at Module:Listbox/doc

local Box = require( 'Module:Box' ).Box

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 renderHList(parent, pages)
  local list = parent:addClass( 'hlist' )
    :tag( 'ul' )
  for _, page in ipairs(pages) do
    list:tag( 'li' )
      :wikitext( '[[' .. page.text .. '|' .. (page.sortkey or page.text) .. ']]' )
  end
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.subject = subject
  obj.categories = { args[1], subject, args[2] }
  return setmetatable( obj, Navbox )
end

function Navbox:renderContent()
  local catprops = getCategoryProps( self.subject )

  -- get list of pages in the category
  local pages = mw.ext.dpl.getPages{ category = self.subject, ordermethod = 'sortkey', order = 'ascending' }

  -- organize them according to metadata
  local pagetree = { default = {} }
  for _, page in ipairs( pages ) do
    -- parse extra
    local extra = page.extra
    page.extra = {}

    if extra then
      for prop in mw.text.gsplit( extra, ',' ) do
        if prop then
          local propvalue = mw.text.split( prop, ':' )
          page.extra[propvalue[1]] = propvalue[2] or true -- for valueless flags use true
        end
      end

      -- remove extra from sortkey
      page.sortkey = string.sub( page.sortkey, 1, -string.len( extra ) - 2 )
    end

    -- add page to group
    if not page.extra.group then page.extra.group = 'default' end
    if not pagetree[page.extra.group] then pagetree[page.extra.group] = {} end
    pagetree[page.extra.group][#pagetree[page.extra.group] + 1] = page
  end

  -- build the table
  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 catprops.groups then
    -- coerce it to a table for easier processing
    local groups = type(catprops.groups) == 'table' and catprops.groups or { catprops.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 tostring( content )
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 )