Documentation for this module may be created at Module:Hatnote/doc

  1. --------------------------------------------------------------------------------
  2. -- Module:Hatnote --
  3. -- --
  4. -- This module produces hatnote links and links to related articles. It --
  5. -- implements the {{hatnote}} and {{format link}} meta-templates and includes --
  6. -- helper functions for other Lua hatnote modules. --
  7. --------------------------------------------------------------------------------
  8.  
  9. local libraryUtil = require('libraryUtil')
  10. local checkType = libraryUtil.checkType
  11. local mArguments -- lazily initialise [[Module:Arguments]]
  12. local yesno -- lazily initialise [[Module:Yesno]]
  13.  
  14. local p = {}
  15.  
  16. --------------------------------------------------------------------------------
  17. -- Helper functions
  18. --------------------------------------------------------------------------------
  19.  
  20. local function getArgs(frame)
  21. -- Fetches the arguments from the parent frame. Whitespace is trimmed and
  22. -- blanks are removed.
  23. mArguments = require('Module:Arguments')
  24. return mArguments.getArgs(frame, {parentOnly = true})
  25. end
  26.  
  27. local function removeInitialColon(s)
  28. -- Removes the initial colon from a string, if present.
  29. return s:match('^:?(.*)')
  30. end
  31.  
  32. function p.findNamespaceId(link, removeColon)
  33. -- Finds the namespace id (namespace number) of a link or a pagename. This
  34. -- function will not work if the link is enclosed in double brackets. Colons
  35. -- are trimmed from the start of the link by default. To skip colon
  36. -- trimming, set the removeColon parameter to true.
  37. checkType('findNamespaceId', 1, link, 'string')
  38. checkType('findNamespaceId', 2, removeColon, 'boolean', true)
  39. if removeColon ~= false then
  40. link = removeInitialColon(link)
  41. end
  42. local namespace = link:match('^(.-):')
  43. if namespace then
  44. local nsTable = mw.site.namespaces[namespace]
  45. if nsTable then
  46. return nsTable.id
  47. end
  48. end
  49. return 0
  50. end
  51.  
  52. function p.formatPages(...)
  53. -- Formats a list of pages using formatLink and returns it as an array. Nil
  54. -- values are not allowed.
  55. local pages = {...}
  56. local ret = {}
  57. for i, page in ipairs(pages) do
  58. ret[i] = p._formatLink(page)
  59. end
  60. return ret
  61. end
  62.  
  63. function p.formatPageTables(...)
  64. -- Takes a list of page/display tables and returns it as a list of
  65. -- formatted links. Nil values are not allowed.
  66. local pages = {...}
  67. local links = {}
  68. for i, t in ipairs(pages) do
  69. checkType('formatPageTables', i, t, 'table')
  70. local link = t[1]
  71. local display = t[2]
  72. links[i] = p._formatLink(link, display)
  73. end
  74. return links
  75. end
  76.  
  77. function p.makeWikitextError(msg, helpLink, addTrackingCategory)
  78. -- Formats an error message to be returned to wikitext. If
  79. -- addTrackingCategory is not false after being returned from
  80. -- [[Module:Yesno]], and if we are not on a talk page, a tracking category
  81. -- is added.
  82. checkType('makeWikitextError', 1, msg, 'string')
  83. checkType('makeWikitextError', 2, helpLink, 'string', true)
  84. yesno = require('Module:Yesno')
  85. local title = mw.title.getCurrentTitle()
  86. -- Make the help link text.
  87. local helpText
  88. if helpLink then
  89. helpText = ' ([[' .. helpLink .. '|help]])'
  90. else
  91. helpText = ''
  92. end
  93. -- Make the category text.
  94. local category
  95. if not title.isTalkPage and yesno(addTrackingCategory) ~= false then
  96. category = 'Hatnote templates with errors'
  97. category = string.format(
  98. '[[%s:%s]]',
  99. mw.site.namespaces[14].name,
  100. category
  101. )
  102. else
  103. category = ''
  104. end
  105. return string.format(
  106. '<strong class="error">Error: %s%s.</strong>%s',
  107. msg,
  108. helpText,
  109. category
  110. )
  111. end
  112.  
  113. --------------------------------------------------------------------------------
  114. -- Format link
  115. --
  116. -- Makes a wikilink from the given link and display values. Links are escaped
  117. -- with colons if necessary, and links to sections are detected and displayed
  118. -- with " § " as a separator rather than the standard MediaWiki "#". Used in
  119. -- the {{format hatnote link}} template.
  120. --------------------------------------------------------------------------------
  121.  
  122. function p.formatLink(frame)
  123. local args = getArgs(frame)
  124. local link = args[1]
  125. local display = args[2]
  126. if not link then
  127. return p.makeWikitextError(
  128. 'no link specified',
  129. 'Template:Format hatnote link#Errors',
  130. args.category
  131. )
  132. end
  133. return p._formatLink(link, display)
  134. end
  135.  
  136. function p._formatLink(link, display)
  137. -- Find whether we need to use the colon trick or not. We need to use the
  138. -- colon trick for categories and files, as otherwise category links
  139. -- categorise the page and file links display the file.
  140. checkType('_formatLink', 1, link, 'string')
  141. checkType('_formatLink', 2, display, 'string', true)
  142. link = removeInitialColon(link)
  143. local namespace = p.findNamespaceId(link, false)
  144. local colon
  145. if namespace == 6 or namespace == 14 then
  146. colon = ':'
  147. else
  148. colon = ''
  149. end
  150.  
  151. -- Find whether a faux display value has been added with the {{!}} magic
  152. -- word.
  153. if not display then
  154. local prePipe, postPipe = link:match('^(.-)|(.*)$')
  155. link = prePipe or link
  156. display = postPipe
  157. end
  158.  
  159. -- Find the display value.
  160. if not display then
  161. local page, section = link:match('^(.-)#(.*)$')
  162. if page then
  163. display = page .. ' § ' .. section
  164. end
  165. end
  166.  
  167. -- Assemble the link.
  168. if display then
  169. return string.format('[[%s%s|%s]]', colon, link, display)
  170. else
  171. return string.format('[[%s%s]]', colon, link)
  172. end
  173. end
  174.  
  175. --------------------------------------------------------------------------------
  176. -- Hatnote
  177. --
  178. -- Produces standard hatnote text. Implements the {{hatnote}} template.
  179. --------------------------------------------------------------------------------
  180.  
  181. function p.hatnote(frame)
  182. local args = getArgs(frame)
  183. local s = args[1]
  184. local options = {}
  185. if not s then
  186. return p.makeWikitextError(
  187. 'no text specified',
  188. 'Template:Hatnote#Errors',
  189. args.category
  190. )
  191. end
  192. options.extraclasses = args.extraclasses
  193. options.selfref = args.selfref
  194. return p._hatnote(s, options)
  195. end
  196.  
  197. function p._hatnote(s, options)
  198. checkType('_hatnote', 1, s, 'string')
  199. checkType('_hatnote', 2, options, 'table', true)
  200. local classes = {'hatnote'}
  201. local extraclasses = options.extraclasses
  202. local selfref = options.selfref
  203. if type(extraclasses) == 'string' then
  204. classes[#classes + 1] = extraclasses
  205. end
  206. if selfref then
  207. classes[#classes + 1] = 'selfref'
  208. end
  209. return string.format(
  210. '<div class="%s">%s</div>',
  211. table.concat(classes, ' '),
  212. s
  213. )
  214. end
  215.  
  216. return p