Module:Passive skill link

From Path of Exile Wiki
Revision as of 09:59, 14 September 2019 by >Illviljan
Jump to navigation Jump to search
Module documentation[view] [edit] [history] [purge]


Lua logo

This module depends on the following other modules:

Implements {{passive skill link}}.

--
-- Module for passive skill links
--

local m_util = require('Module:Util')
local m_cargo = require('Module:Cargo')
local getArgs = require('Module:Arguments').getArgs


-- ----------------------------------------------------------------------------
-- Strings
-- ----------------------------------------------------------------------------

local i18n = {
    icon_name = 'File:%s passive skill icon.png',   
    errors = {
        invalid_args = 'id, int_id, page or name must be specified',
        too_many_passives_found = 'Too many passives found with q_where = %s',
        no_passives_found = 'No passives found with q_where = %s',
        invalid_format = 'Invalid return format specified: %s',
        cats = 'Pages with passive skill link errors'
    },
}


-- ----------------------------------------------------------------------------
-- Constants & Data
-- ----------------------------------------------------------------------------

local c = {}
c.image_size = 39
c.image_size_full = c.image_size * 2
c.parameters = {
    name = 'passive_skills.name',
    icon = 'passive_skills.icon',
    is_keystone = 'passive_skills.is_keystone',
    is_notable = 'passive_skills.is_notable',
    ascendancy_class = 'passive_skills.ascendancy_class', 
    html = 'passive_skills.html',
}

c.selectors = {'id', 'int_id', 'page', 'name'}


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

local h = {}

h.type_order = {
    'basic', 
    'notable', 
    'keystone', 
    'ascendancy_basic', 
    'ascendancy_notable'
}
function h.get_type(passive)
    local key
    if tonumber(passive['passive_skills.is_keystone']) == 1 then
        key = 'keystone'
    elseif tonumber(passive['passive_skills.is_notable']) == 1 then
        key = 'notable'
    else
        key = 'basic'
    end
    
    if passive['passive_skills.ascendancy_class'] ~= nil then
        key = 'ascendancy_' .. key
    end
    
    return key
end

function h.format_passive_icon(passive, tpl_args)
    --[[
    Add a frame to passive image.
    
    TODO: Add a inline size.
    ]]
    
    if passive['passive_skills.icon'] == nil then
        return ''
    end
    local cls = string.format('passive-icon-type__%s', h.get_type(passive))
    local main_page = passive['passive_skills.main_page'] 
                   or passive['main_pages._pageName'] 
                   or passive['passive_skills.name'] 
                   or passive['passive_skills.icon']
    
    div = mw.html.create('div')
    div:addClass('passive-icon-container')
    div:addClass(cls)
    if tpl_args.large then 
        div:tag('div')
            :addClass('passive-icon-frame')
            :done()
        div:wikitext(
            string.format(
                '[[%s|link=%s]]', 
                passive['passive_skills.icon'], 
                main_page
            )
        )
    else     
        -- Inline size
        div:tag('div')
            :addClass('passive-icon-frame')
            -- :attr('style', 'height:16px;width:16px')
            :done()
        div:wikitext(
            string.format(
                '[[%s|link=%s]]', 
                passive['passive_skills.icon'], 
                main_page
            )
        )
    end 
    return tostring(div)
end

-- ----------------------------------------------------------------------------
-- Page functions
-- ----------------------------------------------------------------------------

local p = {}

function p.passive_skill_link(frame)
    --[[
    Links a passive skill.
    
    TODO:
    * Use own CSS.
    
    Examples
    --------
    = p.passive_skill_link{id='AscendancyAscendant45'}
    = p.passive_skill_link{
        skip_query=true,
        page='Passive Skill:AscendancyAscendant45', 
        name='test', 
        icon='File:GLADSpeedAoE (Gladiator) passive skill icon.png',
        large=1,
    }
    = p.passive_skill_link{id='AscendancyAscendant45', format='tablerow'}
    
    ]]
    
    -- Get args
    tpl_args = getArgs(frame, {
        parentFirst = true
    })
    frame = m_util.misc.get_frame(frame)
    
    if m_util.table.has_all_value(tpl_args, c.selectors) and tpl_args.skip_query == nil then
        return m_util.html.error{msg=i18n.errors.invalid_args .. m_util.misc.add_category(i18n.errors.cats)}
    end 
    
    local passive
    if m_util.table.has_one_value(tpl_args, c.selectors, nil) and tpl_args.skip_query == nil then
        tpl_args.name = tpl_args.name or tpl_args[1]
        if tpl_args.name then
            tpl_args.q_where = string.format('passive_skills.name="%s"', tpl_args.name)
        elseif tpl_args.id then
            tpl_args.q_where = string.format('passive_skills.id="%s"', tpl_args.id)
        elseif tpl_args.q_where then
        else
            return m_util.html.error{
                msg=i18n.errors.invalid_args .. m_util.misc.add_category(i18n.errors.cats)
            }
        end
        
        local results = m_cargo.query(
            {'passive_skills', 'main_pages'},
            {
                'passive_skills._pageName', 
                'passive_skills.stat_text',
                'passive_skills.main_page',
                'passive_skills.name',
                'passive_skills.icon',
                'passive_skills.is_keystone',
                'passive_skills.is_notable',
                'passive_skills.ascendancy_class',
                'main_pages._pageName',
            }, 
            {   
                join='passive_skills.id=main_pages.id',
                where=string.format(
                    '(%s)', 
                    tpl_args.q_where
                ),
                orderBy='passive_skills.stat_text',
                limit=2,
            }
        )
        
        if #results > 1 then
            return m_util.html.error{
                msg=string.format(
                    i18n.errors.too_many_passives_found, 
                    tostring(tpl_args.q_where) .. m_util.misc.add_category(i18n.errors.cats)
                    )
                }
        elseif #results < 1 then
            return m_util.html.error{
                msg=string.format(
                    i18n.errors.no_passives_found, 
                    tostring(tpl_args.q_where) .. m_util.misc.add_category(i18n.errors.cats)
                )
            }
        end
        
        passive = results[1]
    else
        passive = {
            ['passive_skills.main_page']=tpl_args.page or tpl_args.name
        }
    end
    
    for k, prop in pairs(c.parameters) do
        if tpl_args[k] ~= nil then
            passive[prop] = tpl_args[k]
        end
    end
    
    if tpl_args.image ~= nil then
        passive['passive_skills.icon'] = 'File:' .. tpl_args.image
    end
    local img = h.format_passive_icon(passive, tpl_args)
    
    local main_page = passive['passive_skills.main_page'] 
                   or passive['main_pages._pageName'] 
                   -- or passive['passive_skills.name']
                   or passive['passive_skills._pageName'] 


    ---------------------------------------------------------------------------
    -- Output
    ---------------------------------------------------------------------------
    
    -- Display in a table:
    if tpl_args.format == 'tablerow' then
        return string.format(
            '| [[%s|%s]]%s\n| %s', 
            main_page, 
            passive['passive_skills.name'], 
            h.format_passive_icon(passive, tpl_args), 
            passive['passive_skills.stat_text']
        )
    
    -- Normal inline link: 
    elseif tpl_args.format == nil then              
        local container = mw.html.create('span')
        container:addClass('c-item-hoverbox')

        if tpl_args.large then
            container:addClass('c-item-hoverbox--large')
        end
        
        local activator = mw.html.create('span')
        activator:addClass('c-item-hoverbox__activator')

        if img and not tpl_args.large then
            activator:wikitext(img)
        end
           
        activator:wikitext(string.format(
            '[[%s|%s]]', 
            main_page, 
            passive['passive_skills.name'] or main_page
            )
        )
        
        local display = mw.html.create('span')
        display:attr('class', 'c-item-hoverbox__display')
        
        if passive['passive_skills.html'] ~= nil then    
            display:wikitext(passive['passive_skills.html'])
                
            if img then
                display:wikitext(img)
            end
        end

        if img and tpl_args.large then
            activator:wikitext(img)
        end

        container
            :node(activator)
            :node(display)
            :done()
            
        return tostring(container)
    else
        return m_util.html.error{
            msg=string.format(i18n.error.invalid_format, tpl_args.format .. m_util.misc.add_category(i18n.errors.cats))
        }
    end
end





-- ----------------------------------------------------------------------------
-- End
-- ----------------------------------------------------------------------------

return p