模块:CargoQuery
This module lets you get around Cargo bugs with html encoding.
To use, preface query arguments with q?
. Even if you are only using one table or one field, use |q?tables=
or |q?fields=
.
Use Lua names of all query parameters, so |q?join=
, |q?groupBy
, etc.
Each method has several other parameters, which are detailed in their respective sections.
Methods
main
Use this method to get around the bug with |no html|format=template
. When using {{#cargo_query:tables=...|no html|template|template=...
in templates, you may see html code on the page.
{{#invoke:CargoQuery|main |q?tables= <!-- corresponds to table / tables --> |q?join= <!-- corresponds to join on --> |q?fields= <!-- corresponds to fields --> |q?where= <!-- corresponds to where --> |q?groupBy= <!-- corresponds to group by --> |q?having= <!-- corresponds to having --> |q?orderBy= <!-- corresponds to order by --> |q?limit= <!-- corresponds to limit --> |template= <!-- pagename of template (required) --> |delimiter= |default= }}
For simplicity of code, the named args parameter is required to be Yes, and you do not need to specify it.
Unlike |format=template
, this wrapper will NOT rename parameters with underscores in them to use spaces instead.
This method can also be called from other modules, with arguments table as first parameter. For example:
local cargoQuery = require('Module:cargoQuery') local tableRows = cargoQuery.main({['q?tables']=<tables>, ["q?fields"]=<fields>, template="cargoRow", default="no result", ... })
list
Use this method to get around the encoded html entity bug with |format=list
. For example, you may see '
instead of '
in the result.
{{#invoke:CargoQuery|list |q?tables= <!-- corresponds to table / tables --> |q?join= <!-- corresponds to join on --> |q?fields= <!-- corresponds to fields --> |q?where= <!-- corresponds to where --> |q?groupBy= <!-- corresponds to group by --> |q?having= <!-- corresponds to having --> |q?orderBy= <!-- corresponds to order by --> |q?limit= <!-- corresponds to limit --> |delimiter= |default= }}
Only the first field in the results will be used.
This method can be called from other modules, with arguments table as first parameter. For example:
local cargoQuery = require('Module:cargoQuery') local listString = cargoQuery.list({['q?tables']=<tables>, ["q?fields"]=<field>, delimiter="/", default="no result", ... })
custom
This method can be called from other modules only. It accepts a callback function, can be used to customize result row formatting. For example:
local cargoQuery = require('Module:cargoQuery') local output = cargoQuery.custom( {['q?tables']=<tables>, ["q?fields"]=<field>, delimiter="<br/>", default="no result", ... }, function(row, args, frame) local tbl = {} for k, v in pairs(row) do tbl[#tbl+1] = k .. ":" .. frame:expandTemplate{ title = "tr", args = {v} } end return table.concat(tbl, args.fieldsep or ',') end )
afExport
Export the query result as an ArrayFunctions Array. This method can be used in templates only.
{{#invoke:CargoQuery|afExport |q?tables= <!-- corresponds to table / tables --> |q?join= <!-- corresponds to join on --> |q?fields= <!-- corresponds to fields --> |q?where= <!-- corresponds to where --> |q?groupBy= <!-- corresponds to group by --> |q?having= <!-- corresponds to having --> |q?orderBy= <!-- corresponds to order by --> |q?limit= <!-- corresponds to limit --> |plainList = <!-- a fieldName in q?fields list--> }}
The return array is a 2-dimensional array by default, for example(represented in JSON format):
{ {name: 'John', age: 56}, {name: 'Bob', age: 24}, {name: 'Harry', age: 12} }
If `plainList` is specified, the return array is a 1-dimensional array with values from that field only. In the above example, if `|plainList=name` is specified, the return array is:
{ 'John', 'Bob', 'Harry' }
Dependencies
local query = function(args)
local query = {}
for k, v in pairs(args) do
if string.sub(k, 0, 2) == 'q?' then
query[string.sub(k, 3)] = v
end
end
return mw.ext.cargo.query(query.tables, query.fields, query)
end
local parse = function(x)
local currentFrame = mw.getCurrentFrame()
if x == currentFrame then
-- being called from template, x is the frame object.
return require('Module:ProcessArgs').merge(currentFrame.args, currentFrame:getParent().args, true), currentFrame
else
-- being called from module, x is the args table.
return x, currentFrame
end
end
local proc = function(x, rowHandle)
local args, frame = parse(x)
local result = query(args)
if not next(result) then
return args.default and frame:preprocess(args.default) or ''
end
local tbl = {}
for _, row in ipairs(result) do
tbl[#tbl+1] = rowHandle(row, args, frame)
end
return table.concat(tbl, args.delimiter or '')
end
------------------------------------------------------------------------
return {
-- only for templates, export the query result as an arrayFunctions array.
afExport = function(x)
local args, frame = parse(x)
local result = query(args)
if args.plainList then
local field = args.plainList
local tbl = {}
for _, row in ipairs(result) do
tbl[#tbl+1] = row[field]
end
return mw.af.export(tbl)
else
return mw.af.export(result)
end
end,
-- from template: {{#invoke:CargoQuery|main|q?tables=<tables>|q?fields=<fields>| ... }}
-- from module: require('Module:cargoQuery').main({['q?tables']=<tables>, ["q?fields"]=<fields>, ... })
main = function(x)
return proc(x, function(row, args, frame)
return frame:expandTemplate{ title = args.template, args = row }
end)
end,
-- from template: {{#invoke:CargoQuery|list|q?tables=<tables>|q?fields=<field>| ... }}
-- from module: require('Module:cargoQuery').list({['q?tables']=<tables>, ["q?fields"]=<field>, ... })
list = function(x)
return proc(x, function(row, args, frame)
for _,v in pairs(row) do
return v
end
end)
end,
-- from module only: require('Module:cargoQuery').callback(args, function(row, args, frame) --[[do something]] end)
custom = proc,
}