Module:Documentation: Difference between revisions

    m>Mr. Stradivarius
    (p.content: use frame:expandTemplate instead of frame:preprocess to improve performance)
    No edit summary
    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 178: Line 178:
    -- 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 197:
    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 209:
    return title
    return title
    end
    end
     
    function envFuncs.templateTitle()
    function envFuncs.templateTitle()
    --[[
    --[[
    Line 226: Line 226:
    end
    end
    end
    end
     
    function envFuncs.docTitle()
    function envFuncs.docTitle()
    --[[
    --[[
    Line 243: Line 243:
    return mw.title.new(docpage)
    return mw.title.new(docpage)
    end
    end
    function envFuncs.sandboxTitle()
    function envFuncs.sandboxTitle()
    --[[
    --[[
    Line 252: Line 252:
    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 261:
    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 270:
    return env.templateTitle:subPageTitle(message('print-subpage'))
    return env.templateTitle:subPageTitle(message('print-subpage'))
    end
    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 287:
    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 297:
    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 312:
    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 383: Line 383:
    return messageBox.main('ombox', omargs)
    return messageBox.main('ombox', omargs)
    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 414: Line 414:
    return nil
    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 450: Line 450:
    end
    end
    end
    end
     
    function p.makeStartBoxLinksData(args, env)
    function p.makeStartBoxLinksData(args, env)
    --[[
    --[[
    Line 473: Line 473:
    return nil
    return nil
    end
    end
     
    local data = {}
    local data = {}
    data.title = title
    data.title = title
    Line 497: Line 497:
    return data
    return data
    end
    end
     
    function p.renderStartBoxLinks(data)
    function p.renderStartBoxLinks(data)
    --[[
    --[[
    Line 503: Line 503:
    -- @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 510: Line 510:
    return s
    return s
    end
    end
     
    local ret
    local ret
    local docTitle = data.docTitle
    local docTitle = data.docTitle
    Line 530: Line 530:
    return ret
    return ret
    end
    end
     
    function p.makeStartBoxData(args, env, links)
    function p.makeStartBoxData(args, env, links)
    --[=[
    --[=[
    Line 555: Line 555:
    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 573: Line 573:
    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 585: Line 585:
    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 592: Line 592:
    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 619: Line 619:
    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 641: Line 641:
    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 661: Line 661:
    -- 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 669: Line 669:
    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 684: Line 684:
    return nil
    return nil
    end
    end
     
    -- Assemble the arguments for {{fmbox}}.
    -- Assemble the arguments for {{fmbox}}.
    local fmargs = {}
    local fmargs = {}
    Line 691: Line 691:
    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 718: Line 718:
    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 767: Line 767:
    return ret
    return ret
    end
    end
     
    function p.makeExperimentBlurb(args, env)
    function p.makeExperimentBlurb(args, env)
    --[[
    --[[
    Line 864: Line 864:
    return message(messageName, {sandboxLinks, testcasesLinks})
    return message(messageName, {sandboxLinks, testcasesLinks})
    end
    end
     
    function p.makeCategoriesBlurb(args, env)
    function p.makeCategoriesBlurb(args, env)
    --[[
    --[[
    Line 881: Line 881:
    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 887: Line 887:
    -- @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 913: Line 913:
    return message('subpages-blurb', {subpagesLink})
    return message('subpages-blurb', {subpagesLink})
    end
    end
     
    function p.makePrintBlurb(args, env)
    function p.makePrintBlurb(args, env)
    --[=[
    --[=[
    Line 943: Line 943:
    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 979: Line 979:
    return ret
    return ret
    end
    end
     
    return p
    return p