Module:Recipes by category table
Jump to navigation
Jump to search
Documentation for this module may be created at Module:Recipes by category table/doc
local p = {}
local lib = require('Module:Feature')
local Icon = require('Module:Icon')._main
local Icon_list = require('Module:Icon list')._main
local Parse = require('Module:Parser').getTemplateArgs
local LL = require('Module:Link label')._main
local show_time = false
function p.main(frame)
local args = require('Module:Arguments').getArgs(frame)
if lib.isEmpty(frame.args.pages) then
local result = args.noresult or ''
if result ~= '' then return result
elseif args[1] then
local array = lib.split(string.lower(args[1]), ';')
local link = (args.noresultlink and args.noresultlink) or 'crafting recipe'
if #array == 0 then result = 'No page matches category selection.'
elseif #array == 1 then result = 'No ' .. link .. ' needs ' .. array[1] .. '.'
elseif #array == 2 then result = 'No ' .. link .. ' needs ' .. array[1] .. ' or ' .. array[2] .. '.'
else
local last = table.remove(array, #array)
result = 'No ' .. link .. ' needs any of the following: ' .. table.concat(array, ', ') .. ', or ' .. last .. '.'
end
else
result = 'No page matches category selection.'
end
result = result .. require('Module:Namespace detect').main{main='[[Category:Pages with empty template results|Recipes by category table]]'}
return result
else
args.pages = frame.args.pages
local mustHave = {
ingredient = {},
medium = {}
}
if args[1] then
for item in lib.gsplit(args[1], ';') do
mustHave.ingredient[string.lower(item)] = true
end
end
if args.medium then
for item in lib.gsplit(args.medium, ';') do
mustHave.medium[string.lower(item)] = true
end
end
local Recipes = p.parsePages(args, mustHave)
-- mw.logObject(Recipes) --debug
if args.col1 then
local i = '1'
local cols = {}
while lib.isNotEmpty(args['col'..i]) do
local col = {}
col.name = args['col'..i .. '_name'] or ('Info ' .. i)
col.form = args['col'..i .. '_format'] ~= nil and lib.split((args['col'..i .. '_format']:gsub('²{', '{{'):gsub('}²', '}}'):gsub('¦', '|'):gsub('«(.-)»', '<%1>')), ',', {noTrim=true}) or nil
col.params = {}
for group in lib.gsplit(args['col'..i], ',') do
local template, params = string.match(group, '^{(.+)}:(.+)$')
for param in lib.gsplit(params, ':') do
table.insert(col.params, {
template = template,
param = param
})
end
end
table.insert(cols, col)
i = tostring(tonumber(i)+1)
end
args.CUSTOM_COLUMNS = cols
end
return p._main(Recipes, args, frame)
end
end
function p._main(Recipes, args, frame)
local out = mw.html.create('table'):addClass('fandom-table article-table sortable ' .. (args.class or ''))
--header
local tr = out:tag('tr')
tr:tag('th'):wikitext('Product')
tr:tag('th'):wikitext('Ingredients')
if not args.nomedium and (not args.medium or args.medium:find(';')) then tr:tag('th'):wikitext('Crafting<br />medium') end
if show_time and not args.notime then tr:tag('th'):wikitext('Time') end
if args.CUSTOM_COLUMNS and type(args.CUSTOM_COLUMNS) == 'table' and #args.CUSTOM_COLUMNS > 0 then
for col_num, col_data in ipairs(args.CUSTOM_COLUMNS) do
tr:tag('th'):wikitext(col_data.name)
end
end
--recipes
for _, recipe in ipairs(Recipes) do
local tr = out:tag('tr')
recipe[1] = recipe.items or recipe[1]
recipe.amount = '1'
tr:tag('td')
:node(Icon{
(recipe.product or recipe.PAGENAME),
(recipe['yield'] or '1'),
size = 60,
})
tr:tag('td'):node(Icon_list(recipe))
if not args.nomedium and (not args.medium or args.medium:find(';')) then
if recipe.medium and recipe.medium ~= 'Menu' then
tr:tag('td')
:node(Icon{
recipe.medium,
size = 60
})
else
tr:tag('td'):wikitext('[[Crafting|In-menu<br />crafting]]')
end
end
if show_time and not args.notime then tr:tag('td'):wikitext(recipe['time'] or '') end
if args.CUSTOM_COLUMNS and type(args.CUSTOM_COLUMNS) == 'table' and #args.CUSTOM_COLUMNS > 0 then
local Pdata = recipe.PAGEDATA
for col_num, col_data in ipairs(args.CUSTOM_COLUMNS) do
local td = tr:tag('td')
local ret = mw.html.create()
if col_data.form ~= nil then
for part, str in ipairs(col_data.form) do
ret:wikitext(str)
local pair = col_data.params[part]
if pair then
if pair.param == '%PAGE%' then
ret:wikitext(recipe.PAGENAME)
elseif Pdata[pair.template] and Pdata[pair.template][pair.param] then
ret:wikitext(Pdata[pair.template][pair.param])
end
end
end
else
for _, pair in ipairs(col_data.params) do
if pair.param == '%PAGE%' then
ret:wikitext(recipe.PAGENAME)
elseif Pdata[pair.template] and Pdata[pair.template][pair.param] then
ret:wikitext(Pdata[pair.template][pair.param])
end
end
end
td:wikitext(frame:preprocess(tostring(ret)))
end
end
end
return out
end
function p.parsePages(args, mustHave)
local Recipes = {}
local defaults = {
delim = ';',
delim_amount = '*',
delim_quality = '/'
}
local function inString(data)
for str in lib.gsplit(data.items, data.delim) do
for item in lib.gsplit(str, '//') do
local pre, quality = string.match(item, data.quality)
if not pre then
pre = item
end
local name, amount = string.match(pre, data.amount)
if not name then
name = pre
amount = '1'
end
-- mw.logObject(string.lower(name), 'name')
-- mw.logObject(mustHave, 'mustHave')
if (next(mustHave.ingredient) ~= nil and next(mustHave.medium) ~= nil and mustHave.ingredient[string.lower(name)] and mustHave.medium[string.lower(data.medium or 'menu')]) then
return true
elseif (next(mustHave.ingredient) ~= nil and next(mustHave.medium) == nil and mustHave.ingredient[string.lower(name)]) then
return true
elseif (next(mustHave.ingredient) == nil and next(mustHave.medium) ~= nil and mustHave.medium[string.lower(data.medium or 'crafting menu')]) then
return true
end
end
end
return false
end
for page in lib.gsplit(args.pages, ';;;') do
local page_data = Parse(page)
if page_data.Recipe then
if next(mustHave.ingredient) ~= nil or next(mustHave.medium) ~= nil then
if type(page_data.Recipe[1]) == 'table' then
for _, call in ipairs(page_data.Recipe) do
local data = {
items = call.items or call[1],
medium = call.medium or 'crafting menu',
delim = call.delim or defaults.delim,
quality = '^(.-)' .. (call.delim_quality or defaults.delim_quality) .. '(.*)$',
amount = '^(.-)' .. (call.delim_amount or defaults.delim_amount) .. '(.*)$'
}
if inString(data) then
if not show_time and lib.isNotEmpty(call['time']) then show_time = true end
call.PAGENAME = page
call.PAGEDATA = page_data
table.insert(Recipes, call)
end
end
else
local data = {
items = page_data.Recipe.items or page_data.Recipe[1],
delim = page_data.Recipe.delim or defaults.delim,
medium = page_data.Recipe.medium or 'crafting menu',
amount = '^(.-)' .. (page_data.Recipe.delim_amount or defaults.delim_amount) .. '(.*)$',
quality = '^(.-)' .. (page_data.Recipe.delim_quality or defaults.delim_quality) .. '(.*)$'
}
if inString(data) then
if not show_time and lib.isNotEmpty(page_data.Recipe['time']) then show_time = true end
page_data.Recipe.PAGENAME = page
page_data.Recipe.PAGEDATA = page_data
table.insert(Recipes, page_data.Recipe)
end
end
else
if page_data.Recipe[1] and type(page_data.Recipe[1]) == 'table' then
for _, call in ipairs(page_data.Recipe) do
if not show_time and lib.isNotEmpty(call['time']) then show_time = true end
call.PAGENAME = page
call.PAGEDATA = page_data
table.insert(Recipes, call)
end
else
if not show_time and lib.isNotEmpty(page_data.Recipe['time']) then show_time = true end
page_data.Recipe.PAGENAME = page
page_data.Recipe.PAGEDATA = page_data
table.insert(Recipes, page_data.Recipe)
end
end
end
end
return Recipes
end
return p