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

  1. --------------------------------------------------------------------------------
  2. -- --
  3. -- PAGETYPE --
  4. -- --
  5. -- This is a meta-module intended to replace {{pagetype}} and similar --
  6. -- templates. It automatically detects namespaces, and allows for a --
  7. -- great deal of customisation. It can easily be ported to other --
  8. -- wikis by changing the values in the [[Module:Pagetype/config]]. --
  9. -- --
  10. --------------------------------------------------------------------------------
  11.  
  12. -- Load config.
  13. local cfg = mw.loadData('Module:Pagetype/config')
  14.  
  15. -- Load required modules.
  16. local getArgs = require('Module:Arguments').getArgs
  17. local yesno = require('Module:Yesno')
  18. local nsDetectModule = require('Module:Namespace detect')
  19. local nsDetect = nsDetectModule._main
  20. local getParamMappings = nsDetectModule.getParamMappings
  21. local getPageObject = nsDetectModule.getPageObject
  22.  
  23. local p = {}
  24.  
  25. local function shallowCopy(t)
  26. -- Makes a shallow copy of a table.
  27. local ret = {}
  28. for k, v in pairs(t) do
  29. ret[k] = v
  30. end
  31. return ret
  32. end
  33.  
  34. local function checkPagetypeInput(namespace, val)
  35. -- Checks to see whether we need the default value for the given namespace,
  36. -- and if so gets it from the pagetypes table.
  37. -- The yesno function returns true/false for "yes", "no", etc., and returns
  38. -- val for other input.
  39. local ret = yesno(val, val)
  40. if ret and type(ret) ~= 'string' then
  41. ret = cfg.pagetypes[namespace]
  42. end
  43. return ret
  44. end
  45.  
  46. local function getPagetypeFromClass(class, param, aliasTable, default)
  47. -- Gets the pagetype from a class specified from the first positional
  48. -- parameter.
  49. param = yesno(param, param)
  50. if param ~= false then -- No check if specifically disallowed.
  51. for _, alias in ipairs(aliasTable) do
  52. if class == alias then
  53. if type(param) == 'string' then
  54. return param
  55. else
  56. return default
  57. end
  58. end
  59. end
  60. end
  61. end
  62.  
  63. local function getNsDetectValue(args)
  64. -- Builds the arguments to pass to [[Module:Namespace detect]] and returns
  65. -- the result.
  66.  
  67. -- Get the default values.
  68. local ndArgs = {}
  69. local defaultns = args[cfg.defaultns]
  70. if defaultns == cfg.defaultnsAll then
  71. ndArgs = shallowCopy(cfg.pagetypes)
  72. else
  73. local defaultnsArray
  74. if defaultns == cfg.defaultnsExtended then
  75. defaultnsArray = cfg.extendedNamespaces
  76. elseif defaultns == cfg.defaultnsNone then
  77. defaultnsArray = {}
  78. else
  79. defaultnsArray = cfg.defaultNamespaces
  80. end
  81. for _, namespace in ipairs(defaultnsArray) do
  82. ndArgs[namespace] = cfg.pagetypes[namespace]
  83. end
  84. end
  85.  
  86. --[[
  87. -- Add custom values passed in from the arguments. These overwrite the
  88. -- defaults. The possible argument names are fetched from
  89. -- Module:Namespace detect automatically in case new namespaces are
  90. -- added. Although we accept namespace aliases as parameters, we only pass
  91. -- the local namespace name as a parameter to Module:Namespace detect.
  92. -- This means that the "image" parameter can overwrite defaults for the
  93. -- File: namespace, which wouldn't work if we passed the parameters through
  94. -- separately.
  95. --]]
  96. local mappings = getParamMappings()
  97. for ns, paramAliases in pairs(mappings) do
  98. -- Copy the aliases table, as # doesn't work with tables returned from
  99. -- mw.loadData.
  100. paramAliases = shallowCopy(paramAliases)
  101. local paramName = paramAliases[1]
  102. -- Iterate backwards along the array so that any values for the local
  103. -- namespace names overwrite those for namespace aliases.
  104. for i = #paramAliases, 1, -1 do
  105. local paramAlias = paramAliases[i]
  106. local ndArg = checkPagetypeInput(paramAlias, args[paramAlias])
  107. if ndArg == false then
  108. -- If any arguments are false, convert them to nil to protect
  109. -- against breakage by future changes to
  110. -- [[Module:Namespace detect]].
  111. ndArgs[paramName] = nil
  112. elseif ndArg then
  113. ndArgs[paramName] = ndArg
  114. end
  115. end
  116. end
  117. -- Check for disambiguation-class and N/A-class pages in mainspace.
  118. if ndArgs.main then
  119. local class = args[1]
  120. if type(class) == 'string' then
  121. -- Put in lower case so e.g. "Dab" and "dab" will both match.
  122. class = mw.ustring.lower(class)
  123. end
  124. local dab = getPagetypeFromClass(
  125. class,
  126. args[cfg.dab],
  127. cfg.dabAliases,
  128. cfg.dabDefault
  129. )
  130. if dab then
  131. ndArgs.main = dab
  132. else
  133. local na = getPagetypeFromClass(
  134. class,
  135. args[cfg.na],
  136. cfg.naAliases,
  137. cfg.naDefault
  138. )
  139. if na then
  140. ndArgs.main = na
  141. end
  142. end
  143. end
  144. -- If there is no talk value specified, use the corresponding subject
  145. -- namespace for talk pages.
  146. if not ndArgs.talk then
  147. ndArgs.subjectns = true
  148. end
  149. -- Add the fallback value. This can also be customised, but it cannot be
  150. -- disabled.
  151. local other = args[cfg.other]
  152. -- We will ignore true/false/nil results from yesno here, but using it
  153. -- anyway for consistency.
  154. other = yesno(other, other)
  155. if type(other) == 'string' then
  156. ndArgs.other = other
  157. else
  158. ndArgs.other = cfg.otherDefault
  159. end
  160. -- Allow custom page values.
  161. ndArgs.page = args.page
  162. return nsDetect(ndArgs)
  163. end
  164.  
  165. local function detectRedirects(args)
  166. local redirect = args[cfg.redirect]
  167. -- The yesno function returns true/false for "yes", "no", etc., and returns
  168. -- redirect for other input.
  169. redirect = yesno(redirect, redirect)
  170. if redirect == false then
  171. -- Detect redirects unless they have been explicitly disallowed with
  172. -- "redirect=no" or similar.
  173. return
  174. end
  175. local pageObject = getPageObject(args.page)
  176. -- If we are using subject namespaces elsewhere, do so here as well.
  177. if pageObject
  178. and not yesno(args.talk, true)
  179. and args[cfg.defaultns] ~= cfg.defaultnsAll
  180. then
  181. pageObject = getPageObject(
  182. pageObject.subjectNsText .. ':' .. pageObject.text
  183. )
  184. end
  185. -- Allow custom values for redirects.
  186. if pageObject and pageObject.isRedirect then
  187. if type(redirect) == 'string' then
  188. return redirect
  189. else
  190. return cfg.redirectDefault
  191. end
  192. end
  193. end
  194.  
  195. function p._main(args)
  196. local redirect = detectRedirects(args)
  197. if redirect then
  198. return redirect
  199. else
  200. return getNsDetectValue(args)
  201. end
  202. end
  203.  
  204. function p.main(frame)
  205. local args = getArgs(frame)
  206. return p._main(args)
  207. end
  208.  
  209. return p