Module:Template documentation

From Roots of Pacha Wiki
Jump to navigation Jump to search

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

--- Does formatting of our template documentation, including
--  [[Template:Documentation]], [[Template:Documentation page]],
--  [[Template:Parameters]] and [[Template:Samples]].
--  @module             template_documentation
--  @alias              p
--  <nowiki>
local p = {}

--  Private logic.

--- Creates a page section with specified content.
--  @function           page_section
--  @param              {table} t Table to insert the section into
--  @param              {string} name Section name
--  @param              {string} content Section content
--  @returns            {string} Formatted section with its contents
--  @local
local function page_section(t, name, content)
    local trimmed = content and mw.text.trim(content) or ''
    if trimmed ~= '' then
        table.insert(t, '== ')
        table.insert(t, name)
        table.insert(t, ' ==\n')
        table.insert(t, trimmed)
        table.insert(t, '\n')
    end
end

--  Package items.

--- Template entrypoint for [[Template:Documentation]].
--  @function           p.docs
--  @param              {table} frame Scribunto frame object
--  @returns            {string} Documentation to display on the template page
function p.docs(frame)
    local title = mw.title.getCurrentTitle()
    -- THIS IS EXPENSIVE
    local docs = mw.title.new(title.fullText .. '/doc')
    local html = mw.html.create('div'):addClass('template-documentation')
    -- Links
    local editLink =  tostring(docs:fullUrl({ action = 'edit' }))
    local historyLink = tostring(docs:fullUrl({ action = 'history' }))
    local purgeLink = tostring(title:fullUrl({ action = 'purge' }))
    if docs.exists then
        html:tag('div')
                :addClass('template-documentation__header')
                :tag('div')
                    :addClass('template-documentation__title')
                    :wikitext('[[/doc|Template documentation]]')
                :done()
                :tag('div')
                    :addClass('template-documentation__buttons plainlinks')
                    :wikitext(table.concat({
                        '[[', editLink, ' edit] • [', historyLink,
                        ' history] • [', purgeLink, ' purge]]'
                    }))
                :done()
            :done()
            :tag('div')
                :addClass('template-documentation__contents')
                :wikitext(frame:preprocess(docs:getContent()))
            :done()
    else
        html:tag('div')
            :addClass('template-documentation__error')
            :wikitext(table.concat({
                'This template has no documentation! Click [', editLink,
                ' here] to create it or [', purgeLink,
                ' here] to purge the current page after the documentation has been created'
            }))
            :done()
    end
    return tostring(html:done())
end

--- Template entrypoint for [[Template:Documentation page]].
--  @function           p.page
--  @param              {table} frame Scribunto frame object
--  @returns            {string} Template documentation contents
function p.page(frame)
    local args = frame:getParent().args
    local content = {}
    table.insert(content, args.description or 'This template is missing a description!')
    table.insert(content, '\n')
    page_section(content, 'Parameters', args.parameters)
    page_section(content, 'Sample output', args.samples)
    page_section(content, 'See also', args.see)
    local title = mw.title.getCurrentTitle()
    if title.namespace == 10 then
        -- We're in template namespace
        if title.subpageText == 'doc' then
            -- We're on a documentation subpage
            table.insert(content, '[[Category:Template documentation]]')
        elseif args.category then
            for _, cat in ipairs(mw.text.split(args.category, ',', true)) do
                table.insert(content, '[[Category:')
                table.insert(content, cat)
                table.insert(content, ' templates]]')
            end
        end
    end
    table.insert(content, '__NOTOC____NOEDITSECTION__')
    return frame:preprocess(table.concat(content))
end

--- Template entrypoint for [[Template:Parameters]].
--  @function           p.parameters
--  @param              {table} frame Scribunto frame object
--  @returns            {string} Template parameters formatted into a table
function p.parameters(frame)
    local html = mw.html.create('table')
        :addClass('wikitable')
        :addClass('template-documentation__parameters')
    html:tag('tr')
            :tag('th')
                :wikitext('Parameter')
            :done()
            :tag('th')
                :wikitext('Description')
            :done()
        :done()
    for k, v in pairs(frame:getParent().args) do
        html:tag('tr')
                :tag('td')
                    :wikitext(table.concat({'<code>', k, '</code>'}))
                :done()
                :tag('td')
                    :wikitext(v)
                :done()
            :done()
    end
    return tostring(html)
end

--- Template entrypoint for [[Template:Samples]].
--  @function           p.samples
--  @param              {table} frame Scribunto frame object
--  @returns            {string} Samples to display on the template page
function p.samples(frame)
    local ret = {}
    local args
    if frame.args.documentation then
        -- We can't use the template for purposes of documenting
        -- that template due to the template loop...
        args = frame.args
    else
        args = frame:getParent().args
    end
    for _, value in ipairs(args) do
        local sample = mw.text.trim(mw.text.decode(mw.text.unstrip(value)))
        table.insert(ret, '<p class="template-documentation__example">')
        if mw.ustring.match(sample, '\n') then
            table.insert(ret, '<pre>')
            table.insert(ret, sample)
            table.insert(ret, '</pre>')
        else
            table.insert(ret, '<code><nowiki>')
            table.insert(ret, sample)
            table.insert(ret, '</nowiki></code>')
        end
        table.insert(ret, ' gives...</p> ')
        table.insert(ret, sample)
        table.insert(ret, '\n')
    end
    return frame:preprocess(table.concat(ret)) .. '\n'
end

return p
--  </nowiki>