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.
mNo edit summary
(implement table with groups)
Line 1: Line 1:
local Box = require( 'Module:Box' ).Box
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()
local Navbox = Box.new()
Line 18: Line 41:


function Navbox:renderContent()
function Navbox:renderContent()
  local catprops = getCategoryProps( self.subject )
   -- get list of pages in the category
   -- get list of pages in the category
   local pages = mw.ext.dpl.getPagenames{ category = self.subject, ordermethod = 'sortkey', order = 'ascending' }
   local pages = mw.ext.dpl.getPages{ category = self.subject, ordermethod = 'sortkey', order = 'ascending' }
  -- TODO get the page contents, look for grouping and variant directives, and restructure the table accordingly


   -- TODO support groupings using table; for now just one big hlist
   -- organize them according to metadata
   local content = mw.html.create( 'div' )
  local pagetree = { default = {} }
     :addClass( 'hlist' )
  for _, page in ipairs( pages ) do
  local hlist = content:tag( 'ul' )
    -- parse extra
   for i, v in ipairs(pages) do
    local extra = page.extra or ''
    -- TODO support variants
    page.extra = {}
    hlist:tag( 'li' )
    for prop in mw.text.gsplit( extra, ',' ) do
      :wikitext( '[[' .. v .. ']]' )
      if prop then
        local propvalue = mw.text.split( prop, ':' )
        page.extra[propvalue[1]] = propvalue[2] or true -- for valueless flags use true
      end
    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' )
    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 _, group in ipairs(groups) do
      if( pagetree[group] ) then
        local row = content:tag( 'tr' )
        row:tag( 'th' )
          :wikitext( group )
        local cell = row:tag( 'td' )
        renderHList( cell, pagetree[group] )
      end
    end
   end
   end


Line 53: Line 107:
p.debugframe = {
p.debugframe = {
   args = {
   args = {
     [1] = "A Link to the Past",
     [1] = "The Legend of Zelda",
     [2] = "Enemies",
     [2] = "Enemies",
   }
   }

Revision as of 19:56, 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 or ''
    page.extra = {}
    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

    -- 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' )
    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 _, group in ipairs(groups) do
      if( pagetree[group] ) then
        local row = content:tag( 'tr' )
        row:tag( 'th' )
          :wikitext( group )
        local cell = row:tag( 'td' )
        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 )