Wynncraft Wiki
Register
mNo edit summary
mNo edit summary
 
(11 intermediate revisions by 2 users not shown)
Line 28: Line 28:
 
end
 
end
 
 
local result = mw.ext.cargo.query(query.tables, query.fields, query)
+
local success, result = pcall(mw.ext.cargo.query, query.tables, query.fields, query)
  +
  +
if not success then
  +
return tostring(
  +
mw.html.create('strong')
  +
:addClass('error')
  +
:wikitext(result)
  +
:done()
  +
) .. '[[Category:Pages with cargo query errors]]'
 
end
  +
 
if #result == 0 then
 
if #result == 0 then
 
return frame:preprocess(args.default or '')
 
return frame:preprocess(args.default or '')
Line 44: Line 54:
 
local outro = frame:preprocess(args.outro or '')
 
local outro = frame:preprocess(args.outro or '')
 
if #result >= tonumber(args.limit or '100') then
 
if #result >= tonumber(args.limit or '100') then
  +
outro = outro .. frame:preprocess('{{#queryformlink:form=' .. (args.tables or args.table) .. '|link text=More results...}}')
local link = 'Special:CargoQuery?'
 
for key, value in pairs(args) do
 
if key ~= 'intro' then
 
link = link .. '&' .. key .. '=' .. value
 
end
 
end
 
outro = outro .. frame:preprocess('[["' .. link .. '|' .. (args['see more'] or 'See More...') .. ']]')
 
 
end
 
end
 
return intro .. table.concat(tbl,args.delimiter or '') .. outro
 
return intro .. table.concat(tbl,args.delimiter or '') .. outro

Latest revision as of 17:43, 20 August 2021

This module lets you get around the |no html bug that Cargo has by avoiding |format=template. This module implicitly assumed you ARE using named args in your template (corresponding to |named_args=yes; you do not need to specify this.)

Unlike |format=template, this wrapper will NOT rename parameters with underscores in them to use spaces instead.

Parameters

  • You may specify all parameters the same as if they were parameters in #cargo_query.

Example

{{#invoke:CargoQuery|main
 |table=Teams,Tenures=Ten
 |join on=Teams._pageName=Ten.Team
 |where=Teams.Region="Europe" AND Ten._pageName IS NOT NULL AND Ten.IsCurrent = "1"
 |fields=Teams._pageName=Page

 |template=User:RheingoldRiver/cargo query example/template
 |intro={{(!}} class="wikitable"
 |outro={{!)}}

 |limit=100
}}


local PARAM_LOOKUP = {
	['order by'] = 'orderBy',
	['join on'] = 'join',
	['group by'] = 'groupBy',
	table = 'tables',
}

local h = {}

local p = {}
function p.main(frame)
	local args = h.merge()
	
	local query = {}
	for k, v in pairs(args) do
		if string.sub(k, 0, 2) == 'q?' then
			local key = string.sub(k, 3)
			 query[PARAM_LOOKUP[key] or key] = v
		elseif PARAM_LOOKUP[k] then
			query[PARAM_LOOKUP[k]] = v
		else
			query[k] = v
		end
	end
	
	if args.one_to_many then
		query.fields = query.fields .. ',' .. query.one_to_many
	end
	
	local success, result = pcall(mw.ext.cargo.query, query.tables, query.fields, query)
	
	if not success then
		return tostring(
			mw.html.create('strong')
				:addClass('error')
				:wikitext(result)
			:done()
		) .. '[[Category:Pages with cargo query errors]]'
	end
	
	if #result == 0 then
		return frame:preprocess(args.default or '')
	end
	if args.one_to_many then
		result = h.groupOneToManyFields(result, h.getOneToManyTableFromArgs(args))
		h.concatOneToManyFieldsInEachRow(result, args.one_to_many_sep or ',')
	end
	local tbl = {}
	for i, row in ipairs(result) do
		row.index = i
		tbl[#tbl+1] = frame:expandTemplate{ title = args.template, args = row }
	end
	local intro = frame:preprocess(args.intro or '')
	local outro = frame:preprocess(args.outro or '')
	if #result >= tonumber(args.limit or '100') then
		outro = outro .. frame:preprocess('{{#queryformlink:form=' .. (args.tables or args.table) .. '|link text=More results...}}')
	end
	return intro .. table.concat(tbl,args.delimiter or '') .. outro
	
end

function h.merge()
	local f = mw.getCurrentFrame()
	local origArgs = f.args
	local parentArgs = f:getParent().args

	local args = {}
	
	for k, v in pairs(origArgs) do
		v = mw.text.trim(tostring(v))
		if v ~= '' then
			args[k] = v
		end
	end
	
	for k, v in pairs(parentArgs) do
		v = mw.text.trim(v)
		if v ~= '' then
			args[k] = v
		end
	end
	
	return args
end

function h.getOneToManyTableFromArgs(args)
	local oneToMany = {
		fields = mw.text.split(args.one_to_many, '%s*,%s*'),
		groupBy = { args.one_to_many_group },
	}
	return oneToMany
end

function h.groupOneToManyFields(result, oneToMany)
	if not oneToMany then return result end
	local currentKey
	local groupedResult = {}
	local fields = h.parseFieldsForKeys(oneToMany.fields)
	for _, row in ipairs(result) do
		local newKey = h.getNewKey(row, oneToMany.groupBy)
		if newKey == currentKey then
			h.addRowToExistingGroup(groupedResult, row, fields)
		else
			h.addRowToNewGroup(groupedResult, row, fields)
			currentKey = newKey
		end
	end
	return groupedResult
end

function h.parseFieldsForKeys(fields)
	for i, v in ipairs(fields) do
		fields[i] = h.parseOneFieldForKey(v)
	end
	return fields
end

function h.getNewKey(row, groupBy)
	local toConcat = {}
	for _, v in ipairs(groupBy) do
		toConcat[#toConcat+1] = row[v]
	end
	return table.concat(toConcat)
end

function h.parseOneFieldForKey(str)
	if not str:find('=') then return str end
	return str:match('=(.+)')
end

function h.addRowToExistingGroup(groupedResult, row, fields)
	for _, v in ipairs(fields) do
		local parentRowValues = groupedResult[#groupedResult][v]
		parentRowValues[#parentRowValues+1] = row[v]
	end
end

function h.addRowToNewGroup(groupedResult, row, fields)
	for _, v in ipairs(fields) do
		row[v] = { row[v] }
	end
	groupedResult[#groupedResult+1] = row
end

function h.concatOneToManyFieldsInEachRow(result, sep)
	for _, row in ipairs(result) do
		for k, v in pairs(row) do
			if type(v) == 'table' then
				row[k] = table.concat(v, sep)
			end
		end
	end
end

return p