Module:Documentation: Difference between revisions

    m>Mr. Stradivarius
    (rename formatMessage --> message, as it is no longer just doing formatting; tweak the function's comment as well)
    m>Mr. Stradivarius
    (start conversion to a p.getEnv function rather than using globals; I've only got as far as the start box, so the module currently won't run)
    Line 10: Line 10:


    local p = {}
    local p = {}
    -- Constants.
    local currentTitle = mw.title.getCurrentTitle()
    local subjectSpace = mw.site.namespaces[currentTitle.namespace].subject.id -- The number of the current subject namespace.


    -- Often-used functions.
    -- Often-used functions.
    Line 104: Line 100:


    ----------------------------------------------------------------------------
    ----------------------------------------------------------------------------
    -- Main functions
    -- Main function
    ----------------------------------------------------------------------------
    ----------------------------------------------------------------------------


    Line 110: Line 106:


    function p._main(args)
    function p._main(args)
    -- Get environment data, using pcall in case we get any errors.
    local success, env = pcall(p.getEnv, args)
    if not success then
    return string.format('<strong class="error">[[Module:Documentation]] error: %s</strong>', env) -- If there's an error, env is the error message.
    end
    -- Build the documentation.
    local root = htmlBuilder.create()
    local root = htmlBuilder.create()
    root
    root
    .wikitext(p.protectionTemplate())
    .wikitext(p.protectionTemplate(env))
    .wikitext(p.sandboxNotice(args))
    .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.
    Line 120: Line 122:
    .addClass(message('mainDivClasses', 'string'))
    .addClass(message('mainDivClasses', 'string'))
    .newline()
    .newline()
    .wikitext(p._startBox(args))
    .wikitext(p._startBox(args, env))
    .wikitext(p._content(args))
    .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.
    Line 127: Line 129:
    .done()
    .done()
    .done()
    .done()
    .wikitext(p._endBox(args))
    .wikitext(p._endBox(args, env))
    .newline()
    .newline()
    .wikitext(p.addTrackingCategories())
    .wikitext(p.addTrackingCategories(env))
    return tostring(root)
    return tostring(root)
    end
    end


    function p.sandboxNotice(args)
    ----------------------------------------------------------------------------
    -- Environment settings
    ----------------------------------------------------------------------------
     
    function p.getEnv(args)
    -- Returns a table with information about the environment, including the title to use, the subject namespace, etc.
    -- This is called from p._main using pcall in case we get any errors from exceeding the expensive function count
    -- limit, or other perils unknown.
    --
    -- Data includes:
    -- env.title - the title object of the page we are making documentation for (usually the current title)
    -- env.subjectSpace - the number of the title's subject namespace.
    -- env.docspace - the name of the namespace the title puts its documentation in.
    -- env.templatePage - the name of the template page with no namespace or interwiki prefixes.
    local env = {}
     
    -- Get the title.
    local title
    local titleArg = args[message('titleArg', 'string')]
    if titleArg then
    title = mw.title.new(titleArg)
    if not title then
    error(message('titleArgError', 'string', {titleArg}))
    end
    else
    title = mw.title.getCurrentTitle()
    end
    env.title = title
     
    -- Get the subject namespace number.
    local subjectSpace = mw.site.namespaces[title.namespace].subject.id
    env.subjectSpace = subjectSpace
    -- Get the name of the documentation namespace.
    local docspace
    if subjectSpace == 0 or subjectSpace == 6 or subjectSpace == 8 or subjectSpace == 14 then
    -- Pages in the Article, File, MediaWiki or Category namespaces must have their
    -- /doc, /sandbox and /testcases pages in talk space.
    docspace = mw.site.namespaces[subjectSpace].talk.name
    else
    docspace = title.subjectNsText
    end
    env.docspace = docspace
    -- Get the template page with no namespace or interwiki prefixes.
    local templatePage
    local subpage = title.subpageText
    if subpage == message('sandboxSubpage', 'string') or subpage == message('testcasesSubpage', 'string') then
    templatePage = title.baseText
    else
    templatePage = title.text
    end
    env.templatePage = templatePage
     
    return env
    end
     
    ----------------------------------------------------------------------------
    -- Auxiliary templates
    ----------------------------------------------------------------------------
     
    function p.sandboxNotice(args, env)
    local sandboxNoticeTemplate = message('sandboxNoticeTemplate', 'string')
    local sandboxNoticeTemplate = message('sandboxNoticeTemplate', 'string')
    if not (sandboxNoticeTemplate and currentTitle.subpageText == message('sandboxSubpage', 'string')) then
    if not (sandboxNoticeTemplate and env.title.subpageText == message('sandboxSubpage', 'string')) then
    return nil
    return nil
    end
    end
    Line 148: Line 211:
    end
    end


    function p.protectionTemplate()
    function p.protectionTemplate(env)
    local title = env.title
    local protectionTemplate = message('protectionTemplate', 'string')
    local protectionTemplate = message('protectionTemplate', 'string')
    if not (protectionTemplate and currentTitle.namespace == 10) then
    if not (protectionTemplate and title.namespace == 10) then
    -- Don't display the protection template if we are not in the template namespace.
    -- Don't display the protection template if we are not in the template namespace.
    return nil
    return nil
    end
    end
    local frame = mw.getCurrentFrame()
    local frame = mw.getCurrentFrame()
    local function getProtectionLevel(protectionType)
    local function getProtectionLevel(protectionType, page)
    -- Gets the protection level for the current page.
    -- Gets the protection level for page, or for the current page if page is not specified.
    local level = frame:callParserFunction('PROTECTIONLEVEL', protectionType)
    local level = frame:callParserFunction('PROTECTIONLEVEL', protectionType, page)
    if level ~= '' then
    if level ~= '' then
    return level
    return level
    Line 164: Line 228:
    end
    end
    end
    end
    if getProtectionLevel('move') == 'sysop' or getProtectionLevel('edit') then
    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.
    return frame:expandTemplate{title = protectionTemplate, args = message('protectionTemplateArgs', 'table')}
    return frame:expandTemplate{title = protectionTemplate, args = message('protectionTemplateArgs', 'table')}
    Line 170: Line 235:
    return nil
    return nil
    end
    end
    ----------------------------------------------------------------------------
    -- Start box
    ----------------------------------------------------------------------------


    p.startBox = makeInvokeFunc('_startBox')
    p.startBox = makeInvokeFunc('_startBox')


    function p._startBox(args)
    function p._startBox(args, env)
    -- Arg processing from {{documentation}}.
    -- Arg processing from {{documentation}}.
    local preload = args[message('preloadArg', 'string')] -- Allow custom preloads.
    local preload = args[message('preloadArg', 'string')] -- Allow custom preloads.
    Line 179: Line 248:
    local headingStyle = args[message('headingStyleArg', 'string')]
    local headingStyle = args[message('headingStyleArg', 'string')]
    local content = args[message('contentArg', 'string')]
    local content = args[message('contentArg', 'string')]
    local docspace = p.docspace()
    local docspace = env.docspace
    local docname = args[1] -- Other docname, if fed.
    local docname = args[1] -- Other docname, if fed.
    local templatePage = p.templatePage()
    local templatePage = env.templatePage


    -- Arg processing from {{documentation/start box2}}.
    -- Arg processing from {{documentation/start box2}}.
    Line 267: Line 336:
    return tostring(sbox)
    return tostring(sbox)
    end
    end
    ----------------------------------------------------------------------------
    -- Documentation content
    ----------------------------------------------------------------------------


    p.content = makeInvokeFunc('_content')
    p.content = makeInvokeFunc('_content')
    Line 289: Line 362:
    return '\n' .. (content or '') .. '\n'  
    return '\n' .. (content or '') .. '\n'  
    end
    end
    ----------------------------------------------------------------------------
    -- End box
    ----------------------------------------------------------------------------


    p.endBox = makeInvokeFunc('_endBox')
    p.endBox = makeInvokeFunc('_endBox')
    Line 408: Line 485:
    return messageBox.main('fmbox', fmargs)
    return messageBox.main('fmbox', fmargs)
    end
    end
    ----------------------------------------------------------------------------
    -- Tracking categories
    ----------------------------------------------------------------------------


    function p.addTrackingCategories()
    function p.addTrackingCategories()
    Line 418: Line 499:
    end
    end
    return ret
    return ret
    end
    function p.docspace()
    -- Determines the namespace of the documentation.
    if subjectSpace == 0 or subjectSpace == 6 or subjectSpace == 8 or subjectSpace == 14 then
    -- Pages in the Article, File, MediaWiki or Category namespaces must have their
    -- /doc, /sandbox and /testcases pages in talk space.
    return mw.site.namespaces[subjectSpace].talk.name
    else
    return currentTitle.subjectNsText
    end
    end
    function p.templatePage()
    -- Determines the template page. No namespace or interwiki prefixes are included.
    local subpage = currentTitle.subpageText
    if subpage == message('sandboxSubpage', 'string') or subpage == message('testcasesSubpage', 'string') then
    return currentTitle.baseText
    else
    return currentTitle.text
    end
    end
    end


    return p
    return p