Editing Module:Recipe
The edit can be undone.
Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.
| Latest revision | Your text | ||
| Line 6: | Line 6: | ||
local param = { | local param = { | ||
sCharArg = 'character', | sCharArg = 'character', | ||
sTypeArg = 'type', | sTypeArg = 'type', | ||
sSortArg = 'sort', | sSortArg = 'sort', | ||
sSortDelim = ';', | sSortDelim = ';', -- Needs to be pattern-safe for current usage | ||
sSortDelim2 = '¤', | sSortDelim2 = '¤', | ||
sTimeArg = 'time', | sTimeArg = 'time', | ||
| Line 17: | Line 16: | ||
p.param = param | p.param = param | ||
local function padLeft(str, amt) | local function padLeft(str, amt) | ||
| Line 31: | Line 26: | ||
sOut = sOut .. 's' | sOut = sOut .. 's' | ||
end | end | ||
return sOut | return sOut | ||
end | end | ||
local function | local function normalizeType(s) | ||
return mw.ustring.lower(mw.text.trim(tostring(s or ''))) | return mw.ustring.lower(mw.text.trim(tostring(s or ''))) | ||
end | end | ||
| Line 43: | Line 37: | ||
end | end | ||
local function | local function addRecipe(category, sAmt, sName) | ||
local cardNode = Card._main({ | |||
local | |||
name = sName, | name = sName, | ||
text = sAmt, | text = sAmt, | ||
show_caption = '1' | show_caption = '1', | ||
mobile = 'bulleted' | |||
}) | |||
category:wikitext( | |||
'[[Category:Uses ', | |||
sName, | sName, | ||
'|', | |||
padLeft(tostring(sAmt or ''):gsub('%D', ''), 10) | padLeft(tostring(sAmt or ''):gsub('%D', ''), 10), | ||
']]' | |||
) | ) | ||
| Line 104: | Line 56: | ||
end | end | ||
local function | local function addSimpleCard(sName, sText) | ||
return Card._main({ | |||
name = sName, | name = sName, | ||
text = sText | text = sText, | ||
show_caption = '1', | show_caption = '1', | ||
mobile = 'bulleted' | |||
}) | }) | ||
end | end | ||
local function renderHeader(args, output, category) | |||
local header = output:tag('div'):addClass('recipe_header') | |||
local sType = args[param.sTypeArg] | local sType = args[param.sTypeArg] | ||
header:tag('span'):addClass(' | header:tag('span'):addClass('recipe_header_main') | ||
:tag('span'):addClass(' | -- Mobile Icon/Text, preserved from original | ||
:tag('span'):addClass('mobileHide'):wikitext('<big>' .. sType .. '</big>'):done() | |||
-- Desktop Icon/Text, preserved from original | |||
:tag('span'):addClass('mobileHide'):wikitext('<big>' .. sType .. '</big>'):done() | |||
-- Text | |||
:tag('span'):addClass('recipe_header_text'):wikitext('[[' .. sType .. ']]'):done() | |||
category:wikitext('[[Category:' .. sType .. ']]') | category:wikitext('[[Category:' .. sType .. ']]') | ||
| Line 224: | Line 160: | ||
end | end | ||
header:tag('span'):addClass(' | header:tag('span'):addClass('recipe_header_sub') | ||
:tag('span'):wikitext(' for '):done() | :tag('span'):addClass('mobileHide'):wikitext(' for '):done() | ||
:tag('span'):addClass(' | :tag('span'):addClass('hidden'):wikitext(' for '):done() | ||
:tag('span'):addClass('recipe_header_text'):wikitext(sTime):done() | |||
end | end | ||
| Line 236: | Line 173: | ||
local sCharName = args[param.sCharArg] | local sCharName = args[param.sCharArg] | ||
header:tag('span'):addClass(' | header:tag('span'):addClass('recipe_header_sub') | ||
:tag('span'):addClass('mobileHide'):wikitext(' with '):done() | |||
:tag('span'):addClass(' | :tag('span'):addClass('hidden'):wikitext('[[File:' .. sCharName .. ' Icon.png|24x24px|link=' .. sCharName .. ']]'):done() | ||
:tag('span'):addClass('recipe_header_text'):wikitext('[[' .. sCharName .. ']]'):done() | |||
:tag('span'):addClass(' | |||
end | end | ||
local function renderYield(args, body) | |||
local function | |||
if args[param.sYieldArg] == '0' then | if args[param.sYieldArg] == '0' then | ||
return | return | ||
end | end | ||
local sYield = args[param.sYieldArg] or | local sYield = args[param.sYieldArg] or '1' | ||
local pageTitle = | local pageTitle = args.page or mw.title.getCurrentTitle().text | ||
local yieldCard = | local yieldCard = Card._main({ | ||
name = pageTitle, | |||
text = sYield, | |||
show_caption = '1', | |||
}) | |||
body | body | ||
:tag('div'):addClass(' | :tag('div'):addClass('recipe_body_icon') | ||
:wikitext('➜'):done() | :wikitext('➜'):done() | ||
:tag('div'):addClass(' | :tag('div'):addClass('recipe_body_yield') | ||
:node(yieldCard) | :node(yieldCard) | ||
-- Preserved from original, though unused. | |||
local itemText = require('Module:Item').main{ | |||
[1] = pageTitle, | |||
[2] = '15', | |||
x = sYield | |||
} | |||
end | end | ||
-------------------------------------------------------------------------------- | |||
-- Standard, non-cooking recipe rendering | |||
-------------------------------------------------------------------------------- | |||
local function renderStandardRecipe(args, frame, output, category) | local function renderStandardRecipe(args, frame, output, category) | ||
| Line 292: | Line 219: | ||
renderCharacter(args, header) | renderCharacter(args, header) | ||
local body = output:tag('div'):addClass(' | local body = output:tag('div'):addClass('recipe_body') | ||
local sSortDelim = param.sSortDelim | local sSortDelim = param.sSortDelim | ||
-- Check if sSortDelim2 exists in sSortArg. | |||
if ((args[param.sSortArg] or ''):find(param.sSortDelim2) ~= nil) then | if ((args[param.sSortArg] or ''):find(param.sSortDelim2) ~= nil) then | ||
sSortDelim = param.sSortDelim2 | sSortDelim = param.sSortDelim2 | ||
end | end | ||
-- Process Sort Parameter, split by delimiter. | |||
for sKey in string.gmatch(args[param.sSortArg] or '', '([^' .. sSortDelim .. ']+)') do | for sKey in string.gmatch(args[param.sSortArg] or '', '([^' .. sSortDelim .. ']+)') do | ||
if type(args[sKey]) ~= 'nil' then | if type(args[sKey]) ~= 'nil' then | ||
body:node( | body:node(addRecipe(category, args[sKey], sKey)) | ||
tArgsProcessed[sKey] = true | tArgsProcessed[sKey] = true | ||
end | end | ||
end | end | ||
-- Process rest of unrestricted parameters. | |||
for sKey, sVal in pairs(args) do | for sKey, sVal in pairs(args) do | ||
if tArgsProcessed[sKey] ~= true and not | local restricted = false | ||
body:node( | |||
for _, keyParam in pairs(param) do | |||
if keyParam == sKey then | |||
restricted = true | |||
end | |||
end | |||
if tArgsProcessed[sKey] ~= true and not restricted then | |||
body:node(addRecipe(category, sVal, sKey)) | |||
end | end | ||
end | end | ||
renderYield(args, body) | |||
body:done() | body:done() | ||
| Line 319: | Line 257: | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
-- Cooking | -- Cooking recipe rendering | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
local function getCookingIngredient(args, index) | local function getCookingIngredient(args, index) | ||
| Line 344: | Line 265: | ||
local ingredient = { | local ingredient = { | ||
index = index, | index = index, | ||
amount = args[prefix .. '_amount'] or | amount = args[prefix .. '_amount'] or '1', | ||
quality = args[prefix .. '_quality'], | quality = args[prefix .. '_quality'], | ||
item = args[prefix], | item = args[prefix], | ||
| Line 351: | Line 272: | ||
} | } | ||
-- Single type: | |||
-- |item_1_type = Fish | |||
if argExists(args, prefix .. '_type') then | if argExists(args, prefix .. '_type') then | ||
table.insert(ingredient.types, args[prefix .. '_type']) | table.insert(ingredient.types, args[prefix .. '_type']) | ||
end | end | ||
-- Multiple types: | |||
-- |item_1_type_1 = Freshwater Fish | |||
-- |item_1_type_2 = Saltwater Fish | |||
local typeIndex = 1 | local typeIndex = 1 | ||
| Line 362: | Line 288: | ||
end | end | ||
-- Multiple accepted specific items: | |||
-- |item_1_option_1 = Rice | |||
-- |item_1_option_2 = Wheat | |||
local optionIndex = 1 | local optionIndex = 1 | ||
| Line 370: | Line 299: | ||
local hasIngredient = | local hasIngredient = | ||
ingredient.item ~= nil | |||
or #ingredient.types > 0 | or #ingredient.types > 0 | ||
or #ingredient.options > 0 | or #ingredient.options > 0 | ||
| Line 381: | Line 310: | ||
end | end | ||
local function getKitchenware(args) | |||
local kitchenware = {} | |||
-- Single kitchenware: | |||
-- |kitchenware = Cooking Pot | |||
end | if argExists(args, 'kitchenware') then | ||
table.insert(kitchenware, args.kitchenware) | |||
end | |||
-- Multiple kitchenware: | |||
local | -- |kitchenware_1 = Cooking Pot | ||
-- |kitchenware_2 = Frying Pan | |||
local index = 1 | |||
while argExists(args, 'kitchenware_' .. index) do | |||
table.insert( | table.insert(kitchenware, args['kitchenware_' .. index]) | ||
index = index + 1 | |||
end | end | ||
return | return kitchenware | ||
end | end | ||
local function | local function renderCookingTypeRequirement(category, typeBox, amountText, types) | ||
local | if #types == 1 then | ||
local typeName = types[1] | |||
typeBox:tag('div') | |||
:addClass('recipe_body_cooking_requirement') | |||
:wikitext(amountText .. ' of [[:Category:' .. typeName .. '|' .. typeName .. ']]') | |||
category:wikitext('[[Category:Uses ', typeName, ']]') | |||
return | |||
end | |||
typeBox:tag('div') | |||
:addClass(' | :addClass('recipe_body_cooking_requirement') | ||
: | :wikitext(amountText .. ' of any of:') | ||
for _, typeName in ipairs(types) do | |||
: | typeBox:tag('div') | ||
:addClass('recipe_body_cooking_type') | |||
:wikitext('[[:Category:' .. typeName .. '|' .. typeName .. ']]') | |||
category:wikitext('[[Category:Uses ', typeName, ']]') | |||
end | end | ||
end | end | ||
local function renderCookingIngredient(category, body, ingredient) | |||
local function | |||
local wrapper = body:tag('div') | local wrapper = body:tag('div') | ||
:addClass(' | :addClass('recipe_body_cooking_ingredient') | ||
local amountText = tostring(ingredient.amount or '1') | |||
if ingredient.quality then | |||
if | amountText = amountText .. ' ' .. ingredient.quality | ||
end | end | ||
-- Specific item: | |||
-- |item_1 = Rice | |||
if ingredient.item then | if ingredient.item then | ||
wrapper:node(addRecipe(category, amountText, ingredient.item)) | |||
return | return | ||
end | end | ||
-- Multiple specific item options: | |||
-- |item_1_option_1 = Rice | |||
-- |item_1_option_2 = Wheat | |||
if #ingredient.options > 0 then | if #ingredient.options > 0 then | ||
local optionBox = wrapper:tag('div') | |||
:addClass('recipe_body_cooking_options') | |||
optionBox:tag('div') | |||
:addClass('recipe_body_cooking_requirement') | |||
:wikitext(amountText .. ' of any of:') | |||
for _, itemName in ipairs(ingredient.options) do | |||
optionBox:node(addRecipe(category, '', itemName)) | |||
end | |||
return | return | ||
end | end | ||
-- Type-based ingredient: | |||
-- |item_1_type = Fish | |||
-- or: | |||
-- |item_1_type_1 = Freshwater Fish | |||
-- |item_1_type_2 = Saltwater Fish | |||
if #ingredient.types > 0 then | if #ingredient.types > 0 then | ||
local typeBox = wrapper:tag('div') | |||
:addClass('recipe_body_cooking_types') | |||
renderCookingTypeRequirement(category, typeBox, amountText, ingredient.types) | |||
return | return | ||
end | end | ||
end | end | ||
local function | local function renderKitchenware(category, body, args) | ||
if | local kitchenware = getKitchenware(args) | ||
if #kitchenware == 0 then | |||
return | return | ||
end | end | ||
local | local wrapper = body:tag('div') | ||
:addClass('recipe_body_kitchenware') | |||
wrapper:tag('div') | |||
:addClass('recipe_body_kitchenware_label') | |||
:wikitext('Kitchenware') | |||
for _, itemName in ipairs(kitchenware) do | |||
: | wrapper:node(addSimpleCard(itemName, '')) | ||
category:wikitext('[[Category:Uses ', itemName, ']]') | |||
end | |||
end | end | ||
| Line 539: | Line 433: | ||
renderTime(args, header) | renderTime(args, header) | ||
renderCharacter(args, header) | renderCharacter(args, header) | ||
local body = output:tag('div') | local body = output:tag('div') | ||
:addClass(' | :addClass('recipe_body') | ||
:addClass(' | :addClass('recipe_body_cooking') | ||
local ingredientIndex = 1 | |||
local foundIngredient = false | local foundIngredient = false | ||
while true do | |||
local ingredient = getCookingIngredient(args, | local ingredient = getCookingIngredient(args, ingredientIndex) | ||
if ingredient then | if not ingredient then | ||
break | |||
end | end | ||
foundIngredient = true | |||
renderCookingIngredient(category, body, ingredient) | |||
ingredientIndex = ingredientIndex + 1 | |||
end | end | ||
| Line 563: | Line 460: | ||
end | end | ||
renderKitchenware(category, body, args) | |||
renderYield(args, body) | |||
body:done() | body:done() | ||
| Line 583: | Line 482: | ||
function p._main(args, frame) | function p._main(args, frame) | ||
local output = mw.html.create('div') | local output = mw.html.create('div') | ||
:addClass(' | :addClass('recipe_container') | ||
-- Important: category must be local to this render. | |||
-- Do not keep it as a module-level variable. | |||
local category = mw.html.create() | local category = mw.html.create() | ||
| Line 594: | Line 495: | ||
local sType = args[param.sTypeArg] | local sType = args[param.sTypeArg] | ||
if | if normalizeType(sType) == 'cooking' then | ||
renderCookingRecipe(args, frame, output, category) | renderCookingRecipe(args, frame, output, category) | ||
else | else | ||