Module:Guide

From The Observatory

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

local p = {}

-- Helper message extractor
local function getMessage(msg)
    return mw.message.new(msg):plain()
end


-- Helper function to format a list of items as formatted links
local function formatted_list(items, prefix)
    local formatted_items = {}

    for item in items:gmatch("[^;]+") do
        item = mw.text.trim(item) -- Trim spaces around the name
        table.insert(formatted_items, '[[' .. item .. ']]')
    end

    local formatted_list
    if #formatted_items > 1 then
        local last_item = table.remove(formatted_items) -- Remove the last item
        formatted_list = table.concat(formatted_items, ", ") .. " and " .. last_item
    else
        formatted_list = formatted_items[1] or "" -- Return the single item or an empty string
    end

    -- Add prefix if provided
    if prefix and prefix ~= "" then
        formatted_list = prefix .. formatted_list
    end

    return formatted_list
end

function p.main(frame)

    local page             = tostring(mw.title.getCurrentTitle())
    local template         = frame:getParent().args
    local category         = '[[Category:Guides]]'

    local display_name     = template['Display name'] or page or ''
    local teaser           = template['About'] or ''
    local guide_editor     = template['Guide editor'] or ''
    local source           = template['Source'] or ''
    local cover_image      = template['Cover image'] or ''

    local filename         = ''
    if cover_image ~= '' then
         filename = frame:preprocess('File:{{PAGENAME:' .. cover_image .. '}}') or ''
    end

    local suppress_caption = template['Suppress uploaded media caption'] or 'No'
    local caption          = ''
    if suppress_caption == 'Yes' then
         caption = template['Cover image caption'] or ''
    else
         caption = tostring(frame:callParserFunction( '#ask',
             '[[' .. filename .. ']][[License short::+]]',
             '?License URL',
             '?License short',
             '?Media credits URL',
             '?Media credits text',
             '?Other text',
             'named args=yes',
             'format=plainlist',
             'mainlabel=-',
             'headers=hide',
             'link=none',
             'template=Image attribution'
          ))
    end

    local limit_img_width  = template['Limit uploaded media width'] or 'No'
    local limit            = template['Limit'] or ''
    local img_width        = ''
    if limit_img_width == 'Yes' and limit ~= '' then
        img_width = limit .. 'px'
    end

    if display_name ~= '' then
	    frame:preprocess('{{DISPLAYTITLE:' .. display_name .. '|noreplace|noerror}}')
        frame:preprocess('{{DEFAULTSORT:' .. display_name .. '}}')
    end

    local articles         = template['Articles'] or {}

    local set_properties   = frame:callParserFunction( '#set',
        'Teaser=' .. teaser,
        'Cover image=' .. filename,
        'Guide editor=' .. guide_editor,
        'Source=' .. source,
        '+sep=;'
    )
    
    local html = mw.html.create()

-- ARTICLE PATH

local articlepath = html:tag('div')
    :attr('id', 'article-path')
    :addClass( 'interface d-flex align-items-center justify-content-between' )
    :addClass( 'font-weight-bold text-uppercase d-print-none screenonly noprint' )

articlepath:tag('span')
    :attr('id', 'observatory-path')
    :addClass( 'd-print-none noprint' )
    :wikitext('[[' .. 
          frame:preprocess('{{int:mainpage}}|{{SITENAME}}') ..
         ']] » ' ..
         '[[Guides]]'
     )

    html:tag('div')
        :addClass( 'd-none' )
        :wikitext(  )
    
    if cover_image ~= '' then
        html:tag('div')
            :attr('id', 'cover-image')
            :wikitext('[[' .. filename .. '|thumb|' .. caption .. '|' .. img_width .. ']]')
    end

    local authorship = html:tag('div')
        :addClass( 'd-flex w-100 flex-column flex-md-row justify-content-between' )

    authorship:tag('div')
        :addClass( 'interface' )
        :wikitext(formatted_list(guide_editor, 'Editor: '))

    authorship:tag('div')
        :addClass( 'interface mb-3' )
        :wikitext(formatted_list(source, 'Source: '))

    html:tag('div')
        :addClass( 'mt-3 mb-5 text-muted' )
        :newline()
        :wikitext( teaser )

    html:tag('div')
        :wikitext( articles )

    -- Initialize the sideblock
    local sideblock = html:tag('div')
        :attr('id', 'article-sources')
        :addClass('my-4 text-left interface')
        :css('flex', '0 0 280px')

    local all_guides = mw.smw.ask( '[[Category:Guides]][[!' .. page .. ']]' ) or {}

    if #all_guides > 0 then
         for _, guide in ipairs(all_guides) do
             sideblock:tag('div')
                 :addClass('py-1')
                 :wikitext('<i class="far fa-map mr-2"></i>' .. tostring(guide[1]))
         end
    end

    local guide = tostring(html) .. tostring(sideblock) .. category

    frame:callParserFunction(
       '#counter',
       'stepcount',
       'type=numeric',
       'set=0'
    )
    return guide
end

return p