Toggle menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Editing Module:Documentation

From Mine in Abyss
Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.

The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.

Latest revision Your text
Line 1: Line 1:
local p = {}
local p = {}
local defaultDocPage = 'doc'


-- Load modules (language wikis exclusive)
local getType = function( namespace, page )
-- ...
local pageType = 'template'
 
if namespace == 'Module' then
-- Customizable strings
local i18n = {
-- default settings, change when necessary
defaultDocPage = 'doc', -- documentation page suffix
defaultSandboxPage = 'sandbox', -- sandbox page suffix
defaultTestCasePage = 'testcases', -- testcases page suffix
defaultPreload = 'Template:Documentation/preload', -- page that stores qualified documentation page contents
defaultStyles = 'Module:Documentation/styles.css', -- stylesheet for this module when using TemplateStyles, remove or set to nil if your wiki not use this
 
-- format strings, should not be translated
commonInternalLink = '[[%s]]',
commonInternalLinkPipe = '[[%s|%s]]',
commonExternalLink = '[%s]',
commonExternalLinkWithName = '[%s %s]',
commonNamespacedPage = '%s:%s',
commonNamespacedPageWithSub = '%s:%s/%s',
 
-- namespace names, translate if your language prefers localized namespace name, although remain it untouched most likely not affect anything
namespaceCategory = 'Category',
namespaceSpecial = 'Special',
namespaceUser = 'User',
 
-- names of special pages, translate if your language prefers localized namespace name, although remain it untouched will still correctly linked to target page
specialPurge = 'Purge',
specialEdit = 'EditPage',
specialHistory = 'PageHistory',
 
-- translate following types if your language displays differ
pageType_template = 'template',
pageType_module = 'module',
pageType_widget = 'widget',
pageType_stylesheet = 'stylesheet',
pageType_script = 'script',
pageType_message = 'message',
 
-- modify them if your wiki use different style to displaying links
linkBar = '%s', -- format used for whole link bar
linkFormat = mw.text.nowiki( '[' ) .. '%s' .. mw.text.nowiki( ']' ), -- format used for each individual links
linkSeparator = ' ', -- separator between links
 
-- name of different type of links, change them if necessary
linkTextPurge = mw.message.new( 'purge' ):plain():lower(),
linkTextView = mw.message.new( 'view' ):plain():lower(),
linkTextEdit = mw.message.new( 'edit' ):plain():lower(),
linkTextHistory = mw.message.new( 'history_short' ):plain():lower(),
linkTextCreate = mw.message.new( 'create' ):plain():lower(),
 
-- strings used in p.create(): contents shown when using {{docc}} or {{subst:docc}}
createOutputFormat = '%s%s', -- overall format
createSplitDocPagePrompt = '\n<!-- Put categories/interwikis on the documentation page -->', -- this string is shown when a separate documentation page is created
createNoSubstCategory = 'Pages with templates requiring substitution', -- tracking category for using {{docc}} without substitution
 
-- strings used in p.docPage(): contents shown in documentation page
docPagePrompt = 'This is the documentation page. It %s transcluded into %s. See [[Template:Documentation]] for more information.', -- message shown as documentation header in documentation pages. Params: word used when page is a module or not; code page's type
docPagePromptWill = 'is', -- word used when code page is a module page
docPagePromptShould = 'should be', -- word used when code is not a module page
docPageBadDocPrompt = "<br>'''This %s's documentation needs improving or additional information.'''", -- additional message if a documentation page marked as baddoc
docPageCategory = 'Documentation pages', -- tracking category for documentation pages
 
-- strings used in p.page(): contents shown in code page
pageNoDocPrompt = "'''This %s has no documentation. If you know how to use this %s, please create it.'''", -- message shown when a separate documentation page is not exist, both parameters refers to page type
pageNoDocCategory = '%ss with no documentation', -- tracking category for pages without documentation, parameters refers to page type
pageNoDocCategoryDefault = 'Pages with no documentation', -- fallback tracking category for pages without documentation
pageBadDocPrompt = "'''This %s's documentation needs improving or additional information.'''\n", -- message shown when a documentation page marked as baddoc, both parameters refers to page type
pageBadDocCategory = '%ss with bad documentation', -- tracking category for pages marked as baddoc, parameters refers to page type
pageBadDocCategoryDefault = 'Pages with bad documentation', -- fallback tracking category for pages marked as baddoc
pageDocHeaderTitle = 'Documentation', -- message shown as the title of the documentation header
pageDocJumpToCode = 'Jump to code ↴', -- text of the link to jump to the code
pageDocHeaderBottom = 'The above documentation is transcluded from %s.', -- message shown as the bottom line of the documentation header
}
 
-- Customizable functions
local function pageCategoryHandler( category )
return mw.getCurrentFrame():expandTemplate{ title = 'translation category', args = { category, project = '0' } }
end
 
-- Load modules
local loadStyles = require( 'Module:TSLoader' ).call
 
local static = require( 'Module:Static' )
if not static.Documentation then
static.Documentation = {}
end
 
-- Internal functions
local function getType( namespace, page )
local pageType = 'page'
if namespace == 'Template' then
pageType = 'template'
elseif namespace == 'Module' then
pageType = 'module'
pageType = 'module'
elseif namespace == 'Widget' then
elseif namespace == 'Widget' then
pageType = 'widget'
pageType = 'widget'
elseif page.fullText:gsub( '/' .. i18n.defaultDocPage .. '$', '' ):find( '%.css$' ) then
elseif page.fullText:gsub( '/' .. defaultDocPage .. '$', '' ):find( '%.css$' ) then
pageType = 'stylesheet'
pageType = 'stylesheet'
elseif page.fullText:gsub( '/' .. i18n.defaultDocPage .. '$', '' ):find( '%.js$' ) then
elseif page.fullText:gsub( '/' .. defaultDocPage .. '$', '' ):find( '%.js$' ) then
pageType = 'script'
pageType = 'script'
elseif namespace == 'MediaWiki' then
elseif namespace == 'MediaWiki' then
pageType = 'message'
pageType = 'message'
end
end
return pageType
return pageType
end
end


local function getDisplayType( pageType )
-- Creating a documentation page or transclusion through {{subst:docc}}
return i18n[ 'pageType_' .. pageType ] or i18n.pageType_template
function p.create( f )
end
 
-- Exported functions
function p.create( f ) -- Creating a documentation page or transclusion through {{subst:docc}}
local args = require( 'Module:ProcessArgs' ).norm()
local args = require( 'Module:ProcessArgs' ).norm()
local page = mw.title.getCurrentTitle()
local page = mw.title.getCurrentTitle()
local docPage = args.page or i18n.commonNamespacedPageWithSub:format( page.nsText, page.baseText, i18n.defaultDocPage )
local docPage = args.page or page.nsText .. ':' .. page.baseText .. '/' .. defaultDocPage
 
local out
local out
if not args.content and tostring( page ) == docPage then
if not args.content and tostring( page ) == docPage then
local pageType = mw.ustring.lower( args.type or getType( page.nsText, page ) )
out = f:preprocess( '{{subst:Template:Documentation/preload}}' )
local pageTypeDisplay = getDisplayType( pageType )
out = f:preprocess( mw.title.new( i18n.defaultPreload ):getContent():gsub( '$1' , pageTypeDisplay ) )
else
else
local templateArgs = {}
local templateArgs = {}
for _, key in ipairs{ 'type', 'page', 'content', 'nodoc', 'baddoc' } do
for _, key in ipairs{ 'type', 'page', 'content' } do
local val = args[ key ]
local val = args[key]
if val then
if val then
if key == 'content' then val = '\n' .. val .. '\n' end
if key == 'content' then val = '\n' .. val .. '\n' end
Line 131: Line 37:
end
end
end
end
out = '{{documentation|' .. table.concat( templateArgs, '|' ) .. '}}'
out = '{{documentation|' .. table.concat( templateArgs, '|' ) .. '}}'
out = out:gsub( '|}}', '}}' )
out = out:gsub( '|}}', '}}' )
out = i18n.createOutputFormat:format( out, args.content and '' or i18n.createSplitDocPagePrompt )
if not args.content then
out = out .. '\n<!-- Put categories/interwikis on the documentation page -->'
end
end
end
 
if not mw.isSubsting() then
if not mw.isSubsting() then
out = f:preprocess( out )
out = f:preprocess( out )
if not args.nocat then
if not args.nocat then
out = out .. i18n.commonInternalLink:format( i18n.commonNamespacedPage:format( i18n.namespaceCategory, i18n.createNoSubstCategory ) )
out = out .. '[[Category:Pages with templates requiring substitution]]'
end
end
end
end
 
return out
return out
end
end


function p.docPage( f ) -- Header on the documentation page
-- Header on the documentation page
function p.docPage( f )
local args = require( 'Module:ProcessArgs' ).merge( true )
local args = require( 'Module:ProcessArgs' ).merge( true )
local badDoc = args.baddoc
local badDoc = args.baddoc
 
if f:callParserFunction( '#dplvar', '$doc noheader' ) == '1' then
if badDoc then
if badDoc then
static.Documentation.badDoc = '1'
f:callParserFunction( '#dplvar:set', '$doc bad', '1' )
end
return
end
end
 
local page = mw.title.getCurrentTitle()
local page = mw.title.getCurrentTitle()
local subpage = page.subpageText
local subpage = page.subpageText
if subpage == i18n.defaultSandboxPage or subpage == i18n.defaultTestCasePage then
if subpage == 'sandbox' or subpage == 'testcases' then
page = page.basePageTitle
page = page.basePageTitle
end
end
local docPage = mw.title.new( args.page or i18n.commonNamespacedPageWithSub:format( page.nsText, page.baseText, i18n.defaultDocPage ) )
if docPage ~= page then return end
local namespace = page.nsText
local namespace = page.nsText
local pageType = mw.ustring.lower( args.type or getType( namespace, page ) )
local pageType = mw.ustring.lower( args.type or getType( namespace, page ) )
local pageTypeDisplay = getDisplayType( pageType )
 
local body = mw.html.create( 'div' ):addClass( 'documentation-header' )
local body = mw.html.create( 'div' ):addClass( 'documentation' )
body
body
:addClass( badDoc and 'documentation-badDoc' or '' )
:addClass( badDoc and 'documentation-badDoc' or '' )
:css{
['margin-bottom'] = '0.8em',
padding = '0.8em 1em 0.7em',
['background-color'] = '#' .. ( badDoc and '888888' or '33333333' ),
border = '1px solid #AAA'
}
:tag( 'div' )
:tag( 'div' )
:attr( 'id', 'documentation-header-tools' )
:attr( 'id', 'documentation-header-tools' )
:wikitext( i18n.linkBar:format( i18n.linkFormat:format( i18n.commonInternalLinkPipe:format( i18n.commonNamespacedPageWithSub:format( i18n.namespaceSpecial, i18n.specialPurge, page.fullText ), i18n.linkTextPurge ) ) ) )
:css( 'float', 'right' )
:wikitext( '[[', page:fullUrl( 'action=purge' ), ' ' .. f:preprocess('{{lc:{{int:page-header-action-button-purge}}}}') .. ']]' )
:done()
:done()
:wikitext( i18n.docPagePrompt:format( pageType == 'module' and i18n.docPagePromptWill or i18n.docPagePromptShould, i18n.commonInternalLink:format( i18n.commonNamespacedPage:format( namespace, page.baseText ) ) ) )
:wikitext(
'This is the documentation page. It ',
pageType == 'module' and 'will' or 'should',
' be transcluded into the main ', pageType, ' page. ',
'See [[Template:Documentation]] for more information'
)
if badDoc then
if badDoc then
body:wikitext( i18n.docPageBadDocPrompt:format( pageTypeDisplay ) )
body:wikitext( "<br>'''This ", pageType, "'s documentation needs improving or additional information.'''" )
end
end
if not ( args.nocat or namespace == i18n.namespaceUser ) then
if not ( args.nocat or namespace == 'User' ) then
body:wikitext( i18n.commonInternalLink:format( i18n.commonNamespacedPage:format( i18n.namespaceCategory, i18n.docPageCategory ) ) )
body:wikitext( '[[Category:Documentation pages]]' )
end
end
 
return loadStyles( i18n.defaultStyles ) .. tostring( body )
return body
end
end


function p.page( f ) -- Wrapper around the documentation on the main page
-- Wrapper around the documentation on the main page
function p.page( f )
-- mw.text.trim uses mw.ustring.gsub, which silently fails on large strings
-- mw.text.trim uses mw.ustring.gsub, which silently fails on large strings
local function trim( s )
local function trim( s )
return ( s:gsub( '^[\t\r\n\f ]+', '' ):gsub( '[\t\r\n\f ]+$', '' ) )
return (s:gsub( '^[\t\r\n\f ]+', '' ):gsub( '[\t\r\n\f ]+$', '' ))
--return string.gsub( s, '^[\t\r\n\f ]*(.-)[\t\r\n\f ]*$', '%1' )
--return string.gsub( s, '^[\t\r\n\f ]*(.-)[\t\r\n\f ]*$', '%1' )
end
end
Line 195: Line 115:
local page = mw.title.getCurrentTitle()
local page = mw.title.getCurrentTitle()
local subpage = page.subpageText
local subpage = page.subpageText
if subpage == i18n.defaultSandboxPage or subpage == i18n.defaultTestCasePage then
if subpage == 'sandbox' or subpage == 'testcases' then
page = page.basePageTitle
page = page.basePageTitle
end
end
Line 201: Line 121:
local docText = trim( args.content or '' )
local docText = trim( args.content or '' )
if docText == '' then docText = nil end
if docText == '' then docText = nil end
 
local docPage
local docPage
local noDoc
local noDoc
Line 207: Line 127:
docPage = page
docPage = page
else
else
docPage = mw.title.new( args.page or i18n.commonNamespacedPageWithSub:format( namespace, page.text, i18n.defaultDocPage ) )
docPage = mw.title.new( args.page or namespace .. ':' .. page.text .. '/' .. defaultDocPage )
noDoc = args.nodoc or not docPage.exists
noDoc = args.nodoc or not docPage.exists
end
end
local badDoc = args.baddoc
local badDoc = args.baddoc
local pageType = mw.ustring.lower( args.type or getType( namespace, page ) )
local pageType = mw.ustring.lower( args.type or getType( namespace, page ) )
local pageTypeDisplay = getDisplayType( pageType )
 
if not docText and not noDoc then
if not docText and not noDoc then
docText = trim( f:expandTemplate{ title = ':' .. docPage.fullText } )
f:callParserFunction( '#dplvar:set', '$doc noheader', '1' )
if static.Documentation.badDoc and static.Documentation.badDoc == '1' then
docText = trim( f:expandTemplate{ title = ':' .. docPage.fullText } )
if f:callParserFunction( '#dplvar', '$doc bad' ) == '1' then
badDoc = 1
badDoc = 1
end
end
 
if docText == '' then
if docText == '' then
docText = nil
docText = nil
Line 228: Line 148:
docText = '\n' .. docText .. '\n'
docText = '\n' .. docText .. '\n'
end
end
 
local action = f:preprocess('{{lc:{{int:edit}}}}')
local preload = ''
local docClass = ''
local docClass = ''
local colour = '00000000'
local message
local message
local category
local category
if noDoc then
if noDoc then
action = f:preprocess('{{lc:{{int:create}}}}')
preload = '&preload=Template:Documentation/preload'
docClass = 'documentation-noDoc'
docClass = 'documentation-noDoc'
message = i18n.pageNoDocPrompt:format( pageTypeDisplay, pageTypeDisplay )
colour = '33333333'
if not ( args.nocat or namespace == i18n.namespaceUser ) then
message = "'''This " .. pageType .. " has no documentation. " ..
category = i18n.pageNoDocCategory:format( pageTypeDisplay )
"If you know how to use this " .. pageType .. ", please create it.'''"
if not mw.title.new( i18n.commonNamespacedPage:format( i18n.namespaceCategory, category ) ).exists then
if not ( args.nocat or namespace == 'User' ) then
category = i18n.pageNoDocCategoryDefault
category = pageType .. 's with no documentation'
if not mw.title.new( 'Category:' .. category ).exists then
category = 'Pages with no documentation'
end
end
end
end
elseif badDoc then
elseif badDoc then
docClass = 'documentation-badDoc'
docClass = 'documentation-badDoc'
message = i18n.pageBadDocPrompt:format( pageTypeDisplay )
colour = 'F9F2EA'
if not ( args.nocat or namespace == i18n.namespaceUser ) then
message = "'''This " .. pageType .. "'s documentation needs improving or additional information.'''\n"
category = i18n.pageBadDocCategory:format( pageTypeDisplay )
if not ( args.nocat or namespace == 'User' ) then
if not mw.title.new( i18n.commonNamespacedPage:format( i18n.namespaceCategory, category ) ).exists then
category = pageType .. 's with bad documentation'
category = i18n.pageBadDocCategoryDefault
if not mw.title.new( 'Category:' .. category ).exists then
category = 'Pages with bad documentation'
end
end
end
end
end
end
 
-- Generates the link bar
local links = {
local links = mw.html.create( 'span' )
'[' .. docPage:fullUrl( 'action=edit' .. preload ) .. ' ' .. action .. ']',
'[' .. docPage:fullUrl( 'action=history' ) .. ' ' .. f:preprocess('{{lc:{{int:history short}}}}') .. ']',
'[' .. page:fullUrl( 'action=purge' ) .. ' ' .. f:preprocess('{{lc:{{int:page-header-action-button-purge}}}}') .. ']'
}
if not noDoc and page ~= docPage then
table.insert( links, 1, '[[' .. docPage.fullText .. '|' .. f:preprocess('{{lc:{{int:view}}}}') .. ']]' )
end
links = mw.html.create( 'span' )
:attr( 'id', 'documentation-header-tools' )
:attr( 'id', 'documentation-header-tools' )
 
:css( 'float', 'right' )
local linkList = {}
:wikitext( mw.text.nowiki( '[' ), table.concat( links, ' | ' ), mw.text.nowiki( ']' ) )
if not noDoc then
if page ~= docPage then
table.insert( linkList, i18n.linkFormat:format( i18n.commonInternalLinkPipe:format( docPage.fullText, i18n.linkTextView ) ) )
end
table.insert( linkList, i18n.linkFormat:format( i18n.commonInternalLinkPipe:format( i18n.commonNamespacedPageWithSub:format( i18n.namespaceSpecial, i18n.specialEdit, docPage.fullText ), i18n.linkTextEdit ) ) )
table.insert( linkList, i18n.linkFormat:format( i18n.commonInternalLinkPipe:format( i18n.commonNamespacedPageWithSub:format( i18n.namespaceSpecial, i18n.specialHistory, docPage.fullText ), i18n.linkTextHistory ) ) )
else
table.insert( linkList, i18n.linkFormat:format( i18n.commonExternalLinkWithName:format( docPage:canonicalUrl{ action = 'edit', preload = i18n.defaultPreload, preloadparams = pageTypeDisplay }, i18n.linkTextCreate ) ) )
end
table.insert( linkList, i18n.linkFormat:format( i18n.commonInternalLinkPipe:format( i18n.commonNamespacedPageWithSub:format( i18n.namespaceSpecial, i18n.specialPurge, docPage.fullText ), i18n.linkTextPurge ) ) )
links:wikitext( i18n.linkBar:format( table.concat( linkList, i18n.linkSeparator ) ) )
 
local body = mw.html.create( 'div' ):addClass( 'documentation' )
local body = mw.html.create( 'div' ):addClass( 'documentation' )
body
body
:addClass( docClass )
:addClass( docClass )
 
:css{
['background-color'] = '#' .. colour,
border = '1px solid #AAA',
padding = '0.8em 1em 0.7em',
['margin-top'] = '1em',
clear = 'both'
}
local header = mw.html.create( 'div' )
local header = mw.html.create( 'div' )
:addClass( 'documentation-header-top' )
:addClass( 'documentation-header-top' )
 
:css{
margin = '-0.8em -1em 0.8em',
padding = '0.8em 1em 0.7em',
['background-color'] = '#33333333',
['border-bottom'] = 'inherit'
}
header
header
:node( links )
:node( links )
:tag( 'span' )
:tag( 'span' )
:addClass( 'documentation-header-title' )
:attr( 'id', 'documentation-header-title' )
:wikitext( i18n.pageDocHeaderTitle )
:css{
 
['font-weight'] = 'bold',
['font-size'] = '130%',
['margin-right'] = '1em',
['line-height'] = '1'
}
:wikitext( 'Documentation' )
local codePages = {
local codePages = {
module = true,
module = true,
Line 287: Line 230:
script = true,
script = true,
}
}
if not noDoc and codePages[ pageType ] then
if not noDoc and codePages[pageType] then
header
header
:tag( 'span' )
:tag( 'span' )
:attr( 'id', 'documentation-jump-to-code' )
:attr( 'id', 'documentation-jump-to-code' )
:wikitext( i18n.commonInternalLinkPipe:format( '#the-code', i18n.pageDocJumpToCode ) )
:css( 'white-space', 'nowrap' )
:wikitext( '[[#the-code|Jump to code ↴]]' )
end
end
 
body
body
:node( header ):done()
:node( header ):done()
:wikitext( message )
:wikitext( message )
:wikitext( docText )
:wikitext( docText )
 
if not noDoc and page ~= docPage then
if not noDoc and page ~= docPage then
body
body
:tag( 'div' )
:tag( 'div' )
:addClass( 'documentation-header-bottom' )
:addClass( 'documentation-header-bottom' )
:css{
margin = '0.7em -1em -0.7em',
['background-color'] = '#33333333',
['border-top'] = 'inherit',
padding = '0.8em 1em 0.7em',
clear = 'both'
}
:node( links )
:node( links )
:wikitext( i18n.pageDocHeaderBottom:format( i18n.commonInternalLink:format( docPage.fullText ) ) )
:wikitext( 'The above documentation is transcluded from [[', docPage.fullText, ']].' )
end
 
if category then
body:wikitext( pageCategoryHandler( category ) )
end
end
 
local anchor = ''
local anchor = ''
if not noDoc and pageType ~= 'template' and pageType ~= 'message' then
if not noDoc and pageType ~= 'template' and pageType ~= 'message' then
anchor = mw.html.create( 'div' ):attr( 'id', 'the-code' )
anchor = mw.html.create( 'div' ):attr( 'id', 'the-code' )
end
end
 
return loadStyles( i18n.defaultStyles ) .. tostring( body ) .. tostring( anchor )
return tostring( body ) .. tostring( anchor )
end
end


return p
return p
Please note that all contributions to Mine in Abyss may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see Mine in Abyss:Copyrights for details). Do not submit copyrighted work without permission!
Cancel Editing help (opens in new window)