Mô đun:Infobox
Giao diện
Mô đun Lua này được sử dụng ởkhoảng 1.090.000 trang, chiếm ≈ 6% tổng số trang. Để tránh gây lỗi trên quy mô lớn vàtải máy chủkhông cần thiết, tất cả thay đổi cần được thử nghiệm ở trang con/sandbox,/testcasescủa mô đun, hoặc ởchỗ thử mô đun.Các thay đổi đã được thử nghiệm có thể thêm vào mô đun bằng một sửa đổi duy nhất. Xin hãy thảo luận các thay đổi tạitrang thảo luậntrước khi áp dụng sửa đổi. |
Mô-đun này là loại cần được khóa. Nó là mộtmô-đun nhìn thấy rõđược sử dụng bởi một số lượng lớn các trang, hoặc là cácthay thếrất thường xuyên. Bởi vì phá hoại hoặc lỗi sai khi sửa sẽ ảnh hưởng đến nhiều trang và thậm chí chỉnh sửa tầm thường có thể gây ra tải đáng kể cho các máy chủ, nóđược khóa bảo vệhạn chế sửa đổi. |
Mô đun này phụ thuộc vào các mô đun sau: |
Module:Infoboxlàmoduletrong đó thực hiện định dạng thiết kế {{Infobox}}. Vui lòng xem trang tài liệu để biết hướng dẫn sử dụng.
--
-- Mô đun này thực hiện [[Bản mẫu:Infobox]].
--
localp={}
localnavbar=require('Module:Navbar')._navbar
localargs={}
localorigArgs={}
localroot
localfunctionnotempty(s)returnsands:match('%S')end
localfunctionfixChildBoxes(sval,tt)
ifnotempty(sval)then
localmarker='<span class=special_infobox_marker>'
locals=sval
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
-- https://en.wikipedia.org/w/index.php?title=Template_talk:Infobox_musical_artist&oldid=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
localfunctionunion(t1,t2)
-- Returns the union of the values of two tables, as a sequence.
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
localfunctiongetArgNums(prefix)
-- 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}.
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
localfunctionaddRow(rowArgs)
-- Adds a row to the infobox, with either a header cell
-- or a label/data cell combination.
ifrowArgs.headerandrowArgs.header~='_BLANK_'then
root
:tag('tr')
:addClass(rowArgs.rowclass)
:cssText(rowArgs.rowstyle)
:attr('id',rowArgs.rowid)
:tag('th')
:attr('colspan',2)
:attr('id',rowArgs.headerid)
:addClass(rowArgs.class)
:addClass(args.headerclass)
:css('text-align','center')
:css('padding','5px')
:cssText(args.headerstyle)
:cssText(rowArgs.rowcellstyle)
:wikitext(fixChildBoxes(rowArgs.header,'th'))
ifrowArgs.datathen
root:wikitext('[[Thể loại:Trang nhúng bản mẫu hộp thông tin có hàng dữ liệu bị bỏ qua]]')
end
elseifrowArgs.datathen
ifnotrowArgs.data:gsub('%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*]]',''):match('^%S')then
rowArgs.rowstyle='display:none'
end
localrow=root:tag('tr')
row:addClass(rowArgs.rowclass)
row:cssText(rowArgs.rowstyle)
row:attr('id',rowArgs.rowid)
ifrowArgs.labelthen
row
:tag('th')
:attr('scope','row')
:attr('id',rowArgs.labelid)
:cssText(args.labelstyle)
:cssText(rowArgs.rowcellstyle)
:wikitext(rowArgs.label)
:done()
end
localdataCell=row:tag('td')
ifnotrowArgs.labelthen
dataCell
:attr('colspan',2)
:css('text-align','center')
end
dataCell
:attr('id',rowArgs.dataid)
:addClass(rowArgs.class)
:cssText(rowArgs.datastyle)
:cssText(rowArgs.rowcellstyle)
:wikitext(fixChildBoxes(rowArgs.data,'td'))
end
end
localfunctionrenderTitle()
ifnotargs.titlethenreturnend
root
:tag('caption')
:addClass(args.titleclass)
:cssText(args.titlestyle)
:wikitext(args.title)
end
localfunctionrenderAboveRow()
ifnotargs.abovethenreturnend
root
:tag('tr')
:tag('th')
:attr('colspan',2)
:addClass(args.aboveclass)
:css('padding','12px')
:css('text-align','center')
:css('vertical-align','middle')
:css('line-height','1.1em')
:css('font-size','135%')
:css('font-weight','bold')
:css('color','black')
:cssText(args.abovestyle)
:wikitext(fixChildBoxes(args.above,'th'))
end
localfunctionrenderBelowRow()
ifnotargs.belowthenreturnend
root
:tag('tr')
:tag('td')
:attr('colspan','2')
:addClass(args.belowclass)
:css('text-align','center')
:cssText(args.belowstyle)
:wikitext(fixChildBoxes(args.below,'td'))
end
localfunctionrenderSubheaders()
ifargs.subheaderthen
args.subheader1=args.subheader
end
ifargs.subheaderrowclassthen
args.subheaderrowclass1=args.subheaderrowclass
end
localsubheadernums=getArgNums('subheader')
fork,numinipairs(subheadernums)do
addRow({
data=args['subheader'..tostring(num)],
datastyle=args.subheaderstyle,
rowcellstyle=args['subheaderstyle'..tostring(num)],
class=args.subheaderclass,
rowclass=args['subheaderrowclass'..tostring(num)]
})
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')
:css('padding','5px')
:cssText(args.captionstyle)
:wikitext(caption)
end
addRow({
data=tostring(data),
datastyle=args.imagestyle,
class=args.imageclass,
rowclass=args['imagerowclass'..tostring(num)]
})
end
end
localfunctionpreprocessRows()
-- Gets the union of the header and data argument numbers,
-- and renders them all in order using addRow.
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)]andargs['data'..tostring(num)]:gsub('%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*]]',''):match('^%S')then
localdata=args['data'..tostring(num)]
ifdata:gsub('%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*]]',''):match('%S')then
lastheader=nil
end
elseifargs['data'..tostring(num)]andmw.ustring.match(mw.ustring.gsub(args['data'..tostring(num)],'%[%[%s*[Tt][Hh][Ểể][_ ]-[Ll][Oo][Ạạ][Ii]%s*:[^]]*]]',''),'^%S')then
localdata=args['data'..tostring(num)]
ifmw.ustring.match(mw.ustring.gsub(data,'%[%[%s*[Tt][Hh][Ểể][_ ]-[Ll][Oo][Ạạ][Ii]%s*:[^]]*]]',''),'%S')then
lastheader=nil
end
end
end
iflastheaderthen
args['header'..tostring(lastheader)]=nil
end
end
localfunctionrenderRows()
-- Gets the union of the header and data argument numbers,
-- and renders them all in order using addRow.
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)],
rowstyle=args['rowstyle'..tostring(num)],
rowcellstyle=args['rowcellstyle'..tostring(num)],
dataid=args['dataid'..tostring(num)],
labelid=args['labelid'..tostring(num)],
headerid=args['headerid'..tostring(num)],
rowid=args['rowid'..tostring(num)]
})
end
end
localfunctionrenderNavBar()
ifnotargs.namethenreturnend
root
:tag('tr')
:tag('td')
:attr('colspan','2')
:css('text-align','right')
:wikitext(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(mw.getCurrentFrame():expandTemplate({title='italic title'}))
end
end
localfunctionrenderTrackingCategories()
ifargs.decat~='yes'then
ifargs.child=='yes'then
ifargs.titlethen
root:wikitext('[[Thể loại:Bài có hộp thông tin có tham số title]]')
end
elseif#(getArgNums('data'))==0andmw.title.getCurrentTitle().namespace==0then
root:wikitext('[[Thể loại:Bài có hộp thông tin không có hàng dữ liệu]]')
end
end
end
localfunction_infobox()
-- Specify the overall layout of the infobox, with special settings
-- if the infobox is used as a 'child' inside another infobox.
ifargs.child~='yes'then
root=mw.html.create('table')
root
:addClass((args.subbox~='yes')and'infobox'ornil)
:addClass(args.bodyclass)
ifargs.subbox=='yes'then
root
:css('padding','0')
:css('border','none')
:css('margin','-3px')
:css('width','auto')
:css('min-width','100%')
:css('font-size','100%')
:css('clear','none')
:css('float','none')
:css('background-color','transparent')
else
root
:css('width','22em')
end
root
:cssText(args.bodystyle)
renderTitle()
renderAboveRow()
else
root=mw.html.create()
root
:wikitext(args.title)
end
renderSubheaders()
renderImages()
ifargs.autoheadersthen
preprocessRows()
end
renderRows()
renderBelowRow()
renderNavBar()
renderItalicTitle()
renderTrackingCategories()
returntostring(root)
end
localfunctionpreprocessSingleArg(argName)
-- 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.
iforigArgs[argName]andorigArgs[argName]~=''then
args[argName]=origArgs[argName]
end
end
localfunctionpreprocessArgs(prefixTable,step)
-- 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.
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
moreArgumentsExist=true-- Do another loop if any arguments are found, even blank ones.
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
localfunctionparseDataParameters()
-- 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.
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'},
{prefix='dataid'},
{prefix='labelid'},
{prefix='headerid'},
{prefix='rowid'}
},50)
preprocessSingleArg('headerclass')
preprocessSingleArg('headerstyle')
preprocessSingleArg('labelstyle')
preprocessSingleArg('datastyle')
preprocessSingleArg('below')
preprocessSingleArg('belowclass')
preprocessSingleArg('belowstyle')
preprocessSingleArg('name')
args['italic title']=origArgs['italic title']-- different behaviour if blank or absent
preprocessSingleArg('decat')
end
functionp.infobox(frame)
-- If called via #invoke, use the args passed into the invoking template.
-- Otherwise, for testing purposes, assume args are being passed directly in.
ifframe==mw.getCurrentFrame()then
origArgs=frame:getParent().args
else
origArgs=frame
end
parseDataParameters()
return_infobox()
end
functionp.infoboxTemplate(frame)
-- For calling via #invoke within a template
origArgs={}
fork,vinpairs(frame.args)doorigArgs[k]=mw.text.trim(v)end
parseDataParameters()
return_infobox()
end
returnp