| Modul Lua ini digunakan pada sekitar 434.000 halaman, atau sekira 10% dari keseluruhan halaman. Untuk mencegah suntingan mengganggu skala besar dan beban peladen, setiap perubahan harus diuji di subhalaman /bak pasir atau /kasus uji Modul:Infobox, atau bak pasir modul Anda. Perubahan yang telah diuji kemudian dapat ditambahkan ke halaman ini dalam satu suntingan. Pertimbangkan untuk mendiskusikan perubahan di halaman pembicaraan sebelum mengimplementasikannya. |
| Modul ini menggunakan Lua: |
| Modul ini menggunakan TemplateStyles: |
| Modul ini dilindungi. Modul ini sangat mencolok yang digunakan oleh banyak halaman, atau sangat sering disubstitusikan. Karena vandalisme atau kesalahan akan mempengaruhi banyak halaman, dan suntingan kecil dapat memberi beban besar pada server, modul ini dilindungi dari penyuntingan. |
Modul ini menjalankan templat {{Infobox}}. Gunakan halaman templat untuk melihat instruksi pemakaian.
Kategori pelacakKategori pelacak
Dokumentasi di atas ditransklusikan dari Modul:Infobox/doc. (sunting | riwayat)
Penyunting dapat melakukan uji coba pada halaman bak pasir (sunting | beda) dan kasus uji (buat) modul ini.
Subhalaman modul ini.
Penyunting dapat melakukan uji coba pada halaman bak pasir (sunting | beda) dan kasus uji (buat) modul ini.
Subhalaman modul ini.
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 localyesno=require("Modul:Yesno") 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 localfunctionisUntitledChildBox(sval) returnsvaland(sval:match('^%s*<%s*[Tt][Rr]')orsval:match('^%s*\127[^\127]*UNIQ%-%-templatestyles%-%x+%-QINU[^\127]*\127%s*<%s*[Tt][Rr]')) 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) :addClass(isUntitledChildBox(rowArgs.header)and'infobox-hiddenrow'ornil) :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.dataandnotyesno(args.decat)then root:wikitext( '[[Kategori:Halaman dengan sel data kotak info yang diabaikan]]' ) 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() else row:addClass(isUntitledChildBox(rowArgs.data)and'infobox-hiddenrow'ornil) 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') :addClass(isUntitledChildBox(args.above)and'infobox-hiddenrow'ornil) :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') :addClass(isUntitledChildBox(args.below)and'infobox-hiddenrow'ornil) :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) row:addClass(isUntitledChildBox(subheaderArgs.data)and'infobox-hiddenrow'ornil) 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) row:addClass(isUntitledChildBox(imageArgs.data)and'infobox-hiddenrow'ornil) 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('Modul: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() ifyesno(args.decat)thenreturnend ifargs.child=='yes'then ifargs.titlethen root:wikitext( '[[Kategori:Halaman yang menggunakan templat kotak info tersemat dengan parameter judul]]' ) end elseif#(getArgNums('data'))==0andmw.title.getCurrentTitle().namespace==0then root:wikitext('[[Kategori:Artikel yang menggunakan templat kotak info tanpa baris data]]') 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='Modul: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