モジュール:Namespace detect
このモジュールについての説明文ページを モジュール:Namespace detect/doc に作成できます
1 --[[
2 --------------------------------------------------------------------------------
3 -- --
4 -- NAMESPACE DETECT --
5 -- --
6 -- This module implements the {{namespace detect}} template in Lua, with a --
7 -- few improvements: all namespaces and all namespace aliases are supported, --
8 -- and namespace names are detected automatically for the local wiki. The --
9 -- module can also use the corresponding subject namespace value if it is --
10 -- used on a talk page. Parameter names can be configured for different wikis --
11 -- by altering the values in the "cfg" table in --
12 -- Module:Namespace detect/config. --
13 -- --
14 --------------------------------------------------------------------------------
15 --]]
16
17 local data = mw.loadData('Module:Namespace detect/data')
18 local argKeys = data.argKeys
19 local cfg = data.cfg
20 local mappings = data.mappings
21
22 local yesno = require('Module:Yesno')
23 local mArguments -- Lazily initialise Module:Arguments
24 local mTableTools -- Lazily initilalise Module:TableTools
25 local ustringLower = mw.ustring.lower
26
27 local p = {}
28
29 local function fetchValue(t1, t2)
30 -- Fetches a value from the table t1 for the first key in array t2 where
31 -- a non-nil value of t1 exists.
32 for i, key in ipairs(t2) do
33 local value = t1[key]
34 if value ~= nil then
35 return value
36 end
37 end
38 return nil
39 end
40
41 local function equalsArrayValue(t, value)
42 -- Returns true if value equals a value in the array t. Otherwise
43 -- returns false.
44 for i, arrayValue in ipairs(t) do
45 if value == arrayValue then
46 return true
47 end
48 end
49 return false
50 end
51
52 function p.getPageObject(page)
53 -- Get the page object, passing the function through pcall in case of
54 -- errors, e.g. being over the expensive function count limit.
55 if page then
56 local success, pageObject = pcall(mw.title.new, page)
57 if success then
58 return pageObject
59 else
60 return nil
61 end
62 else
63 return mw.title.getCurrentTitle()
64 end
65 end
66
67 -- Provided for backward compatibility with other modules
68 function p.getParamMappings()
69 return mappings
70 end
71
72 local function getNamespace(args)
73 -- This function gets the namespace name from the page object.
74 local page = fetchValue(args, argKeys.demopage)
75 if page == '' then
76 page = nil
77 end
78 local demospace = fetchValue(args, argKeys.demospace)
79 if demospace == '' then
80 demospace = nil
81 end
82 local subjectns = fetchValue(args, argKeys.subjectns)
83 local ret
84 if demospace then
85 -- Handle "demospace = main" properly.
86 if equalsArrayValue(argKeys.main, ustringLower(demospace)) then
87 ret = mw.site.namespaces[0].name
88 else
89 ret = demospace
90 end
91 else
92 local pageObject = p.getPageObject(page)
93 if pageObject then
94 if pageObject.isTalkPage then
95 -- Get the subject namespace if the option is set,
96 -- otherwise use "talk".
97 if yesno(subjectns) then
98 ret = mw.site.namespaces[pageObject.namespace].subject.name
99 else
100 ret = 'talk'
101 end
102 else
103 ret = pageObject.nsText
104 end
105 else
106 return nil -- return nil if the page object doesn't exist.
107 end
108 end
109 ret = ret:gsub('_', ' ')
110 return ustringLower(ret)
111 end
112
113 function p._main(args)
114 -- Check the parameters stored in the mappings table for any matches.
115 local namespace = getNamespace(args) or 'other' -- "other" avoids nil table keys
116 local params = mappings[namespace] or {}
117 local ret = fetchValue(args, params)
118 --[[
119 -- If there were no matches, return parameters for other namespaces.
120 -- This happens if there was no text specified for the namespace that
121 -- was detected or if the demospace parameter is not a valid
122 -- namespace. Note that the parameter for the detected namespace must be
123 -- completely absent for this to happen, not merely blank.
124 --]]
125 if ret == nil then
126 ret = fetchValue(args, argKeys.other)
127 end
128 return ret
129 end
130
131 function p.main(frame)
132 mArguments = require('Module:Arguments')
133 local args = mArguments.getArgs(frame, {removeBlanks = false})
134 local ret = p._main(args)
135 return ret or ''
136 end
137
138 function p.table(frame)
139 --[[
140 -- Create a wikitable of all subject namespace parameters, for
141 -- documentation purposes. The talk parameter is optional, in case it
142 -- needs to be excluded in the documentation.
143 --]]
144
145 -- Load modules and initialise variables.
146 mTableTools = require('Module:TableTools')
147 local namespaces = mw.site.namespaces
148 local cfg = data.cfg
149 local useTalk = type(frame) == 'table'
150 and type(frame.args) == 'table'
151 and yesno(frame.args.talk) -- Whether to use the talk parameter.
152
153 -- Get the header names.
154 local function checkValue(value, default)
155 if type(value) == 'string' then
156 return value
157 else
158 return default
159 end
160 end
161 local nsHeader = checkValue(cfg.wikitableNamespaceHeader, 'Namespace')
162 local aliasesHeader = checkValue(cfg.wikitableAliasesHeader, 'Aliases')
163
164 -- Put the namespaces in order.
165 local mappingsOrdered = {}
166 for nsname, params in pairs(mappings) do
167 if useTalk or nsname ~= 'talk' then
168 local nsid = namespaces[nsname].id
169 -- Add 1, as the array must start with 1; nsid 0 would be lost otherwise.
170 nsid = nsid + 1
171 mappingsOrdered[nsid] = params
172 end
173 end
174 mappingsOrdered = mTableTools.compressSparseArray(mappingsOrdered)
175
176 -- Build the table.
177 local ret = '{| class="wikitable"'
178 .. '\n|-'
179 .. '\n! ' .. nsHeader
180 .. '\n! ' .. aliasesHeader
181 for i, params in ipairs(mappingsOrdered) do
182 for j, param in ipairs(params) do
183 if j == 1 then
184 ret = ret .. '\n|-'
185 .. '\n| <code>' .. param .. '</code>'
186 .. '\n| '
187 elseif j == 2 then
188 ret = ret .. '<code>' .. param .. '</code>'
189 else
190 ret = ret .. ', <code>' .. param .. '</code>'
191 end
192 end
193 end
194 ret = ret .. '\n|-'
195 .. '\n|}'
196 return ret
197 end
198
199 return p