Module:Infobox Recipe: Difference between revisions
The Gaffer (talk | contribs) No edit summary |
The Gaffer (talk | contribs) No edit summary |
||
(9 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
local currency = require('Module:Currency') |
local currency = require('Module:Currency') |
||
local |
local hc = require('Module:Param Parse').has_content |
||
local yn = require('Module:Yesno') |
local yn = require('Module:Yesno') |
||
local editButton = require('Module:Edit button') |
|||
local function currency_cell(amount) |
local function currency_cell(amount) |
||
Line 14: | Line 15: | ||
--If set to true, will check if any of the items passed as a rawmaterialparam are actually intermediate materials. Will then change the display order of the infobox. |
--If set to true, will check if any of the items passed as a rawmaterialparam are actually intermediate materials. Will then change the display order of the infobox. |
||
local showFullRecipe = yn(args.showFull or 'no', false) |
local showFullRecipe = yn(args.showFull or 'no', false) |
||
--Get each of the rawmatX parameters from params and store their values in a new table |
--Get each of the rawmatX parameters from params and store their values in a new table |
||
local argsMaterials = p._extractRawMaterials(args) |
local argsMaterials = p._extractRawMaterials(args) |
||
--empty tables to hold materials |
--empty tables to hold materials |
||
local rawMaterials = {} |
local rawMaterials = {} |
||
local intermediateMaterials = {} |
local intermediateMaterials = {} |
||
--counter for total price of raw materials |
--counter for total price of raw materials |
||
local rawMaterialCost = 0 |
local rawMaterialCost = 0 |
||
--get the value for the output product |
--get the value for the output product |
||
local output1Value = |
local output1Value = 0 |
||
if args.output1 then |
|||
output1Value = mw.smw.ask('[[:+]][[' .. args.output1 .. ']]|?Value|limit=1') or 0 |
|||
end |
|||
--Calculate total value of output material(s) |
|||
local output1TotalValue = 0 |
local output1TotalValue = 0 |
||
if output1Value |
if type(output1Value) == "table" then |
||
if output1Value[1]['Value'] ~= nil then |
|||
output1TotalValue = output1Value[1]['Value'] * (tonumber(args.output1qty) or 1) |
|||
else |
|||
output1TotalValue = 0 |
output1TotalValue = 0 |
||
end |
|||
end |
end |
||
--Check if any of the raw mats provided are intermediate products, if they are, return their own raw materials |
--Check if any of the raw mats provided are intermediate products, if they are, return their own raw materials |
||
Line 43: | Line 55: | ||
rawMaterials = argsMaterials |
rawMaterials = argsMaterials |
||
end |
end |
||
--Simple query to get the shop buy price for the provided material, if no buy price is available returns 0 |
--Simple query to get the shop buy price for the provided material, if no buy price is available returns 0 |
||
Line 52: | Line 66: | ||
return 0 |
return 0 |
||
end |
end |
||
--If one of the raw materials provided as a param has been identified as an intermediate material then get the facility it is created at to display in the intermediate Ingredient row |
--If one of the raw materials provided as a param has been identified as an intermediate material then get the facility it is created at to display in the intermediate Ingredient row |
||
Line 63: | Line 79: | ||
return pageName |
return pageName |
||
end |
end |
||
--Set SMW properties |
--Set SMW properties |
||
Line 71: | Line 89: | ||
}) |
}) |
||
end |
end |
||
if args.facility then |
if args.facility then |
||
mw.smw.set({ |
mw.smw.set({ |
||
Line 76: | Line 95: | ||
}) |
}) |
||
end |
end |
||
--Creates a row suitable for the raw materials section of the infobox. |
--Creates a row suitable for the raw materials section of the infobox. |
||
Line 97: | Line 118: | ||
:done() |
:done() |
||
end |
end |
||
--Creates a row suitable for the intermediate materials section of the infobox. |
--Creates a row suitable for the intermediate materials section of the infobox. |
||
Line 121: | Line 144: | ||
:done() |
:done() |
||
end |
end |
||
-- Recipe Table Head |
-- Recipe Table Head |
||
Line 138: | Line 163: | ||
:tag('td') |
:tag('td') |
||
:attr{ colspan = '11' } |
:attr{ colspan = '11' } |
||
:wikitext(args.facility and ('[[File:%s.png|link=%s|30px]] [[%s]]'):format(args.facility, args.facility, args.facility) or ' |
:wikitext(hc(args.facility) and ('[[File:%s.png|link=%s|30px]] [[%s]]'):format(args.facility, args.facility, args.facility) or editButton("'''?''' (edit)")) |
||
:done() |
:done() |
||
:done() |
:done() |
||
Line 158: | Line 184: | ||
:attr{ colspan = '2' } |
:attr{ colspan = '2' } |
||
:css{ ['text-align'] = 'center' } |
:css{ ['text-align'] = 'center' } |
||
:wikitext(args.profession and '[[' .. args.profession .. ']]' or ' |
:wikitext(hc(args.profession) and ('[[' .. args.profession .. ']]') or editButton("'''?''' (edit)")) |
||
:done() |
:done() |
||
:tag('td') |
:tag('td') |
||
:css{ ['text-align'] = 'center' } |
:css{ ['text-align'] = 'center' } |
||
:wikitext(args.level or ' |
:wikitext(hc(args.level) and (args.level) or editButton("'''?''' (edit)")) |
||
:done() |
:done() |
||
:tag('td') |
:tag('td') |
||
:attr{ colspan = '10' } |
:attr{ colspan = '10' } |
||
:css{ ['text-align'] = 'center' } |
:css{ ['text-align'] = 'center' } |
||
:wikitext(args.exp or ' |
:wikitext(hc(args.exp) and (args.exp) or editButton("'''?''' (edit)")) |
||
:done() |
:done() |
||
:done() |
:done() |
||
-- Add raw materials |
|||
-- Headers |
|||
:tag('tr') |
:tag('tr') |
||
:tag('th') |
:tag('th') |
||
Line 187: | Line 213: | ||
:done() |
:done() |
||
-- Values |
|||
for _, material in ipairs(rawMaterials) do |
for _, material in ipairs(rawMaterials) do |
||
out:node(createRawMaterialRow(material)) |
out:node(createRawMaterialRow(material)) |
||
end |
end |
||
-- Add total raw cost |
|||
out |
out |
||
:tag('tr') |
:tag('tr') |
||
Line 202: | Line 228: | ||
:done() |
:done() |
||
-- Add Intermediate steps if required |
|||
-- Headers |
-- Headers |
||
if next(intermediateMaterials) ~= nil then |
if next(intermediateMaterials) ~= nil then |
||
Line 221: | Line 247: | ||
:done() |
:done() |
||
-- Values |
|||
for _, material in ipairs(intermediateMaterials) do |
for _, material in ipairs(intermediateMaterials) do |
||
mw.logObject(material) |
mw.logObject(material) |
||
Line 228: | Line 254: | ||
end |
end |
||
-- Add output data |
|||
⚫ | |||
out |
out |
||
⚫ | |||
:tag('tr') |
:tag('tr') |
||
:tag('th') |
:tag('th') |
||
Line 244: | Line 270: | ||
:done() |
:done() |
||
:done() |
:done() |
||
if args.output1 then |
|||
⚫ | |||
out |
|||
⚫ | |||
:tag('tr') |
:tag('tr') |
||
:tag('td') |
:tag('td') |
||
:css{ ['border-right'] = 'none' } |
:css{ ['border-right'] = 'none' } |
||
:wikitext('[[File:' .. args.output1 .. '.png|30px|link=' .. args.output1 .. ']]') |
:wikitext('[[File:' .. args.output1 .. '.png|30px|link=' .. args.output1 .. ']]' or 'Unknown') |
||
:done() |
:done() |
||
:tag('td') |
:tag('td') |
||
:css{ ['border-left'] = 'none' } |
:css{ ['border-left'] = 'none' } |
||
:wikitext( |
:wikitext('[[' .. args.output1 .. ']]' or 'Unknown') |
||
:done() |
:done() |
||
:tag('td') |
:tag('td') |
||
Line 261: | Line 289: | ||
:wikitext(currency_cell(output1TotalValue)) |
:wikitext(currency_cell(output1TotalValue)) |
||
:done() |
:done() |
||
end |
|||
-- Add profit data |
|||
out |
|||
:tag('tr') |
:tag('tr') |
||
:tag('th') |
:tag('th') |
||
Line 273: | Line 302: | ||
return out |
return out |
||
end |
end |
||
function p._extractRawMaterials(args) |
function p._extractRawMaterials(args) |
||
Line 289: | Line 320: | ||
return rawMaterials |
return rawMaterials |
||
end |
end |
||
--This function takes a table containing the raw materials params received from the calling template. |
--This function takes a table containing the raw materials params received from the calling template. |
||
Line 346: | Line 379: | ||
return { rawMaterials = rawMaterials, intermediateMaterials = intermediateMaterials } |
return { rawMaterials = rawMaterials, intermediateMaterials = intermediateMaterials } |
||
end |
end |
||
function p._reverseTable(t) |
function p._reverseTable(t) |
||
Line 354: | Line 389: | ||
return reversed |
return reversed |
||
end |
end |
||
return p |
return p |
Revision as of 22:23, 21 November 2024
The Infobox Recipe template is used to show the details of a recipe step in item articles, such as a potion mixture or adding a cooking ingredient. It can also be used to display the experience gained for item creation.
Parameters
Parameter | Format | Usage | Mandatory? |
---|---|---|---|
facility
|
Link to facility | The name of the facility that is required to create the item; e.g. facility = Standard Potion Station will display
|
Yes |
profession
|
profession name | The profession in which experience is gained, or which has a level requirement, for creating the item | Yes |
level
|
Integer | The level required in the profession to create the item. | Yes |
exp
|
number | The amount of experience gained for performing the action. | Yes |
rawmat1
|
Exact name of the item | The primary item used for performing the craft. e.g. Brown Kelp for Brown Kelp
|
Yes |
rawmat1qty
|
Integer | The amount of the material used in the process.
This parameter can be removed if it would be 1 |
No |
rawmat2
|
Exact name of the item | The secondary item used for performing the craft. e.g. Brown Kelp for Brown Kelp
|
No |
rawmat2qty
|
Integer | The amount of the material used in the process.
This parameter can be removed if it would be 1 |
No |
rawmat3
|
Exact name of the item | The tertiary item used for performing the craft. e.g. Brown Kelp for Brown Kelp
|
No |
rawmat3qty
|
Integer | The amount of the material used in the process.
This parameter can be removed if it would be 1 |
No |
rawmat4
|
Exact name of the item | The fourth item used for performing the craft. e.g. Brown Kelp for Brown Kelp
|
No |
rawmat4qty
|
Integer | The amount of the material used in the process.
This parameter can be removed if it would be 1 |
No |
output1
|
Exact name of the item | The item created by performing the craft. e.g. Brown Kelp for Brown Kelp
|
Yes |
output1qty
|
Integer | The amount of the output created in the process.
This parameter can be removed if it would be 1 |
No |
showFull
|
boolean | Flag to display all steps of a recipe or only the step specified in the params | No |
Examples
Show Single Step Recipe
This is an example that uses values from the 10% Potion Healing recipe. Notice that this only shows information of the steps for which the information has been provided.
The showFull
parameter can be omitted entirely if this is the desired outcome as the default value is false
{{Infobox Recipe |facility = Standard Potion Station |profession = Alchemist |level = 0 |exp = 63 |rawmat1 = 10% Preparation Healing |rawmat2 = Bottle |output1 = 10% Potion Healing |output1qty = 1 }}
Requirements | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Facility | Standard Potion Station | |||||||||||
Profession | Level | XP | ||||||||||
Alchemist | 0 | 63 | ||||||||||
Raw Ingredient | Quantity | Cost | ||||||||||
10% Preparation Healing | 1 | 0 | ||||||||||
Bottle | 1 | 20 | ||||||||||
Total Raw cost | 20 | |||||||||||
Output | Quantity | Value | ||||||||||
10% Potion Healing | 1 | 450 | ||||||||||
Profit | 430 |
Show Full Recipe
This is an example that uses values from the 10% Potion Healing recipe. Notice that the parameters that have been passed to this example do not include 'Brown Kelp'
This is displayed because the showFull
parameter has been set to true
. This causes the Infobox Module to query smw data for each of the provided
raw materials to check if they have raw materials of their own. If they do, they are brought in to the recipe.
{{Infobox Recipe |facility = Standard Potion Station |profession = Alchemist |level = 0 |exp = 63 |rawmat1 = 10% Preparation Healing |rawmat2 = Bottle |output1 = 10% Potion Healing |output1qty = 1 |showFull = true }}
Requirements | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Facility | Standard Potion Station | |||||||||||
Profession | Level | XP | ||||||||||
Alchemist | 0 | 63 | ||||||||||
Raw Ingredient | Quantity | Cost | ||||||||||
Brown Kelp | 1 | 500 | ||||||||||
Bottle | 1 | 20 | ||||||||||
Total Raw cost | 520 | |||||||||||
Intermediate Ingredient | Quantity | Faciltity | ||||||||||
10% Preparation Healing | 1 | Reagent Preparation Station | ||||||||||
Output | Quantity | Value | ||||||||||
10% Potion Healing | 1 | 450 | ||||||||||
Profit | -70 |
Blank infobox
{{Infobox Recipe |facility = |profession = |level = |exp = |rawmat1 = |rawmat1qty = |rawmat2 = |rawmat2qty = |rawmat3 = |rawmat3qty = |output1 = |output1qty =
local currency = require('Module:Currency')
local hc = require('Module:Param Parse').has_content
local yn = require('Module:Yesno')
local editButton = require('Module:Edit button')
local function currency_cell(amount)
return currency._cell(amount, { html = 'yes' })
end
local p = {}
function p._main(frame)
local args = frame:getParent().args
--If set to true, will check if any of the items passed as a rawmaterialparam are actually intermediate materials. Will then change the display order of the infobox.
local showFullRecipe = yn(args.showFull or 'no', false)
--Get each of the rawmatX parameters from params and store their values in a new table
local argsMaterials = p._extractRawMaterials(args)
--empty tables to hold materials
local rawMaterials = {}
local intermediateMaterials = {}
--counter for total price of raw materials
local rawMaterialCost = 0
--get the value for the output product
local output1Value = 0
if args.output1 then
output1Value = mw.smw.ask('[[:+]][[' .. args.output1 .. ']]|?Value|limit=1') or 0
end
--Calculate total value of output material(s)
local output1TotalValue = 0
if type(output1Value) == "table" then
if output1Value[1]['Value'] ~= nil then
output1TotalValue = output1Value[1]['Value'] * (tonumber(args.output1qty) or 1)
else
output1TotalValue = 0
end
end
--Check if any of the raw mats provided are intermediate products, if they are, return their own raw materials
if showFullRecipe then
local Materials = p._getTrueRawMaterials(argsMaterials)
if next(Materials) ~= nil then
rawMaterials = Materials.rawMaterials
intermediateMaterials = p._reverseTable(Materials.intermediateMaterials)
end
else
rawMaterials = argsMaterials
end
--Simple query to get the shop buy price for the provided material, if no buy price is available returns 0
local function getBuyPrice(material)
local queryResult = mw.smw.ask('[[:+]][[Sold item::' .. material['name'] .. ']]|?Shop buy price|sort=Shop buy price|order=asc|limit=1') or 0
if type(queryResult) == "table" and queryResult[1]['Shop buy price'] then
return tonumber(queryResult[1]['Shop buy price']) or 0
end
return 0
end
--If one of the raw materials provided as a param has been identified as an intermediate material then get the facility it is created at to display in the intermediate Ingredient row
local function getFacility(material)
local result = mw.smw.ask('[[:+]][[' .. material .. ']]|?Uses facility|limit=1') or 'unknown'
local pageName = ''
if result and result[1] and result[1]["Uses facility"] then
local usesFac = result[1]["Uses facility"]
pageName = usesFac:gsub("%[%[", ""):gsub("%]%]", ""):gsub("|.*", ""):gsub("^:", "")
end
return pageName
end
--Set SMW properties
for _,material in ipairs(argsMaterials) do
mw.smw.set({
["Uses item"] = material.name,
["Uses item_and_quantity"] = material.name .. ',' .. tostring(material.quantity)
})
end
if args.facility then
mw.smw.set({
["Uses facility"] = args.facility
})
end
--Creates a row suitable for the raw materials section of the infobox.
local function createRawMaterialRow(item)
local materialBuyPrice = getBuyPrice(item)
rawMaterialCost = rawMaterialCost + materialBuyPrice
return mw.html.create('tr')
:tag('td')
:css{ ['border-right'] = 'none' }
:wikitext('[[File:' .. item.name .. '.png|30px|link=' .. item.name .. ']]')
:done()
:tag('td')
:css{ ['border-left'] = 'none' }
:wikitext('[[' .. item.name .. ']]')
:done()
:tag('td')
:css{ ['text-align'] = 'right' }
:wikitext(item.quantity or 1)
:done()
:wikitext(currency_cell(materialBuyPrice))
:done()
end
--Creates a row suitable for the intermediate materials section of the infobox.
local function createIntermediateMaterialRow(item)
local facility = getFacility(item.name)
return mw.html.create('tr')
:tag('td')
:css{ ['border-right'] = 'none' }
:wikitext('[[File:' .. item.name .. '.png|30px|link=' .. item.name .. ']]')
:done()
:tag('td')
:css{ ['border-left'] = 'none' }
:wikitext('[[' .. item.name .. ']]')
:done()
:tag('td')
:css{ ['text-align'] = 'right' }
:wikitext(item.quantity or 1)
:done()
:tag('td')
:attr{ colspan = '10' }
:css{ ['text-align'] = 'left' }
:wikitext('[[File:' .. facility .. '.png|30px|link=' .. facility .. ']] [[' .. facility .. ']]')
:done()
:done()
end
-- Recipe Table Head
local out = mw.html.create('table')
:addClass('wikitable')
:tag('tr')
:tag('th')
:attr{ colspan = '13' }
:wikitext('Requirements')
:done()
:done()
:tag('tr')
:tag('th')
:attr{ colspan = '2' }
:wikitext('Facility')
:done()
:tag('td')
:attr{ colspan = '11' }
:wikitext(hc(args.facility) and ('[[File:%s.png|link=%s|30px]] [[%s]]'):format(args.facility, args.facility, args.facility) or editButton("'''?''' (edit)"))
:done()
:done()
:tag('tr')
:tag('th')
:attr{ colspan = '2' }
:wikitext('Profession')
:done()
:tag('th')
:wikitext('Level')
:done()
:tag('th')
:attr{ colspan = '10' }
:wikitext('XP')
:done()
:done()
:tag('tr')
:tag('td')
:attr{ colspan = '2' }
:css{ ['text-align'] = 'center' }
:wikitext(hc(args.profession) and ('[[' .. args.profession .. ']]') or editButton("'''?''' (edit)"))
:done()
:tag('td')
:css{ ['text-align'] = 'center' }
:wikitext(hc(args.level) and (args.level) or editButton("'''?''' (edit)"))
:done()
:tag('td')
:attr{ colspan = '10' }
:css{ ['text-align'] = 'center' }
:wikitext(hc(args.exp) and (args.exp) or editButton("'''?''' (edit)"))
:done()
:done()
-- Add raw materials
-- Headers
:tag('tr')
:tag('th')
:attr{ colspan = '2' }
:wikitext('Raw Ingredient')
:done()
:tag('th')
:wikitext('Quantity')
:done()
:tag('th')
:attr{ colspan = '10' }
:wikitext('Cost')
:done()
:done()
-- Values
for _, material in ipairs(rawMaterials) do
out:node(createRawMaterialRow(material))
end
-- Add total raw cost
out
:tag('tr')
:tag('th')
:attr{ colspan = '3' }
:wikitext('Total Raw cost')
:done()
:wikitext(currency_cell(rawMaterialCost))
:done()
-- Add Intermediate steps if required
-- Headers
if next(intermediateMaterials) ~= nil then
-- Headers
out
:tag('tr')
:tag('th')
:attr{ colspan = '2' }
:wikitext('Intermediate Ingredient')
:done()
:tag('th')
:wikitext('Quantity')
:done()
:tag('th')
:attr{ colspan = '10' }
:wikitext('Faciltity')
:done()
:done()
-- Values
for _, material in ipairs(intermediateMaterials) do
mw.logObject(material)
out:node(createIntermediateMaterialRow(material))
end
end
-- Add output data
-- Headers
out
:tag('tr')
:tag('th')
:attr{ colspan = '2' }
:wikitext('Output')
:done()
:tag('th')
:wikitext('Quantity')
:done()
:tag('th')
:attr{ colspan = '10' }
:wikitext('Value')
:done()
:done()
if args.output1 then
out
-- Values
:tag('tr')
:tag('td')
:css{ ['border-right'] = 'none' }
:wikitext('[[File:' .. args.output1 .. '.png|30px|link=' .. args.output1 .. ']]' or 'Unknown')
:done()
:tag('td')
:css{ ['border-left'] = 'none' }
:wikitext('[[' .. args.output1 .. ']]' or 'Unknown')
:done()
:tag('td')
:css{ ['text-align'] = 'right' }
:wikitext(args.output1qty or 1)
:done()
:wikitext(currency_cell(output1TotalValue))
:done()
end
-- Add profit data
out
:tag('tr')
:tag('th')
:attr{ colspan = '3' }
:wikitext('Profit')
:done()
:wikitext(currency_cell(output1TotalValue - rawMaterialCost))
:done()
return out
end
function p._extractRawMaterials(args)
local rawMaterials = {}
for i = 1, 9 do
local materialKey = "rawmat" .. i
local quantityKey = "rawmat" .. i .. "qty"
local materialValue = args[materialKey]
if materialValue and materialValue ~= "" then
local quantityValue = tonumber(args[quantityKey]) or 1
table.insert(rawMaterials, { name = materialValue, quantity = quantityValue })
end
end
return rawMaterials
end
--This function takes a table containing the raw materials params received from the calling template.
--For each of the raw materials, a query will be executed to see if it has the property 'Uses item'.
--If it does, that means that the 'raw material' is actually an 'intermediate material' as it is itself created.
--The materials required to create this intermediate material will be retrieved and added to the rawMaterials table.
--This allows for a full recipe to be shown where only intermediate ingredients were provided.
function p._getTrueRawMaterials(argsMaterials)
local rawMaterials = {}
local intermediateMaterials = {}
local function _processMaterial(material, quantity)
if material then
local result = mw.smw.ask('[[:+]][[' .. material .. ']]|?Uses item|?Uses item_and_quantity')
if result and result[1] and result[1]["Uses item"] then
-- The item is an intermediate material, add it to intermediateMaterials
table.insert(intermediateMaterials, { ["name"] = material, ["quantity"] = quantity })
-- Add the raw materials used by this intermediate material to rawMaterials
local usesItems = result[1]["Uses item"]
local quantities = result[1]["Uses item and quantity"]
if type(usesItems) == "table" then
for index, usedItem in ipairs(usesItems) do
local pageName = usedItem:gsub("%[%[", ""):gsub("%]%]", ""):gsub("|.*", ""):gsub("^:", "")
local qty = 1
if quantities and type(quantities) == "table" then
local quantityString = quantities[index]
local _, q = quantityString:match("(.-),(%d+)")
qty = tonumber(q) or 1
end
_processMaterial(pageName, qty)
end
else
local pageName = usesItems:gsub("%[%[", ""):gsub("%]%]", ""):gsub("|.*", ""):gsub("^:", "")
local qty = 1
if quantities and type(quantities) == "string" then
local _, q = quantities:match("(.-),(%d+)")
qty = tonumber(q) or 1
end
_processMaterial(pageName, qty)
end
else
-- The item is a raw material, add it to rawMaterials
table.insert(rawMaterials, { ["name"] = material, ["quantity"] = quantity })
end
end
end
-- Iterate over the initial argsMaterials
for _, item in pairs(argsMaterials) do
if item["name"] then
_processMaterial(item["name"], item["quantity"])
end
end
return { rawMaterials = rawMaterials, intermediateMaterials = intermediateMaterials }
end
function p._reverseTable(t)
local reversed = {}
for i = #t, 1, -1 do
table.insert(reversed, t[i])
end
return reversed
end
return p