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

  1. --[[
  2. -- This module produces a "redirect" hatnote. It looks like this:
  3. -- '"X" redirects here. For other uses, see Y.'
  4. -- It implements the {{redirect}} template.
  5. --]]
  6.  
  7. local mHatnote = require('Module:Hatnote')
  8. local libraryUtil = require('libraryUtil')
  9. local checkType = libraryUtil.checkType
  10.  
  11. local p = {}
  12.  
  13. local function getTitle(...)
  14. local success, titleObj = pcall(mw.title.new, ...)
  15. if success then
  16. return titleObj
  17. else
  18. return nil
  19. end
  20. end
  21.  
  22. function p.redirect(frame)
  23. -- Get the args table and work out the maximum arg key.
  24. local origArgs = frame:getParent().args
  25. local args = {}
  26. local maxArg = 0
  27. for k, v in pairs(origArgs) do
  28. if type(k) == 'number' and k > maxArg then
  29. maxArg = k
  30. end
  31. v = v:match('^%s*(.-)%s*$') -- Trim whitespace
  32. if v ~= '' then
  33. args[k] = v
  34. end
  35. end
  36.  
  37. -- Return an error if no redirect was specified.
  38. local redirect = args[1]
  39. if not redirect then
  40. return mHatnote.makeWikitextError(
  41. 'no redirect specified',
  42. 'Template:Redirect#Errors',
  43. args.category
  44. )
  45. end
  46.  
  47. -- Create the data table.
  48. local data = {}
  49. local iArg = 0
  50. local iData = 1
  51. repeat
  52. iArg = iArg + 2
  53. local useTable = data[iData] or {}
  54. local pages = useTable.pages or {}
  55. local use = args[iArg]
  56. local page = args[iArg + 1]
  57. local nextUse = args[iArg + 2]
  58. pages[#pages + 1] = page
  59. useTable.pages = pages
  60. if use ~= 'and' then
  61. useTable.use = use
  62. end
  63. data[iData] = useTable
  64. if nextUse ~= 'and' then
  65. iData = iData + 1
  66. end
  67. until iArg >= maxArg - 1
  68.  
  69. -- Create the options table.
  70. local options = {}
  71. options.selfref = args.selfref
  72. return p._redirect(redirect, data, options)
  73. end
  74.  
  75. local function formatUseTable(useTable, isFirst, redirect)
  76. -- Formats one use table. Use tables are the tables inside the data array.
  77. -- Each one corresponds to one use. (A use might be the word "cats" in the
  78. -- phrase "For cats, see [[Felines]]".)
  79. -- Returns a string, or nil if no use was specified.
  80. -- The isFirst parameter is used to apply special formatting for the first
  81. -- table in the data array. If isFirst is specified, the redirect parameter
  82. useTable = useTable or {}
  83. local use
  84. if isFirst then
  85. use = useTable.use or 'other uses'
  86. elseif not useTable.use then
  87. return nil
  88. elseif tonumber(useTable.use) == 1 then
  89. use = 'other uses'
  90. else
  91. use = useTable.use
  92. end
  93. local pages = useTable.pages or {}
  94. if isFirst then
  95. redirect = redirect or error(
  96. 'isFirst was set in formatUseTable, but no redirect was supplied',
  97. 2
  98. )
  99. pages[1] = pages[1] or redirect .. ' (disambiguation)'
  100. else
  101. pages[1] = pages[1] or useTable.use .. ' (disambiguation)'
  102. end
  103. pages = mHatnote.formatPages(unpack(pages))
  104. pages = mw.text.listToText(pages)
  105. return string.format(
  106. 'For %s, see %s.',
  107. use,
  108. pages
  109. )
  110. end
  111.  
  112. function p._redirect(redirect, data, options, currentTitle, redirectTitle, targetTitle)
  113. -- Validate the input. Don't bother checking currentTitle, redirectTitle or
  114. -- targetTitle, as they are only used in testing.
  115. checkType('_redirect', 1, redirect, 'string')
  116. checkType('_redirect', 2, data, 'table', true)
  117. checkType('_redirect', 3, options, 'table', true)
  118. data = data or {}
  119. options = options or {}
  120. currentTitle = currentTitle or mw.title.getCurrentTitle()
  121.  
  122. -- Generate the text.
  123. local text = {}
  124. text[#text + 1] = '"' .. redirect .. '" redirects here.'
  125. text[#text + 1] = formatUseTable(data[1] or {}, true, redirect)
  126. if data[1] and data[1].use and data[1].use ~= 'other uses' then
  127. for i = 2, #data do
  128. text[#text + 1] = formatUseTable(data[i] or {}, false)
  129. end
  130. end
  131. text = table.concat(text, ' ')
  132. -- Generate the tracking category.
  133. -- We don't need a tracking category if the template invocation has been
  134. -- copied directly from the docs, or if we aren't in mainspace or category-space.
  135. local category
  136. if not redirect:find('^REDIRECT%d*$') and redirect ~= 'TERM' --
  137. and currentTitle.namespace == 0 or currentTitle.namespace == 14
  138. then
  139. redirectTitle = redirectTitle or getTitle(redirect)
  140. if not redirectTitle or not redirectTitle.exists then
  141. category = 'Missing redirects'
  142. elseif not redirectTitle.isRedirect then
  143. category = 'Articles with redirect hatnotes needing review'
  144. else
  145. local mRedirect = require('Module:Redirect')
  146. local target = mRedirect.getTarget(redirectTitle)
  147. targetTitle = targetTitle or target and getTitle(target)
  148. if targetTitle and targetTitle ~= currentTitle then
  149. category = 'Articles with redirect hatnotes needing review'
  150. end
  151. end
  152. end
  153. category = category and string.format('[[Category:%s]]', category) or ''
  154.  
  155. -- Generate the options to pass to [[Module:Hatnote]].
  156. local mhOptions = {}
  157. if currentTitle.namespace == 0
  158. and redirectTitle and redirectTitle.namespace ~= 0
  159. then
  160. -- We are on a mainspace page, and the hatnote starts with something
  161. -- like "Wikipedia:Foo redirects here", so automatically label it as a
  162. -- self-reference.
  163. mhOptions.selfref = true
  164. else
  165. mhOptions.selfref = options.selfref
  166. end
  167.  
  168. return mHatnote._hatnote(text, mhOptions) .. category
  169. end
  170. return p