Module:Documentation: Difference between revisions

    No edit summary
    m>WOSlinker
    (use mw.html)
    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 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 19:
    -- table for testing purposes.
    -- table for testing purposes.
    ----------------------------------------------------------------------------
    ----------------------------------------------------------------------------
     
    local function message(cfgKey, valArray, expectType)
    local function message(cfgKey, valArray, expectType)
    --[[
    --[[
    Line 39: Line 38:
    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 57:
    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 84:
    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 110:
    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 128: Line 127:
    --]]
    --]]
    local env = p.getEnvironment(args)
    local env = p.getEnvironment(args)
    local root = htmlBuilder.create()
    local root = mw.html.create()
    root
    root
    .wikitext(p.protectionTemplate(env))
    :wikitext(p.protectionTemplate(env))
    .wikitext(p.sandboxNotice(args, env))
    :wikitext(p.sandboxNotice(args, env))
    -- This div tag is from {{documentation/start box}}, but moving it here
    -- This div tag is from {{documentation/start box}}, but moving it here
    -- so that we don't have to worry about unclosed tags.
    -- so that we don't have to worry about unclosed tags.
    .tag('div')
    :tag('div')
    .attr('id', message('main-div-id'))
    :attr('id', message('main-div-id'))
    .addClass(message('main-div-classes'))
    :addClass(message('main-div-classes'))
    .newline()
    :newline()
    .wikitext(p._startBox(args, env))
    :wikitext(p._startBox(args, env))
    .wikitext(p._content(args, env))
    :wikitext(p._content(args, env))
    .tag('div')
    :tag('div')
    .css('clear', 'both') -- So right or left floating items don't stick out of the doc box.
    :css('clear', 'both') -- So right or left floating items don't stick out of the doc box.
    .newline()
    :newline()
    .done()
    :done()
    .done()
    :done()
    .wikitext(p._endBox(args, env))
    :wikitext(p._endBox(args, env))
    .wikitext(p.addTrackingCategories(env))
    :wikitext(p.addTrackingCategories(env))
    return tostring(root)
    return tostring(root)
    end
    end
     
    ----------------------------------------------------------------------------
    ----------------------------------------------------------------------------
    -- Environment settings
    -- Environment settings
    ----------------------------------------------------------------------------
    ----------------------------------------------------------------------------
     
    function p.getEnvironment(args)
    function p.getEnvironment(args)
    --[[
    --[[
    Line 178: Line 177:
    -- 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 196:
    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 208:
    return title
    return title
    end
    end
     
    function envFuncs.templateTitle()
    function envFuncs.templateTitle()
    --[[
    --[[
    Line 226: Line 225:
    end
    end
    end
    end
     
    function envFuncs.docTitle()
    function envFuncs.docTitle()
    --[[
    --[[
    Line 243: Line 242:
    return mw.title.new(docpage)
    return mw.title.new(docpage)
    end
    end
    function envFuncs.sandboxTitle()
    function envFuncs.sandboxTitle()
    --[[
    --[[
    Line 252: Line 251:
    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 260:
    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 269:
    return env.templateTitle:subPageTitle(message('print-subpage'))
    return env.templateTitle:subPageTitle(message('print-subpage'))
    end
    end
     
    function envFuncs.protectionLevels()
    function envFuncs.protectionLevels()
    -- The protection levels table of the title object.
    -- The protection levels table of the title object.
    return env.title.protectionLevels
    return env.title.protectionLevels
    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 292: Line 291:
    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 302: Line 301:
    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 317: Line 316:
    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 398: Line 397:
    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 432: Line 431:
    end
    end
    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 468: Line 467:
    end
    end
    end
    end
     
    function p.makeStartBoxLinksData(args, env)
    function p.makeStartBoxLinksData(args, env)
    --[[
    --[[
    Line 491: Line 490:
    return nil
    return nil
    end
    end
     
    local data = {}
    local data = {}
    data.title = title
    data.title = title
    Line 515: Line 514:
    return data
    return data
    end
    end
     
    function p.renderStartBoxLinks(data)
    function p.renderStartBoxLinks(data)
    --[[
    --[[
    Line 521: Line 520:
    -- @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 528: Line 527:
    return s
    return s
    end
    end
     
    local ret
    local ret
    local docTitle = data.docTitle
    local docTitle = data.docTitle
    Line 548: Line 547:
    return ret
    return ret
    end
    end
     
    function p.makeStartBoxData(args, env, links)
    function p.makeStartBoxData(args, env, links)
    --[=[
    --[=[
    Line 573: Line 572:
    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 591: Line 590:
    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 603: Line 602:
    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 610: Line 609:
    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.
    -- @data - a table of data generated by p.makeStartBoxData.
    -- @data - a table of data generated by p.makeStartBoxData.
    local sbox = htmlBuilder.create('div')
    local sbox = mw.html.create('div')
    sbox
    sbox
    .css('padding-bottom', '3px')
    :css('padding-bottom', '3px')
    .css('border-bottom', '1px solid #aaa')
    :css('border-bottom', '1px solid #aaa')
    .css('margin-bottom', '1ex')
    :css('margin-bottom', '1ex')
    .newline()
    :newline()
    .tag('span')
    :tag('span')
    .cssText(data.headingStyleText)
    :cssText(data.headingStyleText)
    .css('font-weight', data.headingFontWeight)
    :css('font-weight', data.headingFontWeight)
    .css('font-size', data.headingFontSize)
    :css('font-size', data.headingFontSize)
    .wikitext(data.heading)
    :wikitext(data.heading)
    local links = data.links
    local links = data.links
    if links then
    if links then
    sbox.tag('span')
    sbox:tag('span')
    .addClass(data.linksClass)
    :addClass(data.linksClass)
    .attr('id', data.linksId)
    :attr('id', data.linksId)
    .wikitext(links)
    :wikitext(links)
    end
    end
    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 658: Line 657:
    return '\n' .. (content or '') .. '\n'  
    return '\n' .. (content or '') .. '\n'  
    end
    end
     
    p.contentTitle = makeInvokeFunc('_contentTitle')
    p.contentTitle = makeInvokeFunc('_contentTitle')
     
    function p._contentTitle(args, env)
    function p._contentTitle(args, env)
    env = env or p.getEnvironment(args)
    env = env or p.getEnvironment(args)
    Line 670: Line 669:
    end
    end
    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 690: Line 689:
    -- 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 698: Line 697:
    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 713: Line 712:
    return nil
    return nil
    end
    end
     
    -- Assemble the arguments for {{fmbox}}.
    -- Assemble the arguments for {{fmbox}}.
    local fmargs = {}
    local fmargs = {}
    Line 720: Line 719:
    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 747: Line 746:
    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 796: Line 795:
    return ret
    return ret
    end
    end
     
    function p.makeExperimentBlurb(args, env)
    function p.makeExperimentBlurb(args, env)
    --[[
    --[[
    Line 893: Line 892:
    return message(messageName, {sandboxLinks, testcasesLinks})
    return message(messageName, {sandboxLinks, testcasesLinks})
    end
    end
     
    function p.makeCategoriesBlurb(args, env)
    function p.makeCategoriesBlurb(args, env)
    --[[
    --[[
    Line 910: Line 909:
    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 916: Line 915:
    -- @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 942: Line 941:
    return message('subpages-blurb', {subpagesLink})
    return message('subpages-blurb', {subpagesLink})
    end
    end
     
    function p.makePrintBlurb(args, env)
    function p.makePrintBlurb(args, env)
    --[=[
    --[=[
    Line 972: Line 971:
    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 1,008: Line 1,007:
    return ret
    return ret
    end
    end
     
    return p
    return p