Module:Guide

From Path of Exile 2 Wiki
Jump to navigation Jump to search
Module documentation[view] [edit] [history] [purge]


Lua logo

This module depends on the following other modules:

Templates

-------------------------------------------------------------------------------
-- 
--                             Module:Guide
-- 
-- This module implements Template:Guide.
-------------------------------------------------------------------------------

require('strict')
local m_util = require('Module:Util')

-- Should we use the sandbox version of our submodules?
local use_sandbox = m_util.misc.maybe_sandbox('Guide')

local m_cargo = use_sandbox and require('Module:Cargo/sandbox') or require('Module:Cargo')

-- The cfg table contains all localisable strings and configuration, to make it
-- easier to port this module to another wiki.
local cfg = use_sandbox and mw.loadData('Module:Guide/config/sandbox') or mw.loadData('Module:Guide/config')

local i18n = cfg.i18n

-- ----------------------------------------------------------------------------
-- Helper functions
-- ----------------------------------------------------------------------------

local h = {}

function h.format_date(value, format)
    format = format or 'display'
    local formats = {
        display = 'F j, Y',
        cargo = 'Y-m-d',
    }
    return mw.getContentLanguage():formatDate(formats[format], value)
end

function h.get_page_revision_date(page_id)
    local date
    if page_id ~= nil then
        local page = m_cargo.query(
            {'_pageData'},
            {'_modificationDate'},
            {
                where = string.format('_pageID = %s', page_id),
                limit = 1,
            }
        )
        if #page > 0 then
            date = page[1]['_modificationDate']
        end
    end
    return date
end

function h.error_text(text)
    return tostring(
        mw.html.create('strong')
            :addClass('error')
            :wikitext(text)
    )
end

-- ----------------------------------------------------------------------------
-- Cargo tables
-- ----------------------------------------------------------------------------

local tables = {}

tables.guides = {
    table = 'guides',
    order = {'subject', 'version', 'date'},
    fields = {
        subject = {
            field = 'subject',
            type = 'Text',
            default = '',
        },
        version = {
            field = 'version',
            type = 'String',
            func = function (args, value)
                if value ~= nil then
                    value = m_util.cast.version(value, {return_type='string'})
                end
                return value
            end,
        },
        date = {
            field = 'date',
            type = 'Date',
            func = function (args, value)
                if value ~= nil then
                    value = h.format_date(value, 'cargo')
                end
                return value
            end,
        },
    }
}

-- ----------------------------------------------------------------------------
-- Display
-- ----------------------------------------------------------------------------

local display = {}

display.table_map = {
    {
        header = i18n.table.guide,
        sort_type = 'text',
        func = function (data)
            return mw.html.create('td')
                :wikitext(m_util.html.wikilink(data['guides._pageName'], data['guides._pageTitle']))
        end,
    },
    {
        header = i18n.table.subject,
        sort_type = 'text',
        func = function (data)
            local subject = data['guides.subject']
            return mw.html.create('td')
                :wikitext(subject)
        end,
    },
    {
        header = i18n.table.version,
        sort_type = 'text',
        func = function (data)
            local version = data['guides.version']
            if version then
                return mw.html.create('td')
                    :attr('data-sort-value', version)
                    :wikitext(string.format(i18n.table.version_link, version, version))
            end
            return m_util.html.table_cell('na')
        end,
    },
    {
        header = i18n.table.date,
        sort_type = 'date',
        func = function (data)
            local date = data['guides.date'] or data['_pageData._modificationDate']
            return mw.html.create('td')
                :attr('data-sort-value', h.format_date(date, 'cargo'))
                :wikitext(h.format_date(date, 'display'))
        end,
    },
}

-- ----------------------------------------------------------------------------
-- Main functions
-- ----------------------------------------------------------------------------

local function _main(args)
    args = args or {}
    local frame = mw.getCurrentFrame()
    local title_obj = mw.title.getCurrentTitle()
    if title_obj:inNamespaces(cfg.guide_namespace) then
        -- Store Cargo data
        m_cargo.store_mapped_args{
            tpl_args = {
                subject = args.subject,
                version = args.version,
                date = args.date,
            },
            table_map = tables.guides,
        }

        -- Attach
        frame:expandTemplate{title = cfg.attach_templates.guides}
    end

    -- Make message box
    local title = mw.html.create()
    local subject = args.subject or h.error_text(i18n.errors.no_subject)
    title
        :wikitext(string.format(i18n.message_box.guide_subject, subject))
    local text = mw.html.create()
    if args.note then
        text
            :wikitext(args.note)
            :newline()
            :newline()
    end
    if args.version then
        text
            :wikitext(string.format(i18n.message_box.version_valid, args.version))
            :wikitext(' ')
    end
    local date = args.date or h.get_page_revision_date(title_obj.id)
    text
        :wikitext(string.format(
            i18n.message_box.last_updated,
            h.format_date(date, 'display')
        ))
    local mbox = frame:expandTemplate{title = i18n.templates.message_box, args = {
        type = 'info',
        image = i18n.icons.guide,
        title = tostring(title),
        text = tostring(text),
    }}
    local cats = m_util.misc.add_category(i18n.categories.guides)
    local html = mw.html.create()
        :wikitext(mbox)
        :wikitext(cats)

    return tostring(html)
end

local function _guide_table(args)
    -- Build Cargo query
    local tables = {'guides', '_pageData'}
    local fields = {
        'guides._pageID',
        'guides._pageName',
        'guides._pageTitle',
        'guides.subject',
        'guides.version',
        'guides.date',
        '_pageData._modificationDate',
    }
    local query = {
        where = args.where,
        join = table.concat({'guides._pageID=_pageData._pageID', args.join}, ', '),
        groupBy = table.concat({'guides._pageID', args.groupBy}, ', '),
        having = args.having,
        orderBy = args.orderBy or 'guides._pageName ASC',
        limit = args.limit,
        offset = args.offset,
    }

    -- Append additional tables
    args.tables = m_util.cast.table(args.tables)
    if type(args.tables) == 'table' and #args.tables > 0 then
        tables = m_util.table.merge(tables, args.tables)
    end

    -- Query results
    local results = m_cargo.query(tables, fields, query)
    if #results == 0 then
        return tostring(
            mw.html.create('em')
                :wikitext(i18n.table.no_results)
        )
    end

    -- Build table
    local tbl = mw.html.create('table')
        :addClass('wikitable sortable guide-table')
    local tr = tbl:tag('tr')
    for _, col in ipairs(display.table_map) do
        tr:tag('th')
            :wikitext(col.header)
    end
    for _, row in ipairs(results) do
        tr = tbl:tag('tr')
        for _, col in ipairs(display.table_map) do
            tr:node(col.func(row))
        end
    end
    return tostring(tbl)
end

-- ----------------------------------------------------------------------------
-- Exported functions
-- ----------------------------------------------------------------------------

local p = {}

p.table_guides = m_cargo.declare_factory{data=tables.guides}

-- 
-- Template:Guide
-- 
p.main = m_util.misc.invoker_factory(_main, {
    wrappers = cfg.wrappers.guide,
})
p.guide = p.main

-- 
-- Template:Guide table
-- 
p.guide_table = m_util.misc.invoker_factory(_guide_table, {
    wrappers = cfg.wrappers.guide_table,
})

return p