Pergi ke kandungan

Modul:Infobox

Daripada Wikipedia, ensiklopedia bebas.

Module:Infoboxis amodulethat implements the {{Infobox}} template. Please see the template page for usage instructions.

Tracking categories[sunting sumber]



localp={}
localargs={}
localorigArgs={}
localroot
localempty_row_categories={}
localcategory_in_empty_row_pattern='%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*]]'
localhas_rows=false
locallists={
plainlist_t={
patterns={
'^plainlist$',
'%splainlist$',
'^plainlist%s',
'%splainlist%s'
},
found=false,
styles='Plainlist/styles.css'
},
hlist_t={
patterns={
'^hlist$',
'%shlist$',
'^hlist%s',
'%shlist%s'
},
found=false,
styles='Hlist/styles.css'
}
}

localfunctionhas_list_class(args_to_check)
for_,listinpairs(lists)do
ifnotlist.foundthen
for_,arginpairs(args_to_check)do
for_,patterninipairs(list.patterns)do
ifmw.ustring.find(argor'',pattern)then
list.found=true
break
end
end
iflist.foundthenbreakend
end
end
end
end

localfunctionfixChildBoxes(sval,tt)
localfunctionnotempty(s)returnsands:match('%S')end

ifnotempty(sval)then
localmarker='<span class=special_infobox_marker>'
locals=sval
-- start moving templatestyles and categories inside of table rows
localslast=''
whileslast~=sdo
slast=s
s=mw.ustring.gsub(s,'(</[Tt][Rr]%s*>%s*)(%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*%]%])','%2%1')
s=mw.ustring.gsub(s,'(</[Tt][Rr]%s*>%s*)(\127[^\127]*UNIQ%-%-templatestyles%-%x+%-QINU[^\127]*\127)','%2%1')
end
-- end moving templatestyles and categories inside of table rows
s=mw.ustring.gsub(s,'(<%s*[Tt][Rr])',marker..'%1')
s=mw.ustring.gsub(s,'(</[Tt][Rr]%s*>)','%1'..marker)
ifs:match(marker)then
s=mw.ustring.gsub(s,marker..'%s*'..marker,'')
s=mw.ustring.gsub(s,'([\r\n]|-[^\r\n]*[\r\n])%s*'..marker,'%1')
s=mw.ustring.gsub(s,marker..'%s*([\r\n]|-)','%1')
s=mw.ustring.gsub(s,'(</[Cc][Aa][Pp][Tt][Ii][Oo][Nn]%s*>%s*)'..marker,'%1')
s=mw.ustring.gsub(s,'(<%s*[Tt][Aa][Bb][Ll][Ee][^<>]*>%s*)'..marker,'%1')
s=mw.ustring.gsub(s,'^(%{|[^\r\n]*[\r\n]%s*)'..marker,'%1')
s=mw.ustring.gsub(s,'([\r\n]%{|[^\r\n]*[\r\n]%s*)'..marker,'%1')
s=mw.ustring.gsub(s,marker..'(%s*</[Tt][Aa][Bb][Ll][Ee]%s*>)','%1')
s=mw.ustring.gsub(s,marker..'(%s*\n|%})','%1')
end
ifs:match(marker)then
localsubcells=mw.text.split(s,marker)
s=''
fork=1,#subcellsdo
ifk==1then
s=s..subcells[k]..'</'..tt..'></tr>'
elseifk==#subcellsthen
localrowstyle=' style= "display:none" '
ifnotempty(subcells[k])thenrowstyle=''end
s=s..'<tr'..rowstyle..'><'..tt..' colspan=2>\n'..
subcells[k]
elseifnotempty(subcells[k])then
if(k%2)==0then
s=s..subcells[k]
else
s=s..'<tr><'..tt..' colspan=2>\n'..
subcells[k]..'</'..tt..'></tr>'
end
end
end
end
-- the next two lines add a newline at the end of lists for the PHP parser
-- [[Special:Diff/849054481]]
-- remove when [[:phab:T191516]] is fixed or OBE
s=mw.ustring.gsub(s,'([\r\n][%*#;:][^\r\n]*)$','%1\n')
s=mw.ustring.gsub(s,'^([%*#;:][^\r\n]*)$','%1\n')
s=mw.ustring.gsub(s,'^([%*#;:])','\n%1')
s=mw.ustring.gsub(s,'^(%{%|)','\n%1')
returns
else
returnsval
end
end

-- Cleans empty tables
localfunctioncleanInfobox()
root=tostring(root)
ifhas_rows==falsethen
root=mw.ustring.gsub(root,'<table[^<>]*>%s*</table>','')
end
end

-- Returns the union of the values of two tables, as a sequence.
localfunctionunion(t1,t2)

localvals={}
fork,vinpairs(t1)do
vals[v]=true
end
fork,vinpairs(t2)do
vals[v]=true
end
localret={}
fork,vinpairs(vals)do
table.insert(ret,k)
end
returnret
end

-- Returns a table containing the numbers of the arguments that exist
-- for the specified prefix. For example, if the prefix was 'data', and
-- 'data1', 'data2', and 'data5' exist, it would return {1, 2, 5}.
localfunctiongetArgNums(prefix)
localnums={}
fork,vinpairs(args)do
localnum=tostring(k):match('^'..prefix..'([1-9]%d*)$')
ifnumthentable.insert(nums,tonumber(num))end
end
table.sort(nums)
returnnums
end

-- Adds a row to the infobox, with either a header cell
-- or a label/data cell combination.
localfunctionaddRow(rowArgs)

ifrowArgs.headerandrowArgs.header~='_BLANK_'then
has_rows=true
has_list_class({rowArgs.rowclass,rowArgs.class,args.headerclass})

root
:tag('tr')
:addClass(rowArgs.rowclass)
:cssText(rowArgs.rowstyle)
:tag('th')
:attr('colspan','2')
:addClass('infobox-header')
:addClass(rowArgs.class)
:addClass(args.headerclass)
-- @deprecated next; target.infobox-<name>.infobox-header
:cssText(args.headerstyle)
:cssText(rowArgs.rowcellstyle)
:wikitext(fixChildBoxes(rowArgs.header,'th'))
ifrowArgs.datathen
root:wikitext(
'[[Category:Pages using infobox templates with ignored data cells]]'
)
end
elseifrowArgs.dataandrowArgs.data:gsub(category_in_empty_row_pattern,''):match('^%S')then
has_rows=true
has_list_class({rowArgs.rowclass,rowArgs.class})

localrow=root:tag('tr')
row:addClass(rowArgs.rowclass)
row:cssText(rowArgs.rowstyle)
ifrowArgs.labelthen
row
:tag('th')
:attr('scope','row')
:addClass('infobox-label')
-- @deprecated next; target.infobox-<name>.infobox-label
:cssText(args.labelstyle)
:cssText(rowArgs.rowcellstyle)
:wikitext(rowArgs.label)
:done()
end

localdataCell=row:tag('td')
dataCell
:attr('colspan',notrowArgs.labeland'2'ornil)
:addClass(notrowArgs.labeland'infobox-full-data'or'infobox-data')
:addClass(rowArgs.class)
-- @deprecated next; target.infobox-<name>.infobox(-full)-data
:cssText(rowArgs.datastyle)
:cssText(rowArgs.rowcellstyle)
:wikitext(fixChildBoxes(rowArgs.data,'td'))
else
table.insert(empty_row_categories,rowArgs.dataor'')
end
end

localfunctionrenderTitle()
ifnotargs.titlethenreturnend

has_rows=true
has_list_class({args.titleclass})

root
:tag('caption')
:addClass('infobox-title')
:addClass(args.titleclass)
-- @deprecated next; target.infobox-<name>.infobox-title
:cssText(args.titlestyle)
:wikitext(args.title)

end

localfunctionrenderAboveRow()
ifnotargs.abovethenreturnend

has_rows=true
has_list_class({args.aboveclass})

root
:tag('tr')
:tag('th')
:attr('colspan','2')
:addClass('infobox-above')
:addClass(args.aboveclass)
-- @deprecated next; target.infobox-<name>.infobox-above
:cssText(args.abovestyle)
:wikitext(fixChildBoxes(args.above,'th'))
end

localfunctionrenderBelowRow()
ifnotargs.belowthenreturnend

has_rows=true
has_list_class({args.belowclass})

root
:tag('tr')
:tag('td')
:attr('colspan','2')
:addClass('infobox-below')
:addClass(args.belowclass)
-- @deprecated next; target.infobox-<name>.infobox-below
:cssText(args.belowstyle)
:wikitext(fixChildBoxes(args.below,'td'))
end

localfunctionaddSubheaderRow(subheaderArgs)
ifsubheaderArgs.dataand
subheaderArgs.data:gsub(category_in_empty_row_pattern,''):match('^%S')then
has_rows=true
has_list_class({subheaderArgs.rowclass,subheaderArgs.class})

localrow=root:tag('tr')
row:addClass(subheaderArgs.rowclass)

localdataCell=row:tag('td')
dataCell
:attr('colspan','2')
:addClass('infobox-subheader')
:addClass(subheaderArgs.class)
:cssText(subheaderArgs.datastyle)
:cssText(subheaderArgs.rowcellstyle)
:wikitext(fixChildBoxes(subheaderArgs.data,'td'))
else
table.insert(empty_row_categories,subheaderArgs.dataor'')
end
end

localfunctionrenderSubheaders()
ifargs.subheaderthen
args.subheader1=args.subheader
end
ifargs.subheaderrowclassthen
args.subheaderrowclass1=args.subheaderrowclass
end
localsubheadernums=getArgNums('subheader')
fork,numinipairs(subheadernums)do
addSubheaderRow({
data=args['subheader'..tostring(num)],
-- @deprecated next; target.infobox-<name>.infobox-subheader
datastyle=args.subheaderstyle,
rowcellstyle=args['subheaderstyle'..tostring(num)],
class=args.subheaderclass,
rowclass=args['subheaderrowclass'..tostring(num)]
})
end
end

localfunctionaddImageRow(imageArgs)

ifimageArgs.dataand
imageArgs.data:gsub(category_in_empty_row_pattern,''):match('^%S')then

has_rows=true
has_list_class({imageArgs.rowclass,imageArgs.class})

localrow=root:tag('tr')
row:addClass(imageArgs.rowclass)

localdataCell=row:tag('td')
dataCell
:attr('colspan','2')
:addClass('infobox-image')
:addClass(imageArgs.class)
:cssText(imageArgs.datastyle)
:wikitext(fixChildBoxes(imageArgs.data,'td'))
else
table.insert(empty_row_categories,imageArgs.dataor'')
end
end

localfunctionrenderImages()
ifargs.imagethen
args.image1=args.image
end
ifargs.captionthen
args.caption1=args.caption
end
localimagenums=getArgNums('image')
fork,numinipairs(imagenums)do
localcaption=args['caption'..tostring(num)]
localdata=mw.html.create():wikitext(args['image'..tostring(num)])
ifcaptionthen
data
:tag('div')
:addClass('infobox-caption')
-- @deprecated next; target.infobox-<name>.infobox-caption
:cssText(args.captionstyle)
:wikitext(caption)
end
addImageRow({
data=tostring(data),
-- @deprecated next; target.infobox-<name>.infobox-image
datastyle=args.imagestyle,
class=args.imageclass,
rowclass=args['imagerowclass'..tostring(num)]
})
end
end

-- When autoheaders are turned on, preprocesses the rows
localfunctionpreprocessRows()
ifnotargs.autoheadersthenreturnend

localrownums=union(getArgNums('header'),getArgNums('data'))
table.sort(rownums)
locallastheader
fork,numinipairs(rownums)do
ifargs['header'..tostring(num)]then
iflastheaderthen
args['header'..tostring(lastheader)]=nil
end
lastheader=num
elseifargs['data'..tostring(num)]and
args['data'..tostring(num)]:gsub(
category_in_empty_row_pattern,''
):match('^%S')then
localdata=args['data'..tostring(num)]
ifdata:gsub(category_in_empty_row_pattern,''):match('%S')then
lastheader=nil
end
end
end
iflastheaderthen
args['header'..tostring(lastheader)]=nil
end
end

-- Gets the union of the header and data argument numbers,
-- and renders them all in order
localfunctionrenderRows()

localrownums=union(getArgNums('header'),getArgNums('data'))
table.sort(rownums)
fork,numinipairs(rownums)do
addRow({
header=args['header'..tostring(num)],
label=args['label'..tostring(num)],
data=args['data'..tostring(num)],
datastyle=args.datastyle,
class=args['class'..tostring(num)],
rowclass=args['rowclass'..tostring(num)],
-- @deprecated next; target.infobox-<name> rowclass
rowstyle=args['rowstyle'..tostring(num)],
rowcellstyle=args['rowcellstyle'..tostring(num)]
})
end
end

localfunctionrenderNavBar()
ifnotargs.namethenreturnend

has_rows=true
root
:tag('tr')
:tag('td')
:attr('colspan','2')
:addClass('infobox-navbar')
:wikitext(require('Module:Navbar')._navbar{
args.name,
mini=1,
})
end

localfunctionrenderItalicTitle()
localitalicTitle=args['italic title']andmw.ustring.lower(args['italic title'])
ifitalicTitle==''oritalicTitle=='force'oritalicTitle=='yes'then
root:wikitext(require('Module:Italic title')._main({}))
end
end

-- Categories in otherwise empty rows are collected in empty_row_categories.
-- This function adds them to the module output. It is not affected by
-- args.decat because this module should not prevent module-external categories
-- from rendering.
localfunctionrenderEmptyRowCategories()
for_,sinipairs(empty_row_categories)do
root:wikitext(s)
end
end

-- Render tracking categories. args.decat == turns off tracking categories.
localfunctionrenderTrackingCategories()
ifargs.decat=='yes'thenreturnend
ifargs.child=='yes'then
ifargs.titlethen
root:wikitext(
'[[Category:Pages using embedded infobox templates with the title parameter]]'
)
end
elseif#(getArgNums('data'))==0andmw.title.getCurrentTitle().namespace==0then
root:wikitext('[[Category:Articles using infobox templates with no data rows]]')
end
end

--[=[
Loads the templatestyles for the infobox.

TODO: FINISH loading base templatestyles here rather than in
MediaWiki:Common.css. There are 4-5000 pages with 'raw' infobox tables.
See [[Mediawiki_talk:Common.css/to_do#Infobox]] and/or come help:).
When we do this we should clean up the inline CSS below too.
Will have to do some bizarre conversion category like with sidebar.

]=]
localfunctionloadTemplateStyles()
localframe=mw.getCurrentFrame()

localhlist_templatestyles=''
iflists.hlist_t.foundthen
hlist_templatestyles=frame:extensionTag{
name='templatestyles',args={src=lists.hlist_t.styles}
}
end

localplainlist_templatestyles=''
iflists.plainlist_t.foundthen
plainlist_templatestyles=frame:extensionTag{
name='templatestyles',args={src=lists.plainlist_t.styles}
}
end

-- See function description
localbase_templatestyles=frame:extensionTag{
name='templatestyles',args={src='Module:Infobox/styles.css'}
}

localtemplatestyles=''
ifargs['templatestyles']then
templatestyles=frame:extensionTag{
name='templatestyles',args={src=args['templatestyles']}
}
end

localchild_templatestyles=''
ifargs['child templatestyles']then
child_templatestyles=frame:extensionTag{
name='templatestyles',args={src=args['child templatestyles']}
}
end

localgrandchild_templatestyles=''
ifargs['grandchild templatestyles']then
grandchild_templatestyles=frame:extensionTag{
name='templatestyles',args={src=args['grandchild templatestyles']}
}
end

returntable.concat({
-- hlist -> plainlist -> base is best-effort to preserve old Common.css ordering.
-- this ordering is not a guarantee because the rows of interest invoking
-- each class may not be on a specific page
hlist_templatestyles,
plainlist_templatestyles,
base_templatestyles,
templatestyles,
child_templatestyles,
grandchild_templatestyles
})
end

-- common functions between the child and non child cases
localfunctionstructure_infobox_common()
renderSubheaders()
renderImages()
preprocessRows()
renderRows()
renderBelowRow()
renderNavBar()
renderItalicTitle()
renderEmptyRowCategories()
renderTrackingCategories()
cleanInfobox()
end

-- Specify the overall layout of the infobox, with special settings if the
-- infobox is used as a 'child' inside another infobox.
localfunction_infobox()
ifargs.child~='yes'then
root=mw.html.create('table')

root
:addClass(args.subbox=='yes'and'infobox-subbox'or'infobox')
:addClass(args.bodyclass)
-- @deprecated next; target.infobox-<name>
:cssText(args.bodystyle)

has_list_class({args.bodyclass})

renderTitle()
renderAboveRow()
else
root=mw.html.create()

root
:wikitext(args.title)
end
structure_infobox_common()

returnloadTemplateStyles()..root
end

-- If the argument exists and isn't blank, add it to the argument table.
-- Blank arguments are treated as nil to match the behaviour of ParserFunctions.
localfunctionpreprocessSingleArg(argName)
iforigArgs[argName]andorigArgs[argName]~=''then
args[argName]=origArgs[argName]
end
end

-- Assign the parameters with the given prefixes to the args table, in order, in
-- batches of the step size specified. This is to prevent references etc. from
-- appearing in the wrong order. The prefixTable should be an array containing
-- tables, each of which has two possible fields, a "prefix" string and a
-- "depend" table. The function always parses parameters containing the "prefix"
-- string, but only parses parameters in the "depend" table if the prefix
-- parameter is present and non-blank.
localfunctionpreprocessArgs(prefixTable,step)
iftype(prefixTable)~='table'then
error("Non-table value detected for the prefix table",2)
end
iftype(step)~='number'then
error("Invalid step value detected",2)
end

-- Get arguments without a number suffix, and check for bad input.
fori,vinipairs(prefixTable)do
iftype(v)~='table'ortype(v.prefix)~="string"or
(v.dependandtype(v.depend)~='table')then
error('Invalid input detected to preprocessArgs prefix table',2)
end
preprocessSingleArg(v.prefix)
-- Only parse the depend parameter if the prefix parameter is present
-- and not blank.
ifargs[v.prefix]andv.dependthen
forj,dependValueinipairs(v.depend)do
iftype(dependValue)~='string'then
error('Invalid "depend" parameter value detected in preprocessArgs')
end
preprocessSingleArg(dependValue)
end
end
end

-- Get arguments with number suffixes.
locala=1-- Counter variable.
localmoreArgumentsExist=true
whilemoreArgumentsExist==truedo
moreArgumentsExist=false
fori=a,a+step-1do
forj,vinipairs(prefixTable)do
localprefixArgName=v.prefix..tostring(i)
iforigArgs[prefixArgName]then
-- Do another loop if any arguments are found, even blank ones.
moreArgumentsExist=true
preprocessSingleArg(prefixArgName)
end
-- Process the depend table if the prefix argument is present
-- and not blank, or we are processing "prefix1" and "prefix" is
-- present and not blank, and if the depend table is present.
ifv.dependand(args[prefixArgName]or(i==1andargs[v.prefix]))then
forj,dependValueinipairs(v.depend)do
localdependArgName=dependValue..tostring(i)
preprocessSingleArg(dependArgName)
end
end
end
end
a=a+step
end
end

-- Parse the data parameters in the same order that the old {{infobox}} did, so
-- that references etc. will display in the expected places. Parameters that
-- depend on another parameter are only processed if that parameter is present,
-- to avoid phantom references appearing in article reference lists.
localfunctionparseDataParameters()

preprocessSingleArg('autoheaders')
preprocessSingleArg('child')
preprocessSingleArg('bodyclass')
preprocessSingleArg('subbox')
preprocessSingleArg('bodystyle')
preprocessSingleArg('title')
preprocessSingleArg('titleclass')
preprocessSingleArg('titlestyle')
preprocessSingleArg('above')
preprocessSingleArg('aboveclass')
preprocessSingleArg('abovestyle')
preprocessArgs({
{prefix='subheader',depend={'subheaderstyle','subheaderrowclass'}}
},10)
preprocessSingleArg('subheaderstyle')
preprocessSingleArg('subheaderclass')
preprocessArgs({
{prefix='image',depend={'caption','imagerowclass'}}
},10)
preprocessSingleArg('captionstyle')
preprocessSingleArg('imagestyle')
preprocessSingleArg('imageclass')
preprocessArgs({
{prefix='header'},
{prefix='data',depend={'label'}},
{prefix='rowclass'},
{prefix='rowstyle'},
{prefix='rowcellstyle'},
{prefix='class'}
},50)
preprocessSingleArg('headerclass')
preprocessSingleArg('headerstyle')
preprocessSingleArg('labelstyle')
preprocessSingleArg('datastyle')
preprocessSingleArg('below')
preprocessSingleArg('belowclass')
preprocessSingleArg('belowstyle')
preprocessSingleArg('name')
-- different behaviour for italics if blank or absent
args['italic title']=origArgs['italic title']
preprocessSingleArg('decat')
preprocessSingleArg('templatestyles')
preprocessSingleArg('child templatestyles')
preprocessSingleArg('grandchild templatestyles')
end

-- If called via #invoke, use the args passed into the invoking template.
-- Otherwise, for testing purposes, assume args are being passed directly in.
functionp.infobox(frame)
ifframe==mw.getCurrentFrame()then
origArgs=frame:getParent().args
else
origArgs=frame
end

parseDataParameters()

return_infobox()
end

-- For calling via #invoke within a template
functionp.infoboxTemplate(frame)
origArgs={}
fork,vinpairs(frame.args)doorigArgs[k]=mw.text.trim(v)end

parseDataParameters()

return_infobox()
end
returnp