Jump to content
Wikimedia Meta-Wiki

Module:Sidebar

From Meta, a Wikimedia project coordination wiki
Module documentation
The above documentation is transcluded from Module:Sidebar/doc. (edit | history)
Editors can experiment in this module’s sandbox (edit | diff) and testcases (create) pages.
Please add categories to the /doc subpage. Subpages of this module.

 require('strict')
 localcfg=mw.loadData('Module:Sidebar/configuration')

 localp={}

 localgetArgs=require('Module:Arguments').getArgs

 --[[
 Categorizes calling templates and modules with a 'style' parameter of any sort
 for tracking to convert to TemplateStyles.

 TODO after a long cleanup: Catch sidebars in other namespaces than Template and Module.
 TODO would probably want to remove /log and /archive as CS1 does
 ]]
 localfunctioncategorizeTemplatesWithInlineStyles(args)
 localtitle=mw.title.getCurrentTitle()
 iftitle.namespace~=10andtitle.namespace~=828thenreturn''end
 for_,patterninipairs(cfg.i18n.pattern.uncategorized_conversion_titles)do
 iftitle.text:match(pattern)thenreturn''end
 end

 forkey,_inpairs(args)do
 ifmw.ustring.find(key,cfg.i18n.pattern.style_conversion)orkey=='width'then
 returncfg.i18n.category.conversion
 end
 end
 end

 --[[
 For compatibility with the original {{sidebar with collapsible lists}}
 implementation, which passed some parameters through {{#if}} to trim their
 whitespace. This also triggered the automatic newline behavior.
 ]]
 -- See ([[meta:Help:Newlines and spaces#Automatic newline]])
 localfunctiontrimAndAddAutomaticNewline(s)
 s=mw.ustring.gsub(s,"^%s*(.-)%s*$","%1")
 ifmw.ustring.find(s,'^[#*:;]')ormw.ustring.find(s,'^{|')then
 return'\n'..s
 else
 returns
 end
 end

 --[[
 Finds whether a sidebar has a subgroup sidebar.
 ]]
 localfunctionhasSubgroup(s)
 ifmw.ustring.find(s,cfg.i18n.pattern.subgroup)then
 returntrue
 else
 returnfalse
 end
 end

 localfunctionhas_navbar(navbar_mode,sidebar_name)
 returnnavbar_mode~=cfg.i18n.navbar_noneand
 navbar_mode~=cfg.i18n.navbar_offand
 (
 sidebar_nameor
 mw.getCurrentFrame():getParent():getTitle():gsub(cfg.i18n.pattern.sandbox,'')~=
 cfg.i18n.title_not_to_add_navbar
 )
 end

 localfunctionhas_list_class(args,htmlclass)
 localpatterns={
 '^'..htmlclass..'$',
 '%s'..htmlclass..'$',
 '^'..htmlclass..'%s',
 '%s'..htmlclass..'%s'
 }

 forarg,valueinpairs(args)do
 iftype(arg)=='string'andmw.ustring.find(arg,'class')then
 for_,patterninipairs(patterns)do
 ifmw.ustring.find(args[arg]or'',pattern)then
 returntrue
 end
 end
 end
 end
 returnfalse
 end

 -- there are a lot of list classes in the wild, so we add their TemplateStyles
 localfunctionadd_list_styles(args)
 localframe=mw.getCurrentFrame()
 localfunctionadd_list_templatestyles(htmlclass,templatestyles)
 ifhas_list_class(args,htmlclass)then
 returnframe:extensionTag{
 name='templatestyles',args={src=templatestyles}
 }
 else
 return''
 end
 end

 localplainlist_styles=add_list_templatestyles('plainlist',cfg.i18n.plainlist_templatestyles)
 localhlist_styles=add_list_templatestyles('hlist',cfg.i18n.hlist_templatestyles)

 -- a second workaround for [[phab:T303378]]
 -- when that issue is fixed, we can actually use has_navbar not to emit the
 -- tag here if we want
 ifhas_navbar(args.navbar,args.name)andhlist_styles==''then
 hlist_styles=frame:extensionTag{
 name='templatestyles',args={src=cfg.i18n.hlist_templatestyles}
 }
 end

 -- hlist -> plainlist is best-effort to preserve old Common.css ordering. [hlist_note]
 returnhlist_styles..plainlist_styles
 end

 -- work around [[phab:T303378]]
 -- for each arg: find all the templatestyles strip markers, insert them into a
 -- table. then remove all templatestyles markers from the arg
 localfunctionmove_hiding_templatestyles(args)
 localgfind=string.gfind
 localgsub=string.gsub
 localtemplatestyles_markers={}
 localstrip_marker_pattern='(127円[^127円]*UNIQ%-%-templatestyles%-%x+%-QINU[^127円]*127円)'
 fork,arginpairs(args)do
 formarkeringfind(arg,strip_marker_pattern)do
 table.insert(templatestyles_markers,marker)
 end
 args[k]=gsub(arg,strip_marker_pattern,'')
 end
 returntemplatestyles_markers
 end

 --[[
 Main sidebar function. Takes the frame, args, and an optional collapsibleClass.
 The collapsibleClass is and should be used only for sidebars with collapsible
 lists, as in p.collapsible.
 ]]
 functionp.sidebar(frame,args,collapsibleClass)
 ifnotargsthen
 args=getArgs(frame)
 end
 localhiding_templatestyles=table.concat(move_hiding_templatestyles(args))
 localroot=mw.html.create()
 localchild=args.childandmw.text.trim(args.child)==cfg.i18n.child_yes

 root=root:tag('table')
 ifnotchildthen
 root
 :addClass(cfg.i18n.class.sidebar)
 -- force collapsibleclass to be sidebar-collapse otherwise output nothing
 :addClass(collapsibleClass==cfg.i18n.class.collapseandcfg.i18n.class.collapseornil)
 -- WMF hides vertical-navbox, which was the old name for the class
 -- this module emitted. we add nomobile now instead
 :addClass('nomobile')
 :addClass(args.float==cfg.i18n.float_noneandcfg.i18n.class.float_noneornil)
 :addClass(args.float==cfg.i18n.float_leftandcfg.i18n.class.float_leftornil)
 :addClass(args.wraplinks~=cfg.i18n.wrap_trueandcfg.i18n.class.wraplinksornil)
 :addClass(args.bodyclassorargs.class)
 :css('width',args.widthornil)
 :cssText(args.bodystyleorargs.style)

 ifargs.outertitlethen
 root
 :tag('caption')
 :addClass(cfg.i18n.class.outer_title)
 :addClass(args.outertitleclass)
 :cssText(args.outertitlestyle)
 :wikitext(args.outertitle)
 end

 ifargs.topimagethen
 localimageCell=root:tag('tr'):tag('td')

 imageCell
 :addClass(cfg.i18n.class.top_image)
 :addClass(args.topimageclass)
 :cssText(args.topimagestyle)
 :wikitext(args.topimage)

 ifargs.topcaptionthen
 imageCell
 :tag('div')
 :addClass(cfg.i18n.class.top_caption)
 :cssText(args.topcaptionstyle)
 :wikitext(args.topcaption)
 end
 end

 ifargs.pretitlethen
 root
 :tag('tr')
 :tag('td')
 :addClass(args.topimageandcfg.i18n.class.pretitle_with_top_image
 orcfg.i18n.class.pretitle)
 :addClass(args.pretitleclass)
 :cssText(args.basestyle)
 :cssText(args.pretitlestyle)
 :wikitext(args.pretitle)
 end
 else
 root
 :addClass(cfg.i18n.class.subgroup)
 :addClass(args.bodyclassorargs.class)
 :cssText(args.bodystyleorargs.style)
 end

 ifargs.titlethen
 ifchildthen
 root
 :wikitext(args.title)
 else
 root
 :tag('tr')
 :tag('th')
 :addClass(args.pretitleandcfg.i18n.class.title_with_pretitle
 orcfg.i18n.class.title)
 :addClass(args.titleclass)
 :cssText(args.basestyle)
 :cssText(args.titlestyle)
 :wikitext(args.title)
 end
 end

 ifargs.imagethen
 localimageCell=root:tag('tr'):tag('td')

 imageCell
 :addClass(cfg.i18n.class.image)
 :addClass(args.imageclass)
 :cssText(args.imagestyle)
 :wikitext(args.image)

 ifargs.captionthen
 imageCell
 :tag('div')
 :addClass(cfg.i18n.class.caption)
 :cssText(args.captionstyle)
 :wikitext(args.caption)
 end
 end

 ifargs.abovethen
 root
 :tag('tr')
 :tag('td')
 :addClass(cfg.i18n.class.above)
 :addClass(args.aboveclass)
 :cssText(args.abovestyle)
 :newline()-- newline required for bullet-points to work
 :wikitext(args.above)
 end

 localrowNums={}
 fork,vinpairs(args)do
 k=''..k
 localnum=k:match('^heading(%d+)$')ork:match('^content(%d+)$')
 ifnumthentable.insert(rowNums,tonumber(num))end
 end
 table.sort(rowNums)
 -- remove duplicates from the list (e.g. 3 will be duplicated if both heading3
 -- and content3 are specified)
 fori=#rowNums,1,-1do
 ifrowNums[i]==rowNums[i-1]then
 table.remove(rowNums,i)
 end
 end

 fori,numinipairs(rowNums)do
 localheading=args['heading'..num]
 ifheadingthen
 root
 :tag('tr')
 :tag('th')
 :addClass(cfg.i18n.class.heading)
 :addClass(args.headingclass)
 :addClass(args['heading'..num..'class'])
 :cssText(args.basestyle)
 :cssText(args.headingstyle)
 :cssText(args['heading'..num..'style'])
 :newline()
 :wikitext(heading)
 end

 localcontent=args['content'..num]
 ifcontentthen
 root
 :tag('tr')
 :tag('td')
 :addClass(hasSubgroup(content)andcfg.i18n.class.content_with_subgroup
 orcfg.i18n.class.content)
 :addClass(args.contentclass)
 :addClass(args['content'..num..'class'])
 :cssText(args.contentstyle)
 :cssText(args['content'..num..'style'])
 :newline()
 :wikitext(content)
 :done()
 -- Without a linebreak after the </td>, a nested list like
 -- "* {{hlist| ...}}" doesn't parse correctly.
 :newline()
 end
 end

 ifargs.belowthen
 root
 :tag('tr')
 :tag('td')
 :addClass(cfg.i18n.class.below)
 :addClass(args.belowclass)
 :cssText(args.belowstyle)
 :newline()
 :wikitext(args.below)
 end

 ifnotchildandhas_navbar(args.navbar,args.name)then
 root
 :tag('tr')
 :tag('td')
 :addClass(cfg.i18n.class.navbar)
 :cssText(args.navbarstyle)
 :wikitext(require('Module:Navbar')._navbar{
 args.name,
 mini=1,
 fontstyle=args.navbarfontstyle
 })
 end

 localbase_templatestyles=frame:extensionTag{
 name='templatestyles',args={src=cfg.i18n.templatestyles}
 }

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

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

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

 returntable.concat({
 add_list_styles(args),-- see [hlist_note] above about ordering
 base_templatestyles,
 templatestyles,
 child_templatestyles,
 grandchild_templatestyles,
 hiding_templatestyles,
 tostring(root),
 (childandcfg.i18n.category.childor''),
 categorizeTemplatesWithInlineStyles(args)
 })
 end

 localfunctionlist_title(args,is_centered_list_titles,num)

 localtitle_text=trimAndAddAutomaticNewline(args['list'..num..'title']
 orcfg.i18n.default_list_title)

 localtitle
 ifis_centered_list_titlesthen
 -- collapsible can be finicky, so provide some CSS/HTML to support
 title=mw.html.create('div')
 :addClass(cfg.i18n.class.list_title_centered)
 :wikitext(title_text)
 else
 title=mw.html.create()
 :wikitext(title_text)
 end

 localtitle_container=mw.html.create('div')
 :addClass(cfg.i18n.class.list_title)
 -- don't /need/ a listnumtitleclass because you can do
 -- .templateclass .listnumclass .sidebar-list-title
 :addClass(args.listtitleclass)
 :cssText(args.basestyle)
 :cssText(args.listtitlestyle)
 :cssText(args['list'..num..'titlestyle'])
 :node(title)
 :done()

 returntitle_container
 end

 --[[
 Main entry point for sidebar with collapsible lists.
 Does the work of creating the collapsible lists themselves and including them
 into the args.
 ]]
 functionp.collapsible(frame)
 localargs=getArgs(frame)
 ifnotargs.nameand
 frame:getParent():getTitle():gsub(cfg.i18n.pattern.collapse_sandbox,'')==
 cfg.i18n.collapse_title_not_to_add_navbarthen
 args.navbar=cfg.i18n.navbar_none
 end

 localcontentArgs={}

 localis_centered_list_titles=false
 ifargs['centered list titles']andargs['centered list titles']~=''then
 is_centered_list_titles=true
 end

 fork,vinpairs(args)do
 localnum=string.match(k,'^list(%d+)$')
 ifnumthen
 localexpand=args.expandedand
 (args.expanded=='all'orargs.expanded==args['list'..num..'name'])
 localrow=mw.html.create('div')
 row
 :addClass(cfg.i18n.class.list)
 :addClass('mw-collapsible')
 :addClass((notexpand)and'mw-collapsed'ornil)
 :addClass(args['list'..num..'class'])
 :cssText(args.listframestyle)
 :cssText(args['list'..num..'framestyle'])
 :node(list_title(args,is_centered_list_titles,num))
 :tag('div')
 :addClass(cfg.i18n.class.list_content)
 :addClass('mw-collapsible-content')
 -- don't /need/ a listnumstyleclass because you can do
 -- .templatename .listnumclass .sidebar-list
 :addClass(args.listclass)
 :cssText(args.liststyle)
 :cssText(args['list'..num..'style'])
 :wikitext(trimAndAddAutomaticNewline(args['list'..num]))

 contentArgs['content'..num]=tostring(row)
 end
 end

 fork,vinpairs(contentArgs)do
 args[k]=v
 end

 returnp.sidebar(frame,args,cfg.i18n.class.collapse)
 end

 returnp

AltStyle によって変換されたページ (->オリジナル) /