Module:Data

From MapleStory 2 Wiki
Jump to: navigation, search

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

-- This module provides common functions for parsing and manipulating data on data pages.
-- It is intended for use by other Lua modules, and should not be called from #invoke directly.
-- Data modules should inherit from this module. (i.e. "local p = require('Module:Data') <...> return p")

local p = {}
local infobox = require( 'Module:Infobox' )

--DEPRECATED use inheritance and p._getData( frame.args[1] ) instead
function p.getData( frame )
    return p._getData( p._getSubject( frame ) )
end

-- Get the pagename from the frame. This also checks for a properly initialized frame.
function p._getSubject( frame )
    if not frame or not frame.args then error( "module not properly initialized" ) end
    if not frame.args[1] then error( "subject pagename not specified" ) end
    return frame.args[1]
end

-- Collect all the data from the page. The result is a table with a key=value
-- entry for each row on the data page, plus a "name" entry for the page name.
function p._getData( pagename )
    local data = { name = pagename }
    local subject = mw.title.new( pagename .. "/data" )
    local text = subject:getContent()
    if not text then return nil end -- don't get data for pages that don't have data
    if text and text ~= '' then
        for arg in mw.text.gsplit( text, "\n", true ) do
            local parts = mw.text.split( arg, "=", true )
            if #parts > 1 then
                parts[2] = table.concat( parts, "=", 2 ) -- allow "=" in values
                local key = mw.text.trim( parts[1] )
                local val = mw.getCurrentFrame():preprocess( mw.text.trim( parts[2] ) )
                data[key] = tonumber( val ) or val -- try to convert to a number
            end
        end
    end
    -- convert [[File:Filename.png]] to Filename.png
    if data.icon and not data.icon_name then data.icon_name = string.gsub( data.icon, "%[%[File:(.*)]]", "%1" ) end
    return data
end

-- Turn a comma-separated list into a ul HTML node
function p._list( list )
    if not list or list == "" then return "" end
    local ul = mw.html.create( 'ul' )
    for item in mw.text.gsplit( list, ",", true ) do
        ul:tag( 'li' ):wikitext( item )
    end
    return ul
end

-- Output function: get a specific piece of data
function p.get( frame )
    local pagename = p._getSubject( frame )
    if not frame.args[2] then error( "parameter not specified" ) end
    local data = p._getData( pagename )
    local var = frame.args[2]
    return data[var]
end

-- Output function: render a feature-rich link to the subject's page
-- Optionally, the child module may implement:
---- p._getInlineTooltip
---- p._getInlineClass
function p.inline( frame )
    local data = p._getData( p._getSubject( frame ) )
    local wrapper = mw.html.create( 'span' )
        :addClass( 'data-inline' )
    if p._getInlineClass then wrapper:addClass( p._getInlineClass( data ) ) end

    local linktitle = ''
    local tooltip = p._getInlineTooltip and p._getInlineTooltip( data )
    if tooltip then
        wrapper:attr( 'title', tooltip )
        linktitle = '|' .. tostring( mw.html.create( 'span' )
            :attr( 'title', tooltip )
            :wikitext( data.name ) )
    end

    if data.icon then
        wrapper:wikitext( data.icon .. ' ' )
    end
    wrapper:wikitext( '[[' .. data.name .. linktitle .. ']]' )
    return tostring( wrapper )
end

-- Output function: construct an infobox, to be used on the subject's page
-- This also adds the page to the appropriate categories.
-- Requires child module to implement:
---- p._getInfoboxArgs
---- p._getCategories
function p.infobox( frame )
    local data = p._getData( p._getSubject( frame ) )
    local args = p._getInfoboxArgs( data )
    local cats = p._getCategories( data )
    local catstring = ""
    for k, v in ipairs(cats) do
	catstring = catstring .. "[[Category:" .. v .. "]]"
    end
    return infobox.infobox( args ) .. catstring
end

-- for submodules to make their own infoboxes
function p._infobox( args )
    return infobox.infobox( args )
end

-- Output function: construct a table listing data for all subjects in the given category
-- Requires child module to implement:
---- p._getTableHeadings
---- p._getRowData
-- Optionally, the child module may implement:
---- p._catTableSort
function p.catTable( frame )
    local tbl = mw.html.create( 'table' )
        :addClass( 'wikitable' )
        :addClass( 'sortable' )

    -- build the header row
    local head = tbl:tag( 'tr' )
    for _, heading in ipairs( p._getTableHeadings() ) do
        local th = head:tag( 'th' )
        if type( heading ) == "table" then
            th:wikitext( heading[1] )
            if heading.class then
                th:addClass( heading.class )
            end
        else
            th:wikitext( heading )
        end
    end

    -- retrieve the list of pages
    local args = {
        category = p._getSubject( frame ),
        ordermethod = "title",
        order = "ascending" }
    local pagenames = mw.ext.dpl.getPagenames( args )
    if pagenames == nil then return '[Error] No pages has yet to use this category "'
        .. args.category
        .. '" in Tria/wiki yet! Create the page first (e.g. Item/NPC/Map) and specify the category in that ../data page!'
    end

    -- gather and sort the page data
    local pageData = {}
    for _, pagename in ipairs( pagenames ) do
        local data = p._getData( pagename )
        if data then -- skip the listing page, etc.
            table.insert( pageData, data )
        end
    end
    if p._catTableSort then table.sort( pageData, p._catTableSort ) end

    -- build each row
    for _, data in ipairs( pageData ) do
        local row = tbl:tag( 'tr' )
        for _, cell in ipairs( p._getRowData( data ) ) do
            row:tag( 'td' ):wikitext( cell )
        end
    end

    return tostring( tbl )
end

return p