Module:Documentation: Difference between revisions

    No edit summary
    m>Mr. Stradivarius
    (use title.protectionLevels instead of {{PROTECTIONLEVEL}} in p.protectionTemplate)
    Line 1: Line 1:
    -- This module implements {{documentation}}.
    -- This module implements {{documentation}}.
     
    -- Get required modules.
    -- Get required modules.
    local getArgs = require('Module:Arguments').getArgs
    local getArgs = require('Module:Arguments').getArgs
    local htmlBuilder = require('Module:HtmlBuilder')
    local htmlBuilder = require('Module:HtmlBuilder')
    local messageBox = require('Module:Message box')
    local messageBox = require('Module:Message box')
     
    -- Get the config table.
    -- Get the config table.
    local cfg = mw.loadData('Module:Documentation/config')
    local cfg = mw.loadData('Module:Documentation/config')
     
    local p = {}
    local p = {}
     
    -- Often-used functions.
    -- Often-used functions.
    local ugsub = mw.ustring.gsub
    local ugsub = mw.ustring.gsub
     
    ----------------------------------------------------------------------------
    ----------------------------------------------------------------------------
    -- Helper functions
    -- Helper functions
    Line 20: Line 20:
    -- table for testing purposes.
    -- table for testing purposes.
    ----------------------------------------------------------------------------
    ----------------------------------------------------------------------------
     
    local function message(cfgKey, valArray, expectType)
    local function message(cfgKey, valArray, expectType)
    --[[
    --[[
    Line 39: Line 39:
    return msg
    return msg
    end
    end
     
    local function getMessageVal(match)
    local function getMessageVal(match)
    match = tonumber(match)
    match = tonumber(match)
    return valArray[match] or error('message: no value found for key $' .. match .. ' in message cfg.' .. cfgKey, 4)
    return valArray[match] or error('message: no value found for key $' .. match .. ' in message cfg.' .. cfgKey, 4)
    end
    end
     
    local ret = ugsub(msg, '$([1-9][0-9]*)', getMessageVal)
    local ret = ugsub(msg, '$([1-9][0-9]*)', getMessageVal)
    return ret
    return ret
    end
    end
     
    p.message = message
    p.message = message
     
    local function makeWikilink(page, display)
    local function makeWikilink(page, display)
    if display then
    if display then
    Line 58: Line 58:
    end
    end
    end
    end
     
    p.makeWikilink = makeWikilink
    p.makeWikilink = makeWikilink
     
    local function makeCategoryLink(cat, sort)
    local function makeCategoryLink(cat, sort)
    local catns = mw.site.namespaces[14].name
    local catns = mw.site.namespaces[14].name
    return makeWikilink(catns .. ':' .. cat, sort)
    return makeWikilink(catns .. ':' .. cat, sort)
    end
    end
     
    p.makeCategoryLink = makeCategoryLink
    p.makeCategoryLink = makeCategoryLink
     
    local function makeUrlLink(url, display)
    local function makeUrlLink(url, display)
    return mw.ustring.format('[%s %s]', url, display)
    return mw.ustring.format('[%s %s]', url, display)
    end
    end
     
    p.makeUrlLink = makeUrlLink
    p.makeUrlLink = makeUrlLink
     
    local function makeToolbar(...)
    local function makeToolbar(...)
    local ret = {}
    local ret = {}
    Line 85: Line 85:
    return '<small style="font-style: normal;">(' .. table.concat(ret, ' &#124; ') .. ')</small>'
    return '<small style="font-style: normal;">(' .. table.concat(ret, ' &#124; ') .. ')</small>'
    end
    end
     
    p.makeToolbar = makeToolbar
    p.makeToolbar = makeToolbar
     
    ----------------------------------------------------------------------------
    ----------------------------------------------------------------------------
    -- Argument processing
    -- Argument processing
    ----------------------------------------------------------------------------
    ----------------------------------------------------------------------------
     
    local function makeInvokeFunc(funcName)
    local function makeInvokeFunc(funcName)
    return function (frame)
    return function (frame)
    Line 111: Line 111:
    end
    end
    end
    end
     
    ----------------------------------------------------------------------------
    ----------------------------------------------------------------------------
    -- Main function
    -- Main function
    ----------------------------------------------------------------------------
    ----------------------------------------------------------------------------
     
    p.main = makeInvokeFunc('_main')
    p.main = makeInvokeFunc('_main')
     
    function p._main(args)
    function p._main(args)
    --[[
    --[[
    Line 150: Line 150:
    return tostring(root)
    return tostring(root)
    end
    end
     
    ----------------------------------------------------------------------------
    ----------------------------------------------------------------------------
    -- Environment settings
    -- Environment settings
    ----------------------------------------------------------------------------
    ----------------------------------------------------------------------------
     
    function p.getEnvironment(args)
    function p.getEnvironment(args)
    --[[
    --[[
    Line 170: Line 170:
    --
    --
    -- Data includes:
    -- Data includes:
    -- env.protectionLevels - the protection levels table of the title object.
    -- env.subjectSpace - the number of the title's subject namespace.
    -- env.subjectSpace - the number of the title's subject namespace.
    -- env.docSpace - the number of the namespace the title puts its documentation in.
    -- env.docSpace - the number of the namespace the title puts its documentation in.
    Line 178: Line 179:
    -- returned will be nil.
    -- returned will be nil.
    --]]
    --]]
    local env, envFuncs = {}, {}
    local env, envFuncs = {}, {}
     
    -- Set up the metatable. If triggered we call the corresponding function in the envFuncs table. The value
    -- Set up the metatable. If triggered we call the corresponding function in the envFuncs table. The value
    -- returned by that function is memoized in the env table so that we don't call any of the functions
    -- returned by that function is memoized in the env table so that we don't call any of the functions
    Line 197: Line 198:
    end
    end
    })
    })
     
    function envFuncs.title()
    function envFuncs.title()
    -- The title object for the current page, or a test page passed with args.page.
    -- The title object for the current page, or a test page passed with args.page.
    Line 209: Line 210:
    return title
    return title
    end
    end
     
    function envFuncs.templateTitle()
    function envFuncs.templateTitle()
    --[[
    --[[
    Line 226: Line 227:
    end
    end
    end
    end
     
    function envFuncs.docTitle()
    function envFuncs.docTitle()
    --[[
    --[[
    Line 243: Line 244:
    return mw.title.new(docpage)
    return mw.title.new(docpage)
    end
    end
    function envFuncs.sandboxTitle()
    function envFuncs.sandboxTitle()
    --[[
    --[[
    Line 252: Line 253:
    return mw.title.new(env.docpageBase .. '/' .. message('sandbox-subpage'))
    return mw.title.new(env.docpageBase .. '/' .. message('sandbox-subpage'))
    end
    end
    function envFuncs.testcasesTitle()
    function envFuncs.testcasesTitle()
    --[[
    --[[
    Line 261: Line 262:
    return mw.title.new(env.docpageBase .. '/' .. message('testcases-subpage'))
    return mw.title.new(env.docpageBase .. '/' .. message('testcases-subpage'))
    end
    end
    function envFuncs.printTitle()
    function envFuncs.printTitle()
    --[[
    --[[
    Line 270: Line 271:
    return env.templateTitle:subPageTitle(message('print-subpage'))
    return env.templateTitle:subPageTitle(message('print-subpage'))
    end
    end
     
    function envFuncs.protectionLevels()
    -- The protection levels table of the title object.
    return env.title.protectionLevels
    end
     
    function envFuncs.subjectSpace()
    function envFuncs.subjectSpace()
    -- The subject namespace number.
    -- The subject namespace number.
    return mw.site.namespaces[env.title.namespace].subject.id
    return mw.site.namespaces[env.title.namespace].subject.id
    end
    end
     
    function envFuncs.docSpace()
    function envFuncs.docSpace()
    -- The documentation namespace number. For most namespaces this is the same as the
    -- The documentation namespace number. For most namespaces this is the same as the
    Line 287: Line 293:
    end
    end
    end
    end
     
    function envFuncs.docpageBase()
    function envFuncs.docpageBase()
    -- The base page of the /doc, /sandbox, and /testcases subpages.
    -- The base page of the /doc, /sandbox, and /testcases subpages.
    Line 297: Line 303:
    return docSpaceText .. ':' .. templateTitle.text
    return docSpaceText .. ':' .. templateTitle.text
    end
    end
    function envFuncs.compareUrl()
    function envFuncs.compareUrl()
    -- Diff link between the sandbox and the main template using [[Special:ComparePages]].
    -- Diff link between the sandbox and the main template using [[Special:ComparePages]].
    Line 312: Line 318:
    end
    end
    end
    end
     
    return env
    return env
    end
    end
     
    ----------------------------------------------------------------------------
    ----------------------------------------------------------------------------
    -- Auxiliary templates
    -- Auxiliary templates
    ----------------------------------------------------------------------------
    ----------------------------------------------------------------------------
     
    function p.sandboxNotice(args, env)
    function p.sandboxNotice(args, env)
    --[=[
    --[=[
    Line 385: Line 391:
    return ret
    return ret
    end
    end
     
    function p.protectionTemplate(env)
    function p.protectionTemplate(env)
    -- Generates the padlock icon in the top right.
    -- Generates the padlock icon in the top right.
    Line 393: Line 399:
    -- 'protection-template-args' --> {docusage = 'yes'}
    -- 'protection-template-args' --> {docusage = 'yes'}
    local title = env.title
    local title = env.title
    local protectionLevels
    local protectionTemplate = message('protection-template')
    local protectionTemplate = message('protection-template')
    local namespace = title.namespace
    local namespace = title.namespace
    Line 399: Line 406:
    return nil
    return nil
    end
    end
    local frame = mw.getCurrentFrame()
    protectionLevels = env.protectionLevels
    local function getProtectionLevel(protectionType, page)
    local editLevels = protectionLevels.edit
    -- Gets the protection level for page, or for the current page if page is not specified.
    local moveLevels = protectionLevels.move
    local level = frame:callParserFunction('PROTECTIONLEVEL', protectionType, page)
    if moveLevels and moveLevels[1] == 'sysop' or editLevels and editLevels[1] then
    if level ~= '' then
    return level
    else
    return nil -- The parser function returns the blank string if there is no match.
    end
    end
    local prefixedTitle = title.prefixedText
    if getProtectionLevel('move', prefixedTitle) == 'sysop' or getProtectionLevel('edit', prefixedTitle) then
    -- The page is full-move protected, or full, template, or semi-protected.
    -- The page is full-move protected, or full, template, or semi-protected.
    local frame = mw.getCurrentFrame()
    return frame:expandTemplate{title = protectionTemplate, args = message('protection-template-args', nil, 'table')}
    return frame:expandTemplate{title = protectionTemplate, args = message('protection-template-args', nil, 'table')}
    else
    return nil
    end
    end
    return nil
    end
    end
     
    ----------------------------------------------------------------------------
    ----------------------------------------------------------------------------
    -- Start box
    -- Start box
    ----------------------------------------------------------------------------
    ----------------------------------------------------------------------------
     
    p.startBox = makeInvokeFunc('_startBox')
    p.startBox = makeInvokeFunc('_startBox')
     
    function p._startBox(args, env)
    function p._startBox(args, env)
    --[[
    --[[
    Line 452: Line 453:
    end
    end
    end
    end
     
    function p.makeStartBoxLinksData(args, env)
    function p.makeStartBoxLinksData(args, env)
    --[[
    --[[
    Line 475: Line 476:
    return nil
    return nil
    end
    end
     
    local data = {}
    local data = {}
    data.title = title
    data.title = title
    Line 499: Line 500:
    return data
    return data
    end
    end
     
    function p.renderStartBoxLinks(data)
    function p.renderStartBoxLinks(data)
    --[[
    --[[
    Line 505: Line 506:
    -- @data - a table of data generated by p.makeStartBoxLinksData
    -- @data - a table of data generated by p.makeStartBoxLinksData
    --]]
    --]]
    local function escapeBrackets(s)
    local function escapeBrackets(s)
    -- Escapes square brackets with HTML entities.
    -- Escapes square brackets with HTML entities.
    Line 512: Line 513:
    return s
    return s
    end
    end
     
    local ret
    local ret
    local docTitle = data.docTitle
    local docTitle = data.docTitle
    Line 532: Line 533:
    return ret
    return ret
    end
    end
     
    function p.makeStartBoxData(args, env, links)
    function p.makeStartBoxData(args, env, links)
    --[=[
    --[=[
    Line 557: Line 558:
    end
    end
    local data = {}
    local data = {}
    -- Heading
    -- Heading
    local heading = args.heading -- Blank values are not removed.
    local heading = args.heading -- Blank values are not removed.
    Line 575: Line 576:
    data.heading = message('other-namespaces-heading')
    data.heading = message('other-namespaces-heading')
    end
    end
    -- Heading CSS
    -- Heading CSS
    local headingStyle = args['heading-style']
    local headingStyle = args['heading-style']
    Line 587: Line 588:
    data.headingFontSize = '150%'
    data.headingFontSize = '150%'
    end
    end
    -- Data for the [view][edit][history][purge] or [create] links.
    -- Data for the [view][edit][history][purge] or [create] links.
    if links then
    if links then
    Line 594: Line 595:
    data.links = links
    data.links = links
    end
    end
    return data
    return data
    end
    end
     
    function p.renderStartBox(data)
    function p.renderStartBox(data)
    -- Renders the start box html.
    -- Renders the start box html.
    Line 621: Line 622:
    return tostring(sbox)
    return tostring(sbox)
    end
    end
     
    ----------------------------------------------------------------------------
    ----------------------------------------------------------------------------
    -- Documentation content
    -- Documentation content
    ----------------------------------------------------------------------------
    ----------------------------------------------------------------------------
     
    p.content = makeInvokeFunc('_content')
    p.content = makeInvokeFunc('_content')
     
    function p._content(args, env)
    function p._content(args, env)
    -- Displays the documentation contents
    -- Displays the documentation contents
    Line 643: Line 644:
    return '\n' .. (content or '') .. '\n'  
    return '\n' .. (content or '') .. '\n'  
    end
    end
     
    ----------------------------------------------------------------------------
    ----------------------------------------------------------------------------
    -- End box
    -- End box
    ----------------------------------------------------------------------------
    ----------------------------------------------------------------------------
     
    p.endBox = makeInvokeFunc('_endBox')
    p.endBox = makeInvokeFunc('_endBox')
     
    function p._endBox(args, env)
    function p._endBox(args, env)
    --[=[
    --[=[
    Line 663: Line 664:
    -- The HTML is generated by the {{fmbox}} template, courtesy of [[Module:Message box]].
    -- The HTML is generated by the {{fmbox}} template, courtesy of [[Module:Message box]].
    --]=]
    --]=]
    -- Get environment data.
    -- Get environment data.
    env = env or p.getEnvironment(args)
    env = env or p.getEnvironment(args)
    Line 671: Line 672:
    return nil
    return nil
    end
    end
    -- Check whether we should output the end box at all. Add the end
    -- Check whether we should output the end box at all. Add the end
    -- box by default if the documentation exists or if we are in the
    -- box by default if the documentation exists or if we are in the
    Line 686: Line 687:
    return nil
    return nil
    end
    end
     
    -- Assemble the arguments for {{fmbox}}.
    -- Assemble the arguments for {{fmbox}}.
    local fmargs = {}
    local fmargs = {}
    Line 693: Line 694:
    fmargs.style = message('fmbox-style') -- Sets 'background-color: #ecfcf4'
    fmargs.style = message('fmbox-style') -- Sets 'background-color: #ecfcf4'
    fmargs.textstyle = message('fmbox-textstyle') -- 'font-style: italic;'
    fmargs.textstyle = message('fmbox-textstyle') -- 'font-style: italic;'
     
    -- Assemble the fmbox text field.
    -- Assemble the fmbox text field.
    local text = ''
    local text = ''
    Line 720: Line 721:
    end
    end
    fmargs.text = text
    fmargs.text = text
     
    return messageBox.main('fmbox', fmargs)
    return messageBox.main('fmbox', fmargs)
    end
    end
     
    function p.makeDocPageBlurb(args, env)
    function p.makeDocPageBlurb(args, env)
    --[=[
    --[=[
    Line 769: Line 770:
    return ret
    return ret
    end
    end
     
    function p.makeExperimentBlurb(args, env)
    function p.makeExperimentBlurb(args, env)
    --[[
    --[[
    Line 866: Line 867:
    return message(messageName, {sandboxLinks, testcasesLinks})
    return message(messageName, {sandboxLinks, testcasesLinks})
    end
    end
     
    function p.makeCategoriesBlurb(args, env)
    function p.makeCategoriesBlurb(args, env)
    --[[
    --[[
    Line 883: Line 884:
    return message('add-categories-blurb', {docPathLink})
    return message('add-categories-blurb', {docPathLink})
    end
    end
     
    function p.makeSubpagesBlurb(args, env)
    function p.makeSubpagesBlurb(args, env)
    --[[
    --[[
    Line 889: Line 890:
    -- @args - a table of arguments passed by the user
    -- @args - a table of arguments passed by the user
    -- @env - environment table containing title objects, etc., generated with p.getEnvironment
    -- @env - environment table containing title objects, etc., generated with p.getEnvironment
    -- Messages:
    -- Messages:
    -- 'template-pagetype' --> 'template'
    -- 'template-pagetype' --> 'template'
    Line 915: Line 916:
    return message('subpages-blurb', {subpagesLink})
    return message('subpages-blurb', {subpagesLink})
    end
    end
     
    function p.makePrintBlurb(args, env)
    function p.makePrintBlurb(args, env)
    --[=[
    --[=[
    Line 945: Line 946:
    return ret
    return ret
    end
    end
     
    ----------------------------------------------------------------------------
    ----------------------------------------------------------------------------
    -- Tracking categories
    -- Tracking categories
    ----------------------------------------------------------------------------
    ----------------------------------------------------------------------------
     
    function p.addTrackingCategories(env)
    function p.addTrackingCategories(env)
    --[[
    --[[
    -- Check if {{documentation}} is transcluded on a /doc or /testcases page.
    -- Check if {{documentation}} is transcluded on a /doc or /testcases page.
    -- @env - environment table containing title objects, etc., generated with p.getEnvironment
    -- @env - environment table containing title objects, etc., generated with p.getEnvironment
    -- Messages:
    -- Messages:
    -- 'display-strange-usage-category' --> true
    -- 'display-strange-usage-category' --> true
    Line 981: Line 982:
    return ret
    return ret
    end
    end
     
    return p
    return p