Module:Miscellaneous: Difference between revisions

From Path of Exile Wiki
Jump to navigation Jump to search
>OmegaK2
m (bugfix)
(Moved implementation of Template:Item class list to Module:Item class)
 
(23 intermediate revisions by 6 users not shown)
Line 9: Line 9:
local util = require('Module:Util')
local util = require('Module:Util')
local getArgs = require('Module:Arguments').getArgs
local getArgs = require('Module:Arguments').getArgs
local game = require('Module:Game')


-- Should we use the sandbox version of the game data?
local use_sandbox = util.misc.maybe_sandbox('Miscellaneous')
local m_game = use_sandbox and mw.loadData('Module:Game/sandbox') or mw.loadData('Module:Game')
local h = {}
local p = {}
local p = {}
local g_frame, g_args
local g_frame, g_args


--
function p.item_class_category_list(frame)
-- Template: GemLevelTable
    --[[
--
        Displays a list of categories for all item classes.
    ]]


function p.gem_level_table(frame)
     local tpl_args = getArgs(frame, {parentFirst = true})
     g_args = getArgs(frame, {
     local frame = util.misc.get_frame(frame)
        parentFirst = true
    })
     if frame == nil or type(frame) == 'table' then
        frame = mw.getCurrentFrame()
    end
      
      
     g_args.width = g_args.width or 'auto'  
     tpl_args.format = tpl_args.format or 'default'
       
    local out = {}
      
      
     out[#out+1] = '{| class="wikitable GemLevelTable" '
     local fmt
     out[#out+1] = 'style="width: '
     if tpl_args.format == 'default' then
    out[#out+1] = g_args.width
        fmt = '<li>%s</li>'
    out[#out+1] = '; text-align: center"\n'
     else
    out[#out+1] = '! Level\n'
        error(string.format('Unrecognized format: %s', tpl_args.format))
 
    out[#out+1] = '!' ..  util.html.abbr('[[Image:Level_up_icon_small.png|link=|Lvl.]]', 'Required Level', 'nounderline') .. '\n'
      
    for i, v in ipairs(game.constants.attributes) do
        if g_args[v['short_lower']] ~= nil then
            out[#out+1] = '!' .. util.html.abbr('[[Image:' .. v['long_upper'].. 'Icon_small.png|link=|' .. v['short_upper'] .. '.]]', 'Required ' .. v['long_upper'], 'nounderline') .. '\n'
        end
     end
     end
      
      
     -- original had cost, reserve, duration, radius, unneeded I believe
     out = {'<ul>'}
   
     save_tbl = {}
     i = 0
     for _, data in pairs(m_game.constants.item.classes) do
     -- increase if necessary
         if not save_tbl[data.category] and data.category ~= '' then
    while i < 25 do  
            save_tbl[data.category] = true
         local header = g_args['c' .. i]
           
        if header ~= nil then
             out[#out+1] = string.format(fmt, data.category)
             out[#out+1] = '! ' .. header .. '\n'
         end
         end
        i = i + 1
     end
     end
   
     out[#out+1] = '</ul>'
     out[#out+1] = '!' .. util.html.abbr('Exp.', 'Experience Needed to Level Up') .. '\n'
    out[#out+1] = '!' .. util.html.abbr('Total Exp.', 'Total Experience Needed') .. '\n'
      
      
     return table.concat(out)
     return table.concat(out)
end
end


--
--
Line 70: Line 57:
         parentFirst = true
         parentFirst = true
     })
     })
     if frame == nil or type(frame) == 'table' then
     g_frame = util.misc.get_frame(frame)
        frame = mw.getCurrentFrame()
    end
    g_frame = frame
      
      
     g_args.type = g_args.type or ''
     g_args.type = g_args.type or ''
      
      
     tbl = mw.html.create('table')
     local tbl = mw.html.create('table')
     tbl
     tbl
         :attr('class', 'wikitable sortable')
         :attr('class', 'wikitable sortable')
     tblrow = tbl:tag('tr')
     local tblrow = tbl:tag('tr')
             :tag('th')
             :tag('th')
                 :attr('rowspan', 2)
                 :attr('rowspan', 2)
Line 168: Line 152:
local filter_list_yes_no_args = xtable:new({'customization', 'filtration_general', 'filtration_themes'})
local filter_list_yes_no_args = xtable:new({'customization', 'filtration_general', 'filtration_themes'})
local filter_list_yes_no = xtable:new({'no', 'partial', 'yes', 'unknown'})
local filter_list_yes_no = xtable:new({'no', 'partial', 'yes', 'unknown'})
function h.filter_list_get_arg(arg)
    --[[
    Return a formatted table cell for the given argument
    ]]--
    local val = g_args[arg]
    if type(val) == 'number' then
        val = filter_list_range_values[val]
    end
    if g_args[arg .. '_note'] ~= nil then
        local abbr = mw.html.create('abbr')
        abbr
            :attr('title', g_args[arg .. '_note'])
            :css('color', 'black')
            :wikitext(val)
            :done()
        return tostring(abbr)
    else
        return val
    end
end


-- Test: =p.filter_list{rows=p.filter_list_row{name='a', release_link='http://google.de', author='Mario', author_contact='No idea', direct_link='http://google.de', colour='yes', border='yes', font_size='no', item_hiding='yes', leveling=0, endgame=4, vendor_recipes='partial', crafting='no', release='2015'}}
-- Test: =p.filter_list{rows=p.filter_list_row{name='a', release_link='http://google.de', author='Mario', author_contact='No idea', direct_link='http://google.de', colour='yes', border='yes', font_size='no', item_hiding='yes', leveling=0, endgame=4, vendor_recipes='partial', crafting='no', release='2015'}}
Line 175: Line 180:
         parentFirst = true
         parentFirst = true
     })
     })
     if frame == nil or type(frame) == 'table' then
     g_frame = util.misc.get_frame(frame)
        frame = mw.getCurrentFrame()
    end
    g_frame = frame
      
      
     -- Checking args
     -- Checking args
Line 221: Line 223:
     -- Output
     -- Output
      
      
     tblrow = mw.html.create('tr')
     local tblrow = mw.html.create('tr')
     tblrow
     tblrow
         :tag('td')
         :tag('td')
Line 242: Line 244:
                 :attr('class', 'table-cell-coloured table-cell-' .. text )
                 :attr('class', 'table-cell-coloured table-cell-' .. text )
                 :attr('data-sort-value', index)
                 :attr('data-sort-value', index)
                 :wikitext(filter_list_get_arg(arg))
                 :wikitext(h.filter_list_get_arg(arg))
                 :done()
                 :done()
     end
     end
Line 253: Line 255:
                 :attr('class', 'table-cell-coloured table-cell-' .. val)
                 :attr('class', 'table-cell-coloured table-cell-' .. val)
                 :attr('data-sort-value', '' .. filter_list_yes_no:index(val))
                 :attr('data-sort-value', '' .. filter_list_yes_no:index(val))
                 :wikitext(filter_list_get_arg(arg))
                 :wikitext(h.filter_list_get_arg(arg))
                 :done()
                 :done()
     end
     end
Line 260: Line 262:
         tblrow
         tblrow
             :tag('td')
             :tag('td')
                 :wikitext(filter_list_get_arg('description'))
                 :wikitext(h.filter_list_get_arg('description'))
                 :done()
                 :done()
     end
     end
Line 267: Line 269:
end
end


function filter_list_get_arg(arg)
-- ----------------------------------------------------------------------------
    --[[
    Return a formatted table cell for the given argument
    ]]--
    local val = g_args[arg]
    if type(val) == 'number' then
        val = filter_list_range_values[val]
    end
    if g_args[arg .. '_note'] ~= nil then
        abbr = mw.html.create('abbr')
        abbr
            :attr('title', g_args[arg .. '_note'])
            :wikitext(val)
            :done()
        return tostring(abbr)
    else
        return val
    end
end
 
--
-- Template: Mod
--
 
function p.mod(frame)
    -- Get args
    g_args = getArgs(frame, {
        parentFirst = true
    })
    g_frame = util.misc.get_frame(frame)
   
    --
    -- Validation & semantic properties
    --
   
    -- Validate single value properties and set them
   
    function validate_number (args)
        return function (arg)
            g_args[arg] = util.cast.number(g_args[arg], args)
            return g_args[arg]
        end
    end
   
    local map = {
        {
            name = 'id',
            property = 'Is mod',
            wikitext = 'Mod Id',
        },
        {
            name = 'name',
            property = 'Has name',
            wikitext = 'Name',
        },
        {
            name = 'mod_group',
            property = 'Has mod group',
            wikitext = 'Group',
        },
        {
            name = 'mod_type',
            property = 'Has mod type',
            wikitext = 'Mod type',
        },
        {
            name = 'domain',
            property = 'Has mod domain',
            func = validate_number{min=1, max=11},
            wikitext = 'Mod domain',
            display = function (value)
                return game.constants.mod.domains[value]['short_upper'] .. ' (Id: ' .. value .. ')'
            end,
        },
        {
            name = 'generation_type',
            property = 'Has mod generation type',
            func = validate_number{min=1, max=8},
            wikitext = 'Generation type',
            display = function (value)
                return game.constants.mod.generation_types[value]['short_upper'] .. ' (Id: ' .. value .. ')'
            end,
        },
        {
            name = 'required_level',
            property = 'Has level requirement',
            func = validate_number{min=1, max=100},
            wikitext = 'Req. level',
        },
        {
            name = 'stat_text',
            property = 'Has stat text',
            wikitext = 'Effect',
        },
    }
   
    local properties = {}
   
    for _, data in ipairs(map) do
        if data.func ~= nil then
            data.func(data.name)
        end
       
        properties[data.property] = g_args[data.name]
    end
   
    g_frame:callParserFunction('#set', properties)
   
    -- Validate & set multi value property
   
    if g_args['tags'] == nil then
        g_args['tags'] = {}
    else
        local tags = mw.text.split(g_args['tags'], ', ')
       
        g_args['tags'] = tags
   
        properties = {}
 
        properties['Has tags'] = table.concat(tags, ';')
        properties['+sep'] = ';'
        g_frame:callParserFunction('#set', properties)
    end
   
    -- Validate % set the stat multi value property
    for i=1, 4 do
        local id = {
            id = 'stat' .. i .. '_id',
            min = 'stat' .. i .. '_min',
            max = 'stat' .. i .. '_max',
        }
       
        local value = {
            id = g_args[id.id],
            min = g_args[id.min],
            max = g_args[id.max],
        }
       
        local isnil = true
        for k, v in pairs(value) do
            isnil = isnil and v ~= nil
        end
       
        if not isnil then
            local onenil = nil
            for k, v in pairs(value) do
                if v == nil then
                    onenil = k
                    break
                end
            end
           
            if onenil ~= nil then
                error('"' .. k .. '" is not set for stat ' .. i)
            end
           
            properties = {}
            properties['Is stat number'] = i
            properties['Has stat id'] = value.id
            properties['Has minimum stat value'] = validate_number({min=0})(id.min)
            properties['Has maximum stat value'] = validate_number({min=0})(id.max)
           
            g_frame:callParserFunction('#subobject:', properties)
        end
    end
   
    -- Validate & set spawn weight multi value property
   
    for i=1, 15 do
        local id = {
            tag = 'spawn_tag' .. i,
            value = 'spawn_value' .. i,
        }
   
        local value = {
            tag = g_args[id.tag],
            value = g_args[id.value],
        }
       
        if value.tag ~= nil and value.value ~= nil then
            properties = {}
            properties['Is tag number'] = i
            properties['Has tag'] = value.tag
            properties['Has spawn weight'] = validate_number({min=0})(id.value)
           
            g_frame:callParserFunction('#subobject:', properties)
           
        elseif not (value.tag == nil and value.value == nil) then
            error ('Both ' .. id.tag .. ' and ' .. id.value .. ' must be specified')
        end
    end
   
    --
    -- Display
    --
   
    local container = mw.html.create('div')
    container
        :attr('class', 'modbox')
   
    -- core stats
   
    local tbl = container:tag('table')
    tbl
        :attr('class', 'wikitable')
   
    for _, data in ipairs(map) do
        local text
        if data.display == nil then
            text = g_args[data.name]
        else
            text = data.display(g_args[data.name])
        end
       
        tbl
            :tag('tr')
                :tag('th')
                    :wikitext(string.format('[[Property:%s|%s]]', data.property, data.wikitext))
                    :done()
                :tag('td')
                    :wikitext(text)
                    :done()
                :done()
            :done()
    end
   
    tbl
        :tag('tr')
            :tag('th')
                :wikitext('[[Property:Has tags|Tags]]')
                :done()
            :tag('td')
                :wikitext(table.concat(g_args['tags'], ', '))
                :done()
            :done()
        :done()
   
    -- stat table
   
    tbl = container:tag('table')
    tbl
        :attr('class', 'wikitable sortable')
        :tag('tr')
            :tag('th')
                :attr('colspan', 4)
                :wikitext('Stats')
                :done()
            :done()
        :tag('tr')
            :tag('th')
                :wikitext('[[Property:Is stat number|#]]')
                :done()
            :tag('th')
                :wikitext('[[Property:Has stat id|Stat Id]]')
                :done()
            :tag('th')
                :wikitext('[[Property:Has minimum stat value|Minimum]]')
                :done()
            :tag('th')
                :wikitext('[[Property:Has maximum stat value|Maximum]]')
                :done()
            :done()
        :done()
       
    for i=1, 4 do
        local value = {
            id = g_args['stat' .. i .. '_id'],
            min = g_args['stat' .. i .. '_min'],
            max = g_args['stat' .. i .. '_max'],
        }
       
        if value.id then
            tbl
                :tag('tr')
                    :tag('td')
                        :wikitext(i)
                        :done()
                    :tag('td')
                        :wikitext(value.id)
                        :done()
                    :tag('td')
                        :wikitext(value.min)
                        :done()
                    :tag('td')
                        :wikitext(value.max)
                        :done()
                    :done()
                :done()
        end
    end
   
    -- spawn weight table
   
    tbl = container:tag('table')
    tbl
        :attr('class', 'wikitable sortable')
        :tag('tr')
            :tag('th')
                :attr('colspan', 3)
                :wikitext('Spawn Weights')
                :done()
            :done()
        :tag('tr')
            :tag('th')
                :wikitext('[[Property:Is tag number|#]]')
                :done()
            :tag('th')
                :wikitext('[[Property:Has tag|Tag]]')
                :done()
            :tag('th')
                :wikitext('[[Property:Has spawn weight|Weight]]')
                :done()
            :done()
        :done()
       
    for i=1, 15 do
        local value = {
            tag = g_args['spawn_tag' .. i],
            value = g_args['spawn_value' .. i],
        }
       
        if value.tag then
            tbl
                :tag('tr')
                    :tag('td')
                        :wikitext(i)
                        :done()
                    :tag('td')
                        :wikitext(value.tag)
                        :done()
                    :tag('td')
                        :wikitext(value.value)
                        :done()
                    :done()
                :done()
        end
    end
   
    -- Generic messages on the page
   
    out = {}
   
    if g_args['name'] then
        out[#out+1] = string.format("'''%s''' is the internal id of modifier '''%s'''.", g_args['id'], g_args['name'])
    else
        out[#out+1] = string.format("'''%s''' is the internal id of an unnamed modifier.", g_args['id'], g_args['name'])
    end
   
   
    -- Categories
   
    cats = {'Mods'}
   
    -- Done -> output
   
    return table.concat(out) .. tostring(container) .. util.misc.add_category(cats)
end
 
--
-- Template: Version
--
 
function p.version(frame)
    -- Get args
    g_args = getArgs(frame, {
        parentFirst = true
    })
    if frame == nil or type(frame) == 'table' then
        frame = mw.getCurrentFrame()
    end
    g_frame = frame
   
    -- Parser
    local properties = {}
    local vargs = {before = '←', after = '→'}
    local query = {}
    query['?Has release date'] = ''
    query['mainlabel'] = '-'
   
   
    for arg, value in pairs(vargs) do
        if g_args[arg] ~= nil then
            properties['Has version ' .. arg] = g_args[arg]
            vargs[arg] = '[[Version ' .. g_args[arg] .. '|' .. vargs[arg] .. ' ' .. g_args[arg] .. ']] <br> ' .. g_frame:callParserFunction('#ask: [[Is version::' .. g_args[arg] .. ']]', query)
        else
            vargs[arg] = nil
        end
    end
   
    properties['Is version'] = g_args['patch']
    properties['Has release date'] = g_args['patchdate']
    g_frame:callParserFunction('#set', properties)
   
    -- Output
   
    tbl = mw.html.create('table')
    tbl
        :attr('class', 'wikitable successionbox')
        :tag('tr')
            :tag('th')
                :attr('colspan', 3)
                :wikitext('[[Version history|Version History]]')
                :done()
            :done()
        :tag('tr')
            :tag('td')
                :attr('style', 'width: 30%;')
                :wikitext(vargs['before'])
                :done()
            :tag('td')
                :attr('style', 'width: 40%;')
                :wikitext('[[Version ' .. g_args['patch'] .. ']] <br> ' .. g_frame:callParserFunction('#show: Version ' .. g_args['patch'], {'?Has release date'}))
                :done()
            :tag('td')
                :attr('style', 'width: 30%;')
                :wikitext(vargs['after'])
                :done()
            :done()
        :done()
           
   
    return tostring(tbl)
end
 
 


return p
return p

Latest revision as of 03:12, 26 May 2022

Module documentation[view] [edit] [history] [purge]


Lua logo

This module depends on the following other modules:

Overview

Module for implementing various templates in lua that are not big/complex enough to warrent their own module.

List of currently implemented templates

de:Modul:Miscellaneous

--[[
Module for implementing miscellaneous templates in lua.  
Mostly exists here so we don't have hundred of module pages for templates that don't have a lot of code.
 
If a template requires a *lot* of coding consider moving it into it's own lua module.
]]--

local xtable = require('Module:Table')
local util = require('Module:Util')
local getArgs = require('Module:Arguments').getArgs

-- Should we use the sandbox version of the game data?
local use_sandbox = util.misc.maybe_sandbox('Miscellaneous')

local m_game = use_sandbox and mw.loadData('Module:Game/sandbox') or mw.loadData('Module:Game')

local h = {}
local p = {}
local g_frame, g_args

function p.item_class_category_list(frame)
    --[[
        Displays a list of categories for all item classes.
    ]]

    local tpl_args = getArgs(frame, {parentFirst = true})
    local frame = util.misc.get_frame(frame)
    
    tpl_args.format = tpl_args.format or 'default'
    
    local fmt
    if tpl_args.format == 'default' then
        fmt = '<li>%s</li>'
    else
        error(string.format('Unrecognized format: %s', tpl_args.format))
    end
    
    out = {'<ul>'}
    save_tbl = {}
    for _, data in pairs(m_game.constants.item.classes) do
        if not save_tbl[data.category] and data.category ~= '' then
            save_tbl[data.category] = true
            
            out[#out+1] = string.format(fmt, data.category)
        end
    end
    out[#out+1] = '</ul>'
    
    return table.concat(out)
end

--
-- Template: ItemFilterList
--
function p.filter_list(frame)
    g_args = getArgs(frame, {
        parentFirst = true
    })
    g_frame = util.misc.get_frame(frame)
    
    g_args.type = g_args.type or ''
    
    local tbl = mw.html.create('table')
    tbl
        :attr('class', 'wikitable sortable')
    local tblrow = tbl:tag('tr')
            :tag('th')
                :attr('rowspan', 2)
                :wikitext('Name')
                :done()
            :tag('th')
                :attr('rowspan', 2)
                :wikitext('Author')
                :done()
            :tag('th')
                :attr('rowspan', 2)
                :wikitext('Release')
                :done()
            :tag('th')
                :attr('colspan', 9)
                :wikitext('Ingame Features')
                :done()
            :tag('th')
                :attr('colspan', 1)
                :wikitext('Other Features')
                :done()
            :tag('th')
                :attr('colspan', 2)
                :wikitext('Filtration Support')
                :done()
    if g_args.type == 'specialized' then
            tblrow:tag('th')
                :attr('rowspan', 2)
                :wikitext('Description')
                :done()
    end
            
    tblrow = tbl:tag('tr')
            :tag('th')
                :wikitext('Colours')
                :done()
            :tag('th')
                :wikitext('Borders')
                :done()
            :tag('th')
                :wikitext('Font<br>Size')
                :done()
             :tag('th')
                :wikitext('Background')
                :done()
            :tag('th')
                :wikitext('Item<br>Hiding')
                :done()
            :tag('th')
                :wikitext('Leveling')
                :done()
            :tag('th')
                :wikitext('Endgame')
                :done()
            :tag('th')
                :wikitext('Vendor<br>recipes')
                :done()
            :tag('th')
                :wikitext('Crafting')
                :done()
            -- Other Features
            :tag('th')
                :wikitext('Customizable')
                :done()
            -- Filtration
            :tag('th')
                :wikitext('General')
                :done()
            :tag('th')
                :wikitext('Themes')
                :done()
        :done()
        :wikitext(g_args.rows)
    
    --return tostring(tbl) .. frame:extensionTag{ name = 'references', content = '', args = {group='note'}}
    return tostring(tbl)
end

--
-- Template: ItemFilterListRow
--

local filter_list_required_args = xtable:new({'name', 'release_link', 'author', 'release', 'colour', 'border', 'font_size', 'background', 'item_hiding', 'leveling', 'endgame', 'vendor_recipes', 'crafting'})
local filter_list_range_args = xtable:new({'colour', 'border', 'font_size', 'background', 'item_hiding', 'leveling', 'endgame', 'vendor_recipes', 'crafting'})
local filter_list_range_values = xtable:new({'no', 'minor', 'partial', 'major', 'yes'})

local filter_list_yes_no_args = xtable:new({'customization', 'filtration_general', 'filtration_themes'})
local filter_list_yes_no = xtable:new({'no', 'partial', 'yes', 'unknown'})

function h.filter_list_get_arg(arg)
    --[[
    Return a formatted table cell for the given argument
    ]]--
    local val = g_args[arg]
    if type(val) == 'number' then
        val = filter_list_range_values[val]
    end
    if g_args[arg .. '_note'] ~= nil then
        local abbr = mw.html.create('abbr')
        abbr
            :attr('title', g_args[arg .. '_note'])
            :css('color', 'black')
            :wikitext(val)
            :done()
        return tostring(abbr)
    else
        return val
    end
end

-- Test: =p.filter_list{rows=p.filter_list_row{name='a', release_link='http://google.de', author='Mario', author_contact='No idea', direct_link='http://google.de', colour='yes', border='yes', font_size='no', item_hiding='yes', leveling=0, endgame=4, vendor_recipes='partial', crafting='no', release='2015'}}
-- =p.filter_list{type='specialized',rows=p.filter_list_row{type='specialized', name='a', release_link='http://google.de', author='Mario', author_contact='No idea', direct_link='http://google.de', colour='yes',colour_note="test", border='yes', font_size='no', background='no', item_hiding='yes', leveling=0, endgame=4, vendor_recipes='partial', crafting='no', release='2015', description='test'}}
function p.filter_list_row(frame)
    g_args = getArgs(frame, {
        parentFirst = true
    })
    g_frame = util.misc.get_frame(frame)
    
    -- Checking args
    
    for _, arg in ipairs(filter_list_required_args) do
        if g_args[arg] == nil then
            error('Required argument ' .. arg .. ' is missing')
        end
    end
    
    g_args.filtration_general = g_args.filtration_general or 'unknown'
    g_args.filtration_themes = g_args.filtration_themes or 'unknown'
    g_args.customization = g_args.customization or 'unknown'
    g_args.descriptipon = g_args.description or '<br>'
    g_args.type = g_args.type or ''
    
    -- Checking & formatting args
    
    for _, arg in ipairs(filter_list_range_args) do
        local val = g_args[arg]
        local index = filter_list_range_values:index(val)
        if index then
            g_args[arg] = index
        else
            index = util.cast.number(val)
            if index ~= nil and index >= 0 and index < filter_list_range_values:size() then
                -- Lua starts counting at 1
                g_args[arg] = index+1
            else
                error('Argument ' .. arg .. ' requires one of the following arguments: ' .. table.concat(filter_list_range_values, ' '))
            end
        end
    end
    
    for _, arg in ipairs(filter_list_yes_no_args) do
        local val = g_args[arg]
        if not filter_list_yes_no:contains(val) then
            error('Argument ' .. arg .. ' requires one of the following arguments: ' .. table.concat(filter_list_yes_no, ' '))
        end
    end
    
    -- Output
    
    local tblrow = mw.html.create('tr')
    tblrow
        :tag('td')
            :wikitext('[' .. g_args.release_link .. ' ' .. g_args.name .. ']')
            :done()
        :tag('td')
            :wikitext(g_args.author)
            :done()
        :tag('td')
            :wikitext(g_args.release)
            :done()
            
    -- Basic Features
    for _, arg in ipairs(filter_list_range_args) do
        local index = g_args[arg]
        local text = filter_list_range_values[index] or ''
        local note = g_args[arg .. '_note']
        tblrow
            :tag('td')
                :attr('class', 'table-cell-coloured table-cell-' .. text )
                :attr('data-sort-value', index)
                :wikitext(h.filter_list_get_arg(arg))
                :done()
    end
    
    -- Other Features
    for _, arg in ipairs(filter_list_yes_no_args) do
        local val = g_args[arg]
        tblrow
            :tag('td')
                :attr('class', 'table-cell-coloured table-cell-' .. val)
                :attr('data-sort-value', '' .. filter_list_yes_no:index(val))
                :wikitext(h.filter_list_get_arg(arg))
                :done()
    end
    
    if g_args.type == 'specialized' then
        tblrow
            :tag('td')
                :wikitext(h.filter_list_get_arg('description'))
                :done()
    end

    return tostring(tblrow)
end

-- ----------------------------------------------------------------------------

return p