fcw>Joker876 |
|
(не показаны 2 промежуточные версии 2 участников) |
Строка 1: |
Строка 1: |
| -- This Module is used for making templates based in the Lua language.
| | return require('Dev:Navbox') |
| -- See more details about Lua in [[Help:Lua]].
| |
| -- The Fandom Developer's Wiki hosts Global Lua Modules that can be imported and locally overridden.
| |
| -- The next line imports the Navbox module from the [[w:c:dev:Global Lua Modules]].
| |
| | |
| -- Taken From Dev wiki to allow for custom params
| |
| --------------------------------------------------------------------
| |
| --<pre> Navbox Module
| |
| --
| |
| -- * Fully CSS styled (inline styles possible but not default)
| |
| -- * Supports unlimited rows
| |
| --
| |
| -- By User:Tjcool007 from layton.fandom.com
| |
| --------------------------------------------------------------------
| |
| | |
| local p = {}
| |
| | |
| local args = {} -- Arguments passed to template
| |
| local navbox -- Actual navbox
| |
| | |
| --local working = {}
| |
| local rownums, skiprows = {}, {}
| |
| local hasrows, alt, hasData, isChild = false, false, false, false
| |
| local activeSection, sections, cimage, cimageleft
| |
| local colspan, rowspan
| |
| | |
| local showText, hideText = 'Show', 'Hide'
| |
| | |
| local langCode = mw.getContentLanguage():getCode()
| |
| local localization = {} --localized strings table
| |
| localization['en'] = {show = 'Show', hide = 'Hide'}
| |
| localization['ru'] = {show = 'показать', hide = 'скрыть'}
| |
| localization['zh'] = {show = '显示', hide = '隐藏'}
| |
| if localization[langCode] then
| |
| showText = localization[langCode]['show']
| |
| hideText = localization[langCode]['hide']
| |
| end
| |
| | |
| ------------------------------------------------
| |
| -- Title
| |
| ------------------------------------------------
| |
| | |
| --- Processes the VDE links in the title
| |
| --
| |
| -- @param titlecell The table cell of the title
| |
| local function processVde( titlecell )
| |
| if not args.template then return end
| |
| | |
| titlecell:wikitext('<span class="navbox-vde">'
| |
| .. mw.getCurrentFrame():expandTemplate({
| |
| title = 'vdelinks',
| |
| args = { args.template, ['type'] = 'navbox' }
| |
| }) .. '</span>')
| |
| end
| |
| | |
| --- Processes the main title row
| |
| local function processTitle()
| |
| local titlerow = mw.html.create('tr'):addClass('navbox-title')
| |
| local titlecell = mw.html.create('th'):attr('colspan',colspan):attr('scope','col')
| |
| | |
| if not pcall( processVde, titlecell ) then
| |
| titlecell:wikitext( '<b class="navbox-vde error" title="Missing Template:Vdelinks">!!!</b>' )
| |
| end
| |
| | |
| titlecell:wikitext( args.title or '{{{title}}}' )
| |
| | |
| -- Padding
| |
| local hasTemplate = args.template ~= nil
| |
| local hasState = not args.state or args.state ~= 'plain'
| |
| | |
| if hasTemplate ~= hasState then
| |
| if hasTemplate then
| |
| titlecell:addClass('navbox-title-padright')
| |
| else
| |
| titlecell:addClass('navbox-title-padleft')
| |
| end
| |
| end
| |
| | |
| if args.titleclass then titlerow:addClass( args.titleclass ) end
| |
| if args.titlestyle then titlecell:cssText( args.titlestyle ) end
| |
| | |
| titlerow:node(titlecell)
| |
| navbox:node(titlerow)
| |
| end
| |
| | |
| local function _addGutter( parent, incRowspan )
| |
| parent:tag('tr'):addClass('navbox-gutter'):tag('td'):attr('colspan',2)
| |
| | |
| if incRowspan then
| |
| rowspan = rowspan + 1
| |
| end
| |
| end
| |
| | |
| ------------------------------------------------
| |
| -- Above/Below
| |
| ------------------------------------------------
| |
| | |
| --- Processes the above and below rows
| |
| --
| |
| -- @param rowtype Either 'above' or 'below'
| |
| local function processAboveBelow( rowtype )
| |
| if not args[rowtype] then return end
| |
| | |
| local abrow = mw.html.create('tr'):addClass('navbox-'..rowtype)
| |
| local abcell = mw.html.create('td'):attr('colspan',colspan):wikitext( args[rowtype] )
| |
| | |
| if args[rowtype .. 'class'] then abrow:addClass( args[rowtype .. 'class'] ) end
| |
| if args[rowtype .. 'style'] then abcell:cssText( args[rowtype .. 'style'] ) end
| |
| | |
| abrow:node( abcell )
| |
| _addGutter( navbox )
| |
| navbox:node( abrow )
| |
| end
| |
| | |
| ------------------------------------------------
| |
| -- Main Rows
| |
| ------------------------------------------------
| |
| | |
| --- Processes the images
| |
| local function _processImage(row, imgtype)
| |
| if not args[imgtype] then return end
| |
| | |
| local iclass = imgtype == 'image' and 'navbox-image-right' or 'navbox-image-left'
| |
| | |
| local imagecell = mw.html.create('td'):addClass('navbox-image'):addClass(iclass)
| |
| | |
| local image = args[imgtype]
| |
| if image:sub(1,1) ~= '[' then
| |
| local width = args[imgtype .. 'width'] or '100px'
| |
| imagecell:css('width',width):wikitext('['..'[' .. image .. '|' .. width .. '|link=' .. (args[imgtype .. 'link'] or '') .. ']]')
| |
| else
| |
| imagecell:css('width','0%'):wikitext(image)
| |
| end
| |
| | |
| if args[imgtype .. 'class'] then imagecell:addClass( args[imgtype .. 'class'] ) end
| |
| if args[imgtype .. 'style'] then imagecell:cssText( args[imgtype .. 'style'] ) end
| |
| | |
| row:node( imagecell )
| |
| if imgtype == 'image' then
| |
| cimage = imagecell
| |
| else
| |
| cimageleft = imagecell
| |
| end
| |
| end
| |
| | |
| --- Closes the currently active section (if any)
| |
| local function _closeCurrentSection()
| |
| if not activeSection then return end
| |
| | |
| local row = mw.html.create('tr'):addClass('navbox-section-row')
| |
| local cell = mw.html.create('td'):attr('colspan',2)
| |
| | |
| if not hasrows then
| |
| _processImage(row,'imageleft')
| |
| end
| |
| | |
| cell:node(sections[activeSection])
| |
| row:node(cell)
| |
| | |
| local firstRow = false
| |
| if not hasrows then
| |
| firstRow = true
| |
| hasrows = true
| |
| _processImage(row,'image')
| |
| end
| |
| | |
| _addGutter(navbox,not firstRow)
| |
| navbox:node(row)
| |
| rowspan = rowspan + 1
| |
| | |
| activeSection = false
| |
| hasData = false
| |
| end
| |
| | |
| --- Handles alternating rows
| |
| --
| |
| -- @return Alternatingly returns true or false. Always returns false if alternating rows
| |
| -- are disabled with "alternaterows = no"
| |
| local function _alternateRow()
| |
| if args.alternaterows == 'no' then return false end
| |
| if alt then
| |
| alt = false
| |
| return true
| |
| else
| |
| alt = true
| |
| return false
| |
| end
| |
| end
| |
| | |
| --- Process a single Header "row"
| |
| --
| |
| -- @param num Number of the row to be processed
| |
| local function processHeader(num)
| |
| if not args['header'..num] then return end
| |
| | |
| _closeCurrentSection()
| |
| | |
| local subtable = mw.html.create('table'):addClass('navbox-section')
| |
| local headerrow = mw.html.create('tr')
| |
| local header = mw.html.create('th'):addClass('navbox-header'):attr('colspan',2):attr('scope','col'):wikitext( args['header'..num] )
| |
| | |
| local collapseme = args['state'..num] or false
| |
| local state = false
| |
| | |
| if collapseme then
| |
| -- Look at this one
| |
| if collapseme ~= 'plain' then
| |
| state = collapseme == 'expanded' and 'expanded' or 'collapsed'
| |
| end
| |
| else
| |
| -- Look at default
| |
| local collapseall = args.defaultstate or false
| |
| if collapseall then
| |
| state = collapseall == 'expanded' and 'expanded' or 'collapsed'
| |
| end
| |
| end
| |
| | |
| if state then
| |
| subtable:addClass('mw-collapsible'):attr('data-expandtext',args['expandtext'..num] or args['defaultexpandtext'] or showText):attr('data-collapsetext',args['collapsetext'..num] or args['defaultcollapsetext'] or hideText)
| |
| if state == 'collapsed' then
| |
| subtable:addClass('mw-collapsed')
| |
| end
| |
| header:addClass('navbox-header-collapsible')
| |
| end
| |
| | |
| if args.headerclass then headerrow:addClass( args.headerclass ) end
| |
| if args.headerstyle then header:cssText( args.headerstyle ) end
| |
| | |
| headerrow:node(header)
| |
| subtable:node(headerrow)
| |
| | |
| sections[num] = subtable
| |
| activeSection = num
| |
| end
| |
| | |
| --- Processes a single list row
| |
| --
| |
| -- @param num Number of the row to be processed
| |
| local function processList(num)
| |
| if not args['list'..num] then return end
| |
| | |
| local row = mw.html.create('tr'):addClass('navbox-row')
| |
| | |
| if not hasrows and not activeSection then
| |
| _processImage(row, 'imageleft')
| |
| end
| |
| | |
| local listcell = mw.html.create('td'):addClass('navbox-list')
| |
| local hlistcell = listcell:tag('div'):addClass('hlist')
| |
|
| |
| local data = args['list'..num]
| |
|
| |
| if data:sub(1,1) == '*' then
| |
| -- Add newlines to support lists properly
| |
| hlistcell
| |
| :newline()
| |
| :wikitext( data )
| |
| :newline()
| |
| else
| |
| hlistcell:wikitext( data )
| |
| end
| |
| | |
| local altRow = _alternateRow()
| |
| if altRow then
| |
| row:addClass( args.altrowclass or 'alt' )
| |
| | |
| local listclass = args.altlistclass or args.listclass or false
| |
| if listclass then listcell:addClass( listclass ) end
| |
| | |
| local liststyle = args.altliststyle or args.liststyle or false
| |
| if liststyle then listcell:cssText( liststyle ) end
| |
| else
| |
| if args.rowclass then row:addClass( args.rowclass ) end
| |
| if args.listclass then listcell:addClass( args.listclass ) end
| |
| if args.liststyle then listcell:cssText( args.liststyle ) end
| |
| end
| |
| | |
| if args['group'..num] then
| |
| local groupcell = mw.html.create('th'):addClass('navbox-group'):attr('scope','row'):wikitext( args['group'..num] )
| |
| | |
| if altRow then
| |
| local groupclass = args.altgroupclass or args.groupclass or false
| |
| if groupclass then groupcell:addClass( groupclass ) end
| |
|
| |
| local groupstyle = args.altgroupstyle or args.groupstyle or false
| |
| if groupstyle then groupcell:cssText( groupstyle ) end
| |
| else
| |
| if args.groupclass then groupcell:addClass( args.groupclass ) end
| |
| if args.groupstyle then groupcell:cssText( args.groupstyle ) end
| |
| end
| |
| | |
| row:node( groupcell )
| |
| else
| |
| listcell:attr('colspan',2):addClass('no-group')
| |
| end
| |
| | |
| row:node( listcell )
| |
| | |
| local firstRow = false
| |
| if not hasrows and not activeSection then
| |
| firstRow = true
| |
| hasrows = true
| |
| _processImage(row, 'image')
| |
| end
| |
| | |
| if activeSection then
| |
| local parent = sections[activeSection]
| |
| if not isChild or not firstRow then
| |
| _addGutter(parent)
| |
| end
| |
| parent:node(row)
| |
| hasData = true
| |
| else
| |
| if not isChild or not firstRow then
| |
| _addGutter(navbox,not firstRow)
| |
| end
| |
| navbox:node( row )
| |
| rowspan = rowspan + 1
| |
| end
| |
| end
| |
| | |
| --- Processes all rows
| |
| local function processRows()
| |
| sections = {}
| |
| for i=1,#rownums do
| |
| local num = rownums[i]
| |
| if not skiprows[num] then
| |
| processHeader(num)
| |
| processList(num)
| |
| end
| |
| end
| |
| _closeCurrentSection()
| |
|
| |
| if cimageleft then
| |
| cimageleft:attr('rowspan',rowspan)
| |
| end
| |
| if cimage then
| |
| cimage:attr('rowspan',rowspan)
| |
| end
| |
| end
| |
| | |
| ------------------------------------------------
| |
| -- ARGUMENTS PREPROCESSOR
| |
| -- * Extracts arguments from frame and stores them in args table
| |
| -- * At the same time, checks for valid row numbers
| |
| ------------------------------------------------
| |
| | |
| --- Preprocessor for the arguments.
| |
| -- Will fill up the args table with the parameters from the frame grouped by their type.
| |
| --
| |
| -- @param frame The frame passed to the Module.
| |
| local function preProcessArgs(frame)
| |
| local tmp = {}
| |
| | |
| if frame == mw.getCurrentFrame() then
| |
| tmp = frame:getParent().args
| |
| else
| |
| tmp = frame
| |
| end
| |
| | |
| -- Storage tables
| |
| local nums = {}
| |
| | |
| -- Loop over all the args
| |
| for k,v in pairs(tmp) do
| |
| -- Skip empty args, which are useless
| |
| if v ~= '' then
| |
| local cat,num = tostring(k):match('^(%a+)([1-9]%d*)$')
| |
| | |
| if cat == 'header' or cat == 'list' then
| |
| nums[num] = true
| |
| end
| |
| | |
| args[k] = v -- Simple copy
| |
| end
| |
| end
| |
| | |
| colspan = args.image and 3 or 2
| |
| if args.imageleft then colspan = colspan + 1 end
| |
| rowspan = 0
| |
| | |
| if args.alternaterows == 'swap' then
| |
| alt = true
| |
| end
| |
| | |
| for k, v in pairs(nums) do
| |
| rownums[#rownums+1] = tonumber(k)
| |
| end
| |
| | |
| table.sort(rownums)
| |
| | |
| -- Calculate skip rows
| |
| local cSection, cSkip
| |
| local showall = args.showall
| |
| for i=1,#rownums do
| |
| local num = rownums[i]
| |
| if args['header'..num] then
| |
| cSection = true
| |
| cSkip = false
| |
| local showme = args['show'..num]
| |
| if showme == 'no' then
| |
| cSkip = true
| |
| elseif showme == 'auto' or (showme ~= 'yes' and showall ~= 'yes') then
| |
| if not args['list'..num] then
| |
| local nextNum = rownums[i+1]
| |
| cSkip = not nextNum or args['header'..nextNum] -- If next has a header -> skip
| |
| end
| |
| end
| |
| end
| |
| if cSection and cSkip then
| |
| skiprows[num] = true
| |
| end
| |
| end
| |
| end
| |
| | |
| ------------------------------------------------
| |
| -- MAIN FUNCTIONS
| |
| ------------------------------------------------
| |
| | |
| --- Processes the arguments to create the navbox.
| |
| --
| |
| -- @return A string with HTML that is the navbox.
| |
| local function _navbox()
| |
| -- Create the root HTML element
| |
| local trim = function(s)
| |
| return s and mw.ustring.gsub(s, "^%s*(.-)%s*$", "%1") or ''
| |
| end
| |
| local border = args.border or trim(args[1]) or ''
| |
| isChild = (border == 'child' or border == 'subgroup')
| |
| | |
| if isChild then
| |
| navbox = mw.html.create('table'):addClass('navbox-subgroup')
| |
| else
| |
| navbox = mw.html.create('table'):addClass('navbox')
| |
| | |
| if args.state ~= 'plain' then
| |
| navbox:addClass('mw-collapsible'):attr('data-expandtext',args['expandtext'] or args['defaultexpandtext'] or showText):attr('data-collapsetext',args['collapsetext'] or args['defaultcollapsetext'] or hideText)
| |
| if args.state == 'collapsed' then
| |
| navbox:addClass('mw-collapsed')
| |
| end
| |
| end
| |
| end
| |
| | |
| if args.bodyclass then navbox:addClass(args.bodyclass) end
| |
| if args.bodystyle then navbox:cssText(args.bodystyle) end
| |
| | |
| -- Process...
| |
| if not isChild then
| |
| processTitle()
| |
| processAboveBelow('above')
| |
| processRows()
| |
| processAboveBelow('below')
| |
| | |
| return tostring(navbox)
| |
| else
| |
| processRows()
| |
| | |
| local wrapper = mw.html.create('')
| |
| wrapper:wikitext('</div>')
| |
| wrapper:node(navbox)
| |
| wrapper:wikitext('<div class="hlist">')
| |
| return tostring(wrapper)
| |
| end
| |
| end
| |
| | |
| --- Main module entry point.
| |
| -- To be called with {{#invoke:navbox|main}} or directly from another module.
| |
| --
| |
| -- @param frame The frame passed to the module via the #invoke. If called from another
| |
| -- module directly, this should be a table with the parameter definition.
| |
| function p.main(frame)
| |
| -- Save the arguments in a local variable so other functions can use them.
| |
| preProcessArgs(frame)
| |
|
| |
| return _navbox()
| |
| end
| |
| | |
| return p
| |