模組:Navbox

萌娘百科,萬物皆可萌的百科全書!轉載請標註來源頁面的網頁連結,並聲明引自萌娘百科。內容不可商用。
貢獻者:
Template-info.svg 模塊文檔  [] [刷新]
  1. --
  2. -- This module will implement {{Navbox}}
  3. --
  4. local p = {}
  5. local navbar = require('Module:Navbar')._navbar
  6. local getArgs -- lazily initialized
  7. local args
  8. local tableRowAdded = false
  9. local border
  10. local listnums = {}
  11. local function trim(s)
  12. return (mw.ustring.gsub(s, "^%s*(.-)%s*$", "%1"))
  13. end
  14. local function addNewline(s)
  15. if s:match('^[*:;#]') or s:match('^{|') then
  16. return '\n' .. s ..'\n'
  17. else
  18. return s
  19. end
  20. end
  21. local function addTableRow(tbl)
  22. -- If any other rows have already been added, then we add a 2px gutter row.
  23. if tableRowAdded then
  24. tbl
  25. :tag('tr')
  26. :css('height', '2px')
  27. :tag('td')
  28. :attr('colspan',2)
  29. end
  30. tableRowAdded = true
  31. return tbl:tag('tr')
  32. end
  33. local function renderNavBar(titleCell)
  34. -- Depending on the presence of the navbar and/or show/hide link, we may need to add a spacer div on the left
  35. -- or right to keep the title centered.
  36. local spacerSide = nil
  37. if args.navbar == 'off' then
  38. -- No navbar, and client wants no spacer, i.e. wants the title to be shifted to the left. If there's
  39. -- also no show/hide link, then we need a spacer on the right to achieve the left shift.
  40. if args.state == 'plain' then spacerSide = 'right' end
  41. elseif args.navbar == 'plain' then
  42. -- No navbar. Need a spacer on the left to balance out the width of the show/hide link.
  43. if args.state ~= 'plain' then spacerSide = 'left' end
  44. else
  45. -- Will render navbar (or error message). If there's no show/hide link, need a spacer on the right
  46. -- to balance out the width of the navbar.
  47. if args.state == 'plain' then spacerSide = 'right' end
  48. titleCell
  49. :tag('span')
  50. :css('float', 'left')
  51. :css('width', '8em')
  52. :css('text-align', 'left')
  53. :css('margin-right', '0.5em')
  54. :wikitext(navbar{
  55. args.name,
  56. mini = 1,
  57. fontstyle = (args.basestyle or '') .. ';' .. (args.titlestyle or '') .. ';background:none transparent;border:none;'
  58. })
  59. end
  60. -- Render the spacer div.
  61. if spacerSide then
  62. titleCell
  63. :tag('span')
  64. :css('float', spacerSide)
  65. :css('width', '8em')
  66. :css('font-size', '80%')
  67. :css('margin-' .. (spacerSide == 'left' and 'right' or 'left'), '0.5em')
  68. :wikitext(' ')
  69. end
  70. end
  71. --
  72. -- Title row
  73. --
  74. local function renderTitleRow(tbl)
  75. if not args.title then return end
  76. local titleRow = addTableRow(tbl)
  77. if args.titlegroup then
  78. titleRow
  79. :tag('th')
  80. :attr('scope', 'row')
  81. :addClass('navbox-group')
  82. :addClass(args.titlegroupclass)
  83. :cssText(args.basestyle)
  84. :cssText(args.groupstyle)
  85. :cssText(args.titlegroupstyle)
  86. :wikitext(args.titlegroup)
  87. end
  88. local titleCell = titleRow:tag('th'):attr('scope', 'col')
  89. if args.titlegroup then
  90. titleCell
  91. :css('border-left', '2px solid #fdfdfd')
  92. :css('width', '100%')
  93. end
  94. local titleColspan = 2
  95. if args.imageleft then titleColspan = titleColspan + 1 end
  96. if args.image then titleColspan = titleColspan + 1 end
  97. if args.titlegroup then titleColspan = titleColspan - 1 end
  98. titleCell
  99. :cssText(args.basestyle)
  100. :cssText(args.titlestyle)
  101. :addClass('navbox-title')
  102. :attr('colspan', titleColspan)
  103. renderNavBar(titleCell)
  104. titleCell
  105. :tag('div')
  106. :addClass(args.titleclass)
  107. :css('font-size', '110%')
  108. :wikitext(addNewline(args.title))
  109. end
  110. --
  111. -- Above/Below rows
  112. --
  113. local function getAboveBelowColspan()
  114. local ret = 2
  115. if args.imageleft then ret = ret + 1 end
  116. if args.image then ret = ret + 1 end
  117. return ret
  118. end
  119. local function renderAboveRow(tbl)
  120. if not args.above then return end
  121. addTableRow(tbl)
  122. :tag('td')
  123. :addClass('navbox-abovebelow')
  124. :addClass(args.aboveclass)
  125. :cssText(args.basestyle)
  126. :cssText(args.abovestyle)
  127. :attr('colspan', getAboveBelowColspan())
  128. :tag('div')
  129. :wikitext(addNewline(args.above))
  130. end
  131. local function renderBelowRow(tbl)
  132. if not args.below then return end
  133. addTableRow(tbl)
  134. :tag('td')
  135. :addClass('navbox-abovebelow')
  136. :addClass(args.belowclass)
  137. :cssText(args.basestyle)
  138. :cssText(args.belowstyle)
  139. :attr('colspan', getAboveBelowColspan())
  140. :tag('div')
  141. :wikitext(addNewline(args.below))
  142. end
  143. --
  144. -- List rows
  145. --
  146. local function renderListRow(tbl, listnum)
  147. local row = addTableRow(tbl)
  148. if listnum == 1 and args.imageleft then
  149. row
  150. :tag('td')
  151. :addClass('navbox-image')
  152. :addClass(args.imageclass)
  153. :css('width', '0%')
  154. :css('padding', '0px 2px 0px 0px')
  155. :cssText(args.imageleftstyle)
  156. :attr('rowspan', 2 * #listnums - 1)
  157. :tag('div')
  158. :wikitext(addNewline(args.imageleft))
  159. end
  160. if args['group' .. listnum] then
  161. local groupCell = row:tag('th')
  162. groupCell
  163. :attr('scope', 'row')
  164. :addClass('navbox-group')
  165. :addClass(args.groupclass)
  166. :cssText(args.basestyle)
  167. if args.groupwidth then
  168. groupCell:css('width', args.groupwidth)
  169. end
  170. groupCell
  171. :cssText(args.groupstyle)
  172. :cssText(args['group' .. listnum .. 'style'])
  173. :wikitext(args['group' .. listnum])
  174. end
  175. local listCell = row:tag('td')
  176. if args['group' .. listnum] then
  177. listCell
  178. :css('text-align', 'left')
  179. :css('border-left-width', '2px')
  180. :css('border-left-style', 'solid')
  181. else
  182. listCell:attr('colspan', 2)
  183. end
  184. if not args.groupwidth then
  185. listCell:css('width', '100%')
  186. end
  187. local isOdd = (listnum % 2) == 1
  188. local rowstyle = args.evenstyle
  189. if isOdd then rowstyle = args.oddstyle end
  190. local evenOdd
  191. if args.evenodd == 'swap' then
  192. if isOdd then evenOdd = 'even' else evenOdd = 'odd' end
  193. else
  194. if isOdd then evenOdd = args.evenodd or 'odd' else evenOdd = args.evenodd or 'even' end
  195. end
  196. listCell
  197. :css('padding', '0px')
  198. :cssText(args.liststyle)
  199. :cssText(rowstyle)
  200. :cssText(args['list' .. listnum .. 'style'])
  201. :addClass('navbox-list')
  202. :addClass('navbox-' .. evenOdd)
  203. :addClass(args.listclass)
  204. :tag('div')
  205. :css('padding', (listnum == 1 and args.list1padding) or args.listpadding or '0em 0.25em')
  206. :wikitext(addNewline(args['list' .. listnum]))
  207. if listnum == 1 and args.image then
  208. row
  209. :tag('td')
  210. :addClass('navbox-image')
  211. :addClass(args.imageclass)
  212. :css('width', '0%')
  213. :css('padding', '0px 0px 0px 2px')
  214. :cssText(args.imagestyle)
  215. :attr('rowspan', 2 * #listnums - 1)
  216. :tag('div')
  217. :wikitext(addNewline(args.image))
  218. end
  219. end
  220. --
  221. -- Tracking categories
  222. --
  223. --[=[
  224. local function needsHorizontalLists()
  225. if border == 'child' or border == 'subgroup' or args.tracking == 'no' then return false end
  226. local listClasses = {'plainlist', 'hlist', 'hlist hnum', 'hlist hwrap', 'hlist vcard', 'vcard hlist', 'hlist vevent'}
  227. for i, cls in ipairs(listClasses) do
  228. if args.listclass == cls or args.bodyclass == cls then
  229. return false
  230. end
  231. end
  232. return true
  233. end
  234. local function hasBackgroundColors()
  235. return mw.ustring.match(args.titlestyle or '','background') or mw.ustring.match(args.groupstyle or '','background') or mw.ustring.match(args.basestyle or '','background')
  236. end
  237. local function getTrackingCategories()
  238. local cats = {}
  239. if needsHorizontalLists() then table.insert(cats, '沒有使用水平列表的導航框') end
  240. if hasBackgroundColors() then table.insert(cats, '使用背景顏色的導航框') end
  241. return cats
  242. end
  243. local function renderTrackingCategories(builder)
  244. local title = mw.title.getCurrentTitle()
  245. if title.namespace ~= 10 then return end -- not in template space
  246. local subpage = title.subpageText
  247. if subpage == 'doc' or subpage == 'sandbox' or subpage == 'testcases' then return end
  248. for i, cat in ipairs(getTrackingCategories()) do
  249. builder:wikitext('[[Category:' .. cat .. ']]')
  250. end
  251. end
  252. ]=]
  253. --
  254. -- Main navbox tables
  255. --
  256. local function renderMainTable()
  257. local tbl = mw.html.create('table')
  258. :attr('cellspacing', 0)
  259. :addClass('nowraplinks')
  260. :addClass(args.bodyclass)
  261. if args.title and (args.state ~= 'plain' and args.state ~= 'off') then
  262. tbl
  263. :addClass('mw-collapsible')
  264. :addClass(args.state or 'autocollapse')
  265. end
  266. tbl:css('border-spacing', 0)
  267. if border == 'subgroup' or border == 'child' or border == 'none' then
  268. tbl
  269. :addClass('navbox-subgroup')
  270. :cssText(args.bodystyle)
  271. :cssText(args.style)
  272. else -- regular navobx - bodystyle and style will be applied to the wrapper table
  273. tbl
  274. :addClass('navbox-inner')
  275. :css('background', 'transparent')
  276. :css('color', 'inherit')
  277. end
  278. tbl:cssText(args.innerstyle)
  279. renderTitleRow(tbl)
  280. renderAboveRow(tbl)
  281. for i, listnum in ipairs(listnums) do
  282. renderListRow(tbl, listnum)
  283. end
  284. renderBelowRow(tbl)
  285. return tbl
  286. end
  287. function p._navbox(navboxArgs)
  288. args = navboxArgs
  289. for k, v in pairs(args) do
  290. local listnum = ('' .. k):match('^list(%d+)$')
  291. if listnum then table.insert(listnums, tonumber(listnum)) end
  292. end
  293. table.sort(listnums)
  294. border = trim(args.border or args[1] or '')
  295. -- render the main body of the navbox
  296. local tbl = renderMainTable()
  297. -- render the appropriate wrapper around the navbox, depending on the border param
  298. local res = mw.html.create()
  299. if border == 'none' then
  300. res:node(tbl)
  301. elseif border == 'subgroup' or border == 'child' then
  302. -- We assume that this navbox is being rendered in a list cell of a parent navbox, and is
  303. -- therefore inside a div with padding:0em 0.25em. We start with a </div> to avoid the
  304. -- padding being applied, and at the end add a <div> to balance out the parent's </div>
  305. res
  306. :wikitext('</div>') -- XXX: hack due to lack of unclosed support in mw.html.
  307. :node(tbl)
  308. :wikitext('<div>') -- XXX: hack due to lack of unclosed support in mw.html.
  309. else
  310. res
  311. :tag('table')
  312. :attr('cellspacing', 0)
  313. :addClass('navbox')
  314. :css('border-spacing', 0)
  315. :cssText(args.bodystyle)
  316. :cssText(args.style)
  317. :tag('tr')
  318. :tag('td')
  319. :css('padding', '2px')
  320. :node(tbl)
  321. end
  322. -- [=[ renderTrackingCategories(res) ]=]
  323. return tostring(res)
  324. end
  325. function p.navbox(frame)
  326. if not getArgs then
  327. getArgs = require('Module:Arguments').getArgs
  328. end
  329. args = getArgs(frame, {wrappers = 'Template:Navbox'})
  330. -- Read the arguments in the order they'll be output in, to make references number in the right order.
  331. local _
  332. _ = args.title
  333. _ = args.above
  334. for i = 1, 50 do
  335. _ = args["group" .. tostring(i)]
  336. _ = args["list" .. tostring(i)]
  337. end
  338. _ = args.below
  339. return p._navbox(args)
  340. end
  341. return p
此頁面最後編輯於 2016年12月8日 (週四) 13:43。
搜尋萌娘百科 (按"/"快速搜尋)
有新的未讀公告

阅读更多:模塊:Navbox(http://mzh.moegirl.tw/%E6%A8%A1%E5%A1%8A%3ANavbox )
本文引自萌娘百科(http://mzh.moegirl.tw ),文字内容默认使用《知识共享 署名-非商业性使用-相同方式共享 3.0 中国大陆》协议。