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.
(parse extra as json)
m (change label class to zdw-label to distinguish from bootstrap)
 
(40 intermediate revisions by the same user not shown)
Line 1: Line 1:
local Box = require( 'Module:Box' ).Box
local Args = require( 'Module:Args' )
local Listing = require( 'Module:Listing' )


function getCategoryProps( categoryName )
function buildHList( parent, sections )
  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' )
   local list = parent:addClass( 'hlist' )
     :tag( 'ul' )
     :tag( 'ul' )
   for _, page in ipairs(pages) do
   for _, section in ipairs( sections ) do
    -- !!!! This may break if Template:Main is modified !!!!
    local expandedMainTemplate = section.summary:match( 'Main article: %[%[(.-)]]' )
    local link = expandedMainTemplate and mw.text.split( expandedMainTemplate, '|' )[1]
     list:tag( 'li' )
     list:tag( 'li' )
       :wikitext( '[[' .. page.text .. '|' .. (page.sortkey or page.text) .. ']]' )
       :wikitext( '[[' .. (link or section.name) .. '|' .. section.name .. ']]' )
   end
   end
end
end


local Navbox = Box.new()
local Navbox = Listing.Navbox
Navbox.__index = Navbox
 
setmetatable( Navbox, Box )
local Listbox = setmetatable( {}, Navbox )
Listbox.__index = Listbox


function Navbox.new( format, args )
function Listbox.new( args )
  local subject = args[1] .. ' ' .. args[2]
   local obj = Navbox.new( args )
  args.class = 'navbox'
   return setmetatable( obj, Listbox )
  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
end


function Navbox:renderContent()
-- override
   local catprops = getCategoryProps( self.subject )
function Listbox:renderContent()
   local listing = Listing._parseListing( self.subject )


   -- get list of pages in the category
   -- If categories weren't set already (because caller used single arg), then use the ones parsed from the page.
   local pages = mw.ext.dpl.getPages{ category = self.subject, ordermethod = 'sortkey', order = 'ascending' }
   -- CODE SMELL: setting unrelated state. this only works because renderFooter is called after renderContent.
  if #self.categories == 0 then self.categories = listing.categories end


  -- 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
    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' )
   local content = mw.html.create( 'table' )
   if #pagetree.default then
   if #listing.topLevelLeaves > 0 then
     local defaultcell = content:tag( 'tr' )
     local defaultCell = content:tag( 'tr' )
       :tag( 'td' )
       :tag( 'td' )
       :addClass( 'odd' )
       :addClass( 'odd' )
       :attr( 'colspan', '2' )
       :attr( 'colspan', '2' )
       :css( 'text-align', 'center' )
       :css( 'text-align', 'center' )
     renderHList( defaultcell, pagetree.default )
     buildHList( defaultCell, listing.topLevelLeaves )
   end
   end
   if catprops.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(catprops.groups) == 'table' and catprops.groups or { catprops.groups }
       local row = content:tag( 'tr' )
     for index, group in ipairs(groups) do
      row:tag( 'th' )
       if( pagetree[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 + (#pagetree.default and 1 or 0)) % 2 == 0 and 'even' or 'odd' )
        renderHList( cell, pagetree[group] )
      end
     end
     end
   end
   end


   return tostring( content )
   return content
end
end


local p, mt = {}, {}
local p = {}


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, frame.args )
  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

Latest revision as of 02:17, November 16, 2020

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

local Args = require( 'Module:Args' )
local Listing = require( 'Module:Listing' )

function buildHList( parent, sections )
  local list = parent:addClass( 'hlist' )
    :tag( 'ul' )
  for _, section in ipairs( sections ) do
    -- !!!! This may break if Template:Main is modified !!!!
    local expandedMainTemplate = section.summary:match( 'Main article: %[%[(.-)]]' )
    local link = expandedMainTemplate and mw.text.split( expandedMainTemplate, '|' )[1]
    list:tag( 'li' )
      :wikitext( '[[' .. (link or section.name) .. '|' .. section.name .. ']]' )
  end
end

local Navbox = Listing.Navbox

local Listbox = setmetatable( {}, Navbox )
Listbox.__index = Listbox

function Listbox.new( args )
  local obj = Navbox.new( args )
  return setmetatable( obj, Listbox )
end

-- override
function Listbox:renderContent()
  local listing = Listing._parseListing( self.subject )

  -- If categories weren't set already (because caller used single arg), then use the ones parsed from the page.
  -- 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 content = mw.html.create( 'table' )
  if #listing.topLevelLeaves > 0 then
    local defaultCell = content:tag( 'tr' )
      :tag( 'td' )
      :addClass( 'odd' )
      :attr( 'colspan', '2' )
      :css( 'text-align', 'center' )
    buildHList( defaultCell, listing.topLevelLeaves )
  end
  if #listing.groups > 0 then
    for index, group in ipairs( listing.groups ) do
      local row = content:tag( 'tr' )
      row:tag( 'th' )
        :addClass( 'zdw-label' )
        :wikitext( group.name )
      local cell = row:tag( 'td' )
        :addClass( (index + (#listing.topLevelLeaves > 0 and 1 or 0)) % 2 == 0 and 'even' or 'odd' )
      buildHList( cell, group.sections )
    end
  end

  return content
end

local p = {}

function p.main( frame )
  local listbox = Listbox.new( Args.fromFrame( frame ) )
  return listbox:render()
end

-- for use in the debug console:
-- =p.main(p.debugframe)
p.debugframe = {
  args = {},
  getParent = function() return {
    args = {
      [1] = "The Legend of Zelda Locations"
    }
  } end
}

return p