Module:Badge

From Homecoming Wiki
Jump to navigation Jump to search

This module returns detailed information about a badge, or a list or table of badges matching given parameters.

To output a summary containing images, maps, links, and data for a badge, on that badge's page: {{#invoke:Badge|summary|alt=…}}. The alt parameter sets the image's alternative text for non-visual browsers, and should briefly describe what the badge image looks like: location, surroundings, and other visible features.

To output a summary for a badge different than the page's title, add the badge's name as the first anonymous argument, for example: {{#invoke:Badge|summary|Top Dog|alt=…}}.

This module uses data from Module:Badge data, and Module:Map data.


local function generate_summary(name, alt)
    local badge_data = mw.loadData('Module:Badge data')

    for _, b in ipairs(badge_data) do
        if name == b['name'] then
            -- Outer container div
            local summary_root = mw.html.create('div')
                :addClass('summary')
                :attr('itemscope', '')
                :attr('itemtype', 'http://schema.org/Thing')

            summary_root
                :tag('meta')
                    :attr('itemprop', 'name')
                    :attr('content', name)

            -- Skip link, for accessible keyboard navigation
            summary_root
                :tag('div')
                    :addClass('skip-link')
                    :wikitext('[[#introduction|Jump to introduction]]')

            summary_root
                :tag('h2')
                    :addClass('summary-heading')
                    :wikitext('Badge')

            -- Slideshow
            if b['images'] then
                local summary_slideshow = summary_root:tag('div')
                    :attr('role', 'figure')
                    :wikitext('[[File:' .. b['images'][1] .. '|link=|alt=]]')
                if b['images'][2] then
                    summary_slideshow
                        :wikitext('[[File:' .. b['images'][2] .. '|link=|alt=]]')
                end
            end

            -- Map
            if b['locations'] and b['locations'][1] then
                local map_data = mw.loadData('Module:Map data')

                for _, m in ipairs(map_data) do
                    if b['locations'][1][1] == m['name'] then
                        local mapbasename = m['name']
                            :gsub(' ', '-')
                            :gsub('\'', '')
                            :gsub(':', '')

                        local pixelsize = math.max(m['width'], m['height'])
                        local aspectratio = m['width'] / m['height']
                        local xsize = (m['west'] - m['east']) / math.min(aspectratio, 1)
                        local zsize = (m['south'] - m['north']) * math.max(aspectratio, 1)
                        local right = (m['east'] + m['west'] - xsize) / 2
                        local top = (m['north'] + m['south'] - zsize) / 2

                        summary_root:tag('div')
                            :addClass('figure-button')
                            :addClass(m['background'] or nil)
                            :attr('data-highquality', '{{filepath:' .. mapbasename .. '-map.png}}')
                            :attr('data-zoomout', 'top:' .. (pixelsize - m['height']) / pixelsize * 50 - 50 .. '%;right:' .. (pixelsize - m['width']) / pixelsize * 50 - 50 .. '%;width:' .. m['width'] / pixelsize * 100 .. '%;height:' .. m['height'] / pixelsize * 100 .. '%;background:center/100% url("{{filepath:' .. mapbasename .. '-map.jpeg}}");')
                            :attr('data-zoomin', 'top:' .. (top - b['locations'][1][4]) / zsize * pixelsize + (pixelsize - m['height']) / 2 .. 'px;right:' .. (right - b['locations'][1][2]) / xsize * pixelsize + (pixelsize - m['width']) / 2 .. 'px;width:' .. m['width'] .. 'px;height:' .. m['height'] .. 'px;background:center/100% url("{{filepath:' .. mapbasename .. '-map.jpeg}}");')
                            :attr('data-overlay', 'top:' .. (b['locations'][1][4] - top) / zsize * 100 .. '%;right:' .. (b['locations'][1][2] - right) / xsize * 100 .. '%;')
                            :tag('div')
                                :attr('role', 'figure')
                                :tag('div')
                                    :attr('role', 'img')
                                    :tag('div')
                                        :addClass('frame')
                                        :tag('div')
                                            :addClass('container')
                                            :attr('style', 'top:' .. (pixelsize - m['height']) / pixelsize * 50 - 50 .. '%;right:' .. (pixelsize - m['width']) / pixelsize * 50 - 50 .. '%;width:' .. m['width'] / pixelsize * 100 .. '%;height:' .. m['height'] / pixelsize * 100 .. '%;')
                                            :wikitext('[[File:' .. mapbasename .. '-map.jpeg|link=|alt=]]')
                                            :done()
                                        :done()
                                    :tag('div')
                                        :addClass(m['explorationicons'][2] and 'icon-overlay-alternate' or 'icon-overlay')
                                        :attr('style', 'top:' .. (b['locations'][1][4] - top) / zsize * 100 .. '%;right:' .. (b['locations'][1][2] - right) / xsize * 100 .. '%;')
                                        :wikitext('[[File:' .. m['explorationicons'][1] .. '|link=|alt=]]' .. (m['explorationicons'][2] and '[[File:' .. m['explorationicons'][2] .. '|link=|alt=]]' or ''))
                                        :done()
                                    :done()
                                :done()
                            :tag('div')
                                :addClass('button')
                                :attr('data-function', 'zoom')

                        break
                    end
                end
            end

            -- Data figure
            local summary_data = summary_root:tag('div')
                :attr('role', 'figure')
                :attr('aria-label', 'summary')
                :addClass('summary-data')
                :tag('dl')
                    :addClass('float-container')

            -- Data: Alternate names
            if b['alternatenames'] then
                local i = 1
                while b['alternatenames'][i] do
                    summary_data
                        :tag('dt')
                            :wikitext(b['alternatenames'][i][1] == 'hero' and 'Hero/vigilante' or b['alternatenames'][i][1] == 'villain' and 'Villain/rogue' or b['alternatenames'][i][1] == 'male' and 'Male' or b['alternatenames'][i][1] == 'female' and 'Female' or b['alternatenames'][i][1] == 'hero male' and 'Hero/vigilante male' or b['alternatenames'][i][1] == 'hero female' and 'Hero/vigilante female' or b['alternatenames'][i][1] == 'villain male' and 'Villain/rogue male' or b['alternatenames'][i][1] == 'villain female' and 'Villain/rogue female' or '')
                            :done()
                        :tag('dd')
                            :wikitext(b['alternatenames'][i][2])
                    i = i + 1
                end
            end

            -- Data: Category
            summary_data
                :tag('dt')
                    :wikitext('Category')
                    :done()
                :tag('dd')
                    :wikitext(b['category'])

            -- Data: Door locations
            if b['doorlocations'] then
                summary_data
                    :tag('dt')
                        :wikitext((b['doorlocations'][2] or b['doorlocations'][1][6]) and 'Door locations' or 'Door location')

                local i = 1
                while b['doorlocations'][i] do
                    summary_data
                        :tag('dd')
                            :wikitext(b['doorlocations'][i][1] .. ' {{coordinates|' .. b['doorlocations'][i][2] .. '|' .. b['doorlocations'][i][3] .. '|' .. b['doorlocations'][i][4] .. '}}' .. (b['doorlocations'][i][5] and ' ' .. b['doorlocations'][i][5] .. ' {{coordinates|' .. b['doorlocations'][i][6] .. '|' .. b['doorlocations'][i][7] .. '|' .. b['doorlocations'][i][8].. '}}' or ''))
                    i = i + 1
                end
            end

            -- Data: Locations
            if b['locations'] then
                summary_data
                    :tag('dt')
                        :wikitext(b['locations'][2] and 'Locations' or 'Location')

                local i = 1
                while b['locations'][i] do
                    summary_data
                        :tag('dd')
                            :wikitext(b['locations'][i][1] .. ' {{coordinates|' .. b['locations'][i][2] .. '|' .. b['locations'][i][3] .. '|' .. b['locations'][i][4] .. '}}')
                    i = i + 1
                end
            end

            -- Data: Alignment
            if b['alignment'] then
                summary_data
                    :tag('dt')
                        :wikitext('Alignment')

                if b['alignment'] == 'hero' then
                    summary_root
                        :addClass('blueside')
                    summary_data
                        :tag('dd')
                            :wikitext('hero/vigilante')
                elseif b['alignment'] == 'villain' then
                    summary_root
                        :addClass('redside')
                    summary_data
                        :tag('dd')
                            :wikitext('villain/rogue')
                end
            end

            -- Data: ID
            summary_data
                :tag('dt')
                    :wikitext('Title ID')
                    :done()
                :tag('dd')
                    :wikitext(b['titleid'] == 0 and '[{{fullurl:Module:Badge data|action=edit}} add this data]' or b['titleid'])

            -- Data: Requires
            if b['requires'] then
                summary_data
                    :tag('dt')
                        :wikitext('Requires')

                local i = 1
                while b['requires'][i] do
                    summary_data
                        :tag('dd')
                            :wikitext(b['requires'][i])
                    i = i + 1
                end
            end

            -- Data: Required for
            if b['requiredfor'] then
                summary_data
                    :tag('dt')
                        :wikitext('Required for')

                local i = 1
                while b['requiredfor'][i] do
                    summary_data
                        :tag('dd')
                            :wikitext(b['requiredfor'][i])
                    i = i + 1
                end
            end

            -- Return summary, breadcrumb trail, and introduction region placeholder
            return '__NOTOC__' .. tostring(summary_root) .. '{{#invoke:Breadcrumbs|breadcrumbs|Badge|' .. b['category'] .. (b['category'] == 'accolade' and '' or ' badge') .. '}}<div role="region" id="introduction"></div>'
        end
    end

    return '<div class="error">[[Module:Badge]]: "' .. name .. '" not found in badge data table.</div>[[Category:Pages with script errors]]'
end

local p = {}

function p.summary(frame)
    return frame:preprocess(generate_summary(frame['args'][1] or mw.title.getCurrentTitle().text:match('(.+) %(.*%)') or mw.title.getCurrentTitle().text, frame['args']['alt']))
end

return p