Module:Recipe: Difference between revisions
Appearance
No edit summary |
No edit summary |
||
| (16 intermediate revisions by 2 users not shown) | |||
| Line 6: | Line 6: | ||
local param = { | local param = { | ||
sCharArg = 'character', | sCharArg = 'character', | ||
sKitchArg = 'kitchenware', | |||
sTypeArg = 'type', | sTypeArg = 'type', | ||
sSortArg = 'sort', | sSortArg = 'sort', | ||
| Line 42: | Line 43: | ||
end | end | ||
local function addUseCategory(category, name, sort) | local function addUseCategory(category, name, quality, sort) | ||
if not name or tostring(name) == '' then | |||
return | |||
end | |||
if quality and tostring(quality) ~= '' then | |||
if sort and tostring(sort) ~= '' then | |||
category:wikitext('[[Category:Uses ', quality, '-Quality ', name, '|', sort, ']]') | |||
else | |||
category:wikitext('[[Category:Uses ', quality, '-Quality ', name, ']]') | |||
end | |||
return | |||
end | |||
if sort and tostring(sort) ~= '' then | |||
category:wikitext('[[Category:Uses ', name, '|', sort, ']]') | |||
else | |||
category:wikitext('[[Category:Uses ', name, ']]') | |||
end | |||
end | end | ||
local function getCurrentPageName(args) | local function getCurrentPageName(args) | ||
return args[param.sPage] or args.page or mw.title.getCurrentTitle().text | return args[param.sPage] or args.page or mw.title.getCurrentTitle().text | ||
end | |||
local function getQualityClass(quality) | |||
if not quality or tostring(quality) == '' then | |||
return nil | |||
end | |||
return 'card-quality-' .. normalizeText(quality) | |||
end | end | ||
| Line 66: | Line 85: | ||
name = sName, | name = sName, | ||
text = sAmt, | text = sAmt, | ||
show_caption = '1 | show_caption = '1' | ||
} | } | ||
| Line 79: | Line 97: | ||
category, | category, | ||
sName, | sName, | ||
quality, | |||
padLeft(tostring(sAmt or ''):gsub('%D', ''), 10) | padLeft(tostring(sAmt or ''):gsub('%D', ''), 10) | ||
) | ) | ||
| Line 90: | Line 109: | ||
text = sText or '', | text = sText or '', | ||
show_caption = '1', | show_caption = '1', | ||
mini = '1' | mini = '1' | ||
} | } | ||
| Line 118: | Line 136: | ||
local function renderHeader(args, output, category) | local function renderHeader(args, output, category) | ||
local header = output:tag('div'):addClass(' | 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('recipe-header-text'):wikitext('[[' .. sType .. ']]'):done() | |||
:tag('span'):addClass(' | |||
category:wikitext('[[Category:' .. sType .. ']]') | category:wikitext('[[Category:' .. sType .. ']]') | ||
| Line 209: | Line 224: | ||
end | end | ||
header:tag('span'):addClass(' | header:tag('span'):addClass('recipe-header-sub') | ||
:tag('span | :tag('span'):wikitext(' for '):done() | ||
:tag('span'):addClass('recipe-header-text'):wikitext(sTime):done() | |||
:tag('span'):addClass(' | |||
end | end | ||
| Line 222: | Line 236: | ||
local sCharName = args[param.sCharArg] | local sCharName = args[param.sCharArg] | ||
header:tag('span'):addClass(' | header:tag('span'):addClass('recipe-header-sub') | ||
:tag('span'):addClass(' | :tag('span'):wikitext('[[File:' .. sCharName .. ' Icon.png|24x24px|link=' .. sCharName .. ']]'):done() | ||
:tag('span'):addClass(' | :tag('span'):addClass('recipe-header-text'):wikitext('[[' .. sCharName .. ']]'):done() | ||
:tag('span'):addClass(' | end | ||
local function renderKitchenwareHeader(args, header) | |||
if type(args[param.sKitchArg]) ~= 'string' then | |||
return | |||
end | |||
local sKitchName = args[param.sKitchArg] | |||
header:tag('span'):addClass('recipe-header-sub') | |||
:tag('span'):wikitext('[[File:' .. sKitchName .. ' Icon.png|24x24px|link=' .. sKitchName .. ']]'):done() | |||
:tag('span'):addClass('recipe-header-text'):wikitext('[[' .. sKitchName .. ']]'):done() | |||
end | end | ||
| Line 247: | Line 272: | ||
end | end | ||
local sYield = args[param.sYieldArg] or | local sYield = args[param.sYieldArg] or nil | ||
local pageTitle = getCurrentPageName(args) | local pageTitle = getCurrentPageName(args) | ||
| Line 253: | Line 278: | ||
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) | ||
end | end | ||
| Line 267: | Line 292: | ||
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 | ||
| Line 275: | Line 300: | ||
end | end | ||
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 | ||
| Line 283: | Line 307: | ||
end | end | ||
for sKey, sVal in pairs(args) do | for sKey, sVal in pairs(args) do | ||
if tArgsProcessed[sKey] ~= true and not isRestrictedStandardParam(sKey) then | if tArgsProcessed[sKey] ~= true and not isRestrictedStandardParam(sKey) then | ||
| Line 321: | Line 344: | ||
local ingredient = { | local ingredient = { | ||
index = index, | index = index, | ||
amount = args[prefix .. '_amount'] or | amount = args[prefix .. '_amount'] or nil, | ||
quality = args[prefix .. '_quality'], | quality = args[prefix .. '_quality'], | ||
item = args[prefix], | item = args[prefix], | ||
| Line 328: | Line 351: | ||
} | } | ||
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 | ||
local typeIndex = 1 | local typeIndex = 1 | ||
| Line 344: | Line 362: | ||
end | end | ||
local optionIndex = 1 | local optionIndex = 1 | ||
| Line 366: | Line 381: | ||
end | end | ||
local function | -------------------------------------------------------------------------------- | ||
local | -- Cooking type split-card helpers | ||
-------------------------------------------------------------------------------- | |||
local function makeTypeIcon(typeName) | |||
return '[[File:' .. typeName .. ' Icon.png|74x74px|link=' .. typeName .. ']]' | |||
end | |||
local function joinTypeCaption(types) | |||
local out = {} | |||
for _, typeName in ipairs(types) do | |||
table.insert( | table.insert(out, '[[' .. typeName .. ']]') | ||
end | end | ||
local | return table.concat(out, ' / ') | ||
end | |||
local function renderCookingSplitTypeCard(category, body, ingredient) | |||
local qualityClass = getQualityClass(ingredient.quality or 'Gray') | |||
local container = body:tag('span') | |||
:addClass('card-container') | |||
:addClass('recipe-type-split-card') | |||
local wrapper = container:tag('span') | |||
:addClass('card-wrapper') | |||
local cardBody = wrapper:tag('span') | |||
:addClass('card-body') | |||
local imageContainer = cardBody:tag('span') | |||
:addClass('card-image-container') | |||
:addClass('recipe-type-split-image') | |||
imageContainer:tag('span') | |||
:addClass('recipe-type-split-half') | |||
:addClass('recipe-type-split-half-a') | |||
:wikitext(makeTypeIcon(ingredient.types[1])) | |||
:done() | |||
imageContainer:tag('span') | |||
:addClass('recipe-type-split-half') | |||
:addClass('recipe-type-split-half-b') | |||
:wikitext(makeTypeIcon(ingredient.types[2])) | |||
:done() | |||
if qualityClass then | |||
imageContainer:addClass(qualityClass) | |||
end | |||
if tostring(ingredient.amount or '') ~= '' then | |||
container:tag('span') | |||
:addClass('card-label') | |||
:wikitext(tostring(ingredient.amount or '1')) | |||
:done() | |||
end | end | ||
container:tag('span') | |||
:addClass('card-caption') | |||
:wikitext(joinTypeCaption(ingredient.types)) | |||
:done() | |||
for _, typeName in ipairs(ingredient.types) do | |||
addUseCategory(category, typeName) | |||
end | |||
end | end | ||
| Line 396: | Line 462: | ||
end | end | ||
local function | local function renderCookingTypeFallback(category, body, ingredient) | ||
local wrapper = body:tag('div') | local wrapper = body:tag('div') | ||
:addClass(' | :addClass('recipe-body-cooking-ingredient') | ||
:addClass(' | :addClass('recipe-body-cooking-type-cards') | ||
for _, typeName in ipairs(ingredient.types) do | for _, typeName in ipairs(ingredient.types) do | ||
| Line 408: | Line 474: | ||
ingredient.quality | ingredient.quality | ||
)) | )) | ||
end | |||
end | |||
local function renderCookingTypeCards(category, body, ingredient) | |||
if #ingredient.types == 2 then | |||
renderCookingSplitTypeCard(category, body, ingredient) | |||
else | |||
renderCookingTypeFallback(category, body, ingredient) | |||
end | end | ||
end | end | ||
| Line 413: | Line 487: | ||
local function renderCookingOptionCards(category, body, ingredient) | local function renderCookingOptionCards(category, body, ingredient) | ||
local wrapper = body:tag('div') | local wrapper = body:tag('div') | ||
:addClass(' | :addClass('recipe-body-cooking-ingredient') | ||
:addClass(' | :addClass('recipe-body-cooking-option-cards') | ||
for _, itemName in ipairs(ingredient.options) do | for _, itemName in ipairs(ingredient.options) do | ||
| Line 427: | Line 501: | ||
local function renderCookingIngredient(category, body, ingredient) | local function renderCookingIngredient(category, body, ingredient) | ||
if ingredient.item then | if ingredient.item then | ||
renderCookingSpecificItem(category, body, ingredient) | renderCookingSpecificItem(category, body, ingredient) | ||
| Line 434: | Line 506: | ||
end | end | ||
if #ingredient.options > 0 then | if #ingredient.options > 0 then | ||
renderCookingOptionCards(category, body, ingredient) | renderCookingOptionCards(category, body, ingredient) | ||
| Line 442: | Line 511: | ||
end | end | ||
if #ingredient.types > 0 then | if #ingredient.types > 0 then | ||
renderCookingTypeCards(category, body, ingredient) | renderCookingTypeCards(category, body, ingredient) | ||
return | return | ||
end | end | ||
end | end | ||
| Line 482: | Line 522: | ||
end | end | ||
local sYield = args[param.sYieldArg] or | local sYield = args[param.sYieldArg] or nil | ||
local pageTitle = getCurrentPageName(args) | local pageTitle = getCurrentPageName(args) | ||
local yieldCard = addYieldCard(pageTitle, sYield) | local yieldCard = addYieldCard(pageTitle, sYield) | ||
body | |||
:tag('div'):addClass('recipe-body-icon') | |||
:wikitext('➜'):done() | |||
:tag('div'):addClass('recipe-body-yield') | |||
:node(yieldCard) | |||
end | end | ||
| Line 499: | Line 539: | ||
renderTime(args, header) | renderTime(args, header) | ||
renderCharacter(args, header) | renderCharacter(args, header) | ||
renderKitchenwareHeader(args, header) | |||
local body = output:tag('div') | local body = output:tag('div') | ||
:addClass(' | :addClass('recipe-body') | ||
:addClass(' | :addClass('recipe-body-cooking') | ||
local foundIngredient = false | local foundIngredient = false | ||
| Line 542: | Line 583: | ||
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') | ||
local category = mw.html.create() | local category = mw.html.create() | ||
Latest revision as of 20:10, 13 May 2026
| Main | Documentation | Usage |
Lua module for {{Recipe}}.
local p = {}
local Card = require('Module:Card')
-- Arguments for template
local param = {
sCharArg = 'character',
sKitchArg = 'kitchenware',
sTypeArg = 'type',
sSortArg = 'sort',
sSortDelim = ';',
sSortDelim2 = '¤',
sTimeArg = 'time',
sYieldArg = 'yield',
sPage = 'page'
}
p.param = param
--------------------------------------------------------------------------------
-- Utility
--------------------------------------------------------------------------------
local function padLeft(str, amt)
str = tostring(str or '')
return string.rep('0', math.max(amt - str:len(), 0)) .. str
end
local function pluralize(sOut, plural)
if plural then
sOut = sOut .. 's'
end
return sOut
end
local function normalizeText(s)
return mw.ustring.lower(mw.text.trim(tostring(s or '')))
end
local function argExists(args, key)
return args[key] ~= nil and tostring(args[key]) ~= ''
end
local function addUseCategory(category, name, quality, sort)
if not name or tostring(name) == '' then
return
end
if quality and tostring(quality) ~= '' then
if sort and tostring(sort) ~= '' then
category:wikitext('[[Category:Uses ', quality, '-Quality ', name, '|', sort, ']]')
else
category:wikitext('[[Category:Uses ', quality, '-Quality ', name, ']]')
end
return
end
if sort and tostring(sort) ~= '' then
category:wikitext('[[Category:Uses ', name, '|', sort, ']]')
else
category:wikitext('[[Category:Uses ', name, ']]')
end
end
local function getCurrentPageName(args)
return args[param.sPage] or args.page or mw.title.getCurrentTitle().text
end
local function getQualityClass(quality)
if not quality or tostring(quality) == '' then
return nil
end
return 'card-quality-' .. normalizeText(quality)
end
--------------------------------------------------------------------------------
-- Card helpers
--------------------------------------------------------------------------------
local function addRecipeCard(category, sAmt, sName, quality)
local cardArgs = {
name = sName,
text = sAmt,
show_caption = '1'
}
if quality then
cardArgs.quality = quality
end
local cardNode = Card._main(cardArgs)
addUseCategory(
category,
sName,
quality,
padLeft(tostring(sAmt or ''):gsub('%D', ''), 10)
)
return cardNode
end
local function addMiniCard(category, sName, sText, quality)
local cardArgs = {
name = sName,
text = sText or '',
show_caption = '1',
mini = '1'
}
if quality then
cardArgs.quality = quality
end
local cardNode = Card._main(cardArgs)
addUseCategory(category, sName)
return cardNode
end
local function addYieldCard(pageTitle, sYield)
return Card._main({
name = pageTitle,
text = sYield,
show_caption = '1'
})
end
--------------------------------------------------------------------------------
-- Header rendering
--------------------------------------------------------------------------------
local function renderHeader(args, output, category)
local header = output:tag('div'):addClass('recipe-header')
local sType = args[param.sTypeArg]
header:tag('span'):addClass('recipe-header-main')
:tag('span'):addClass('recipe-header-text'):wikitext('[[' .. sType .. ']]'):done()
category:wikitext('[[Category:' .. sType .. ']]')
return header
end
local function renderTime(args, header)
if type(args[param.sTimeArg]) ~= 'string' then
return
end
local tTime = {}
local key = false
local plural = false
for n1, d, n2, h, n3, m, n4, s in mw.ustring.gmatch(
args[param.sTimeArg],
'(%d+)(d?)(%d*)(h?)(%d*)(m?)(%d*)(s?)'
) do
table.insert(tTime, n1)
if n1 ~= '1' then
plural = true
end
if d == 'd' then
table.insert(tTime, pluralize('day', plural))
plural = false
key = true
end
if n2 ~= '' then
table.insert(tTime, n2)
if n2 ~= '1' then
plural = true
end
end
if h == 'h' then
table.insert(tTime, pluralize('hour', plural))
plural = false
key = true
end
if n3 ~= '' then
table.insert(tTime, n3)
if n3 ~= '1' then
plural = true
end
end
if m == 'm' then
table.insert(tTime, pluralize('minute', plural))
plural = false
key = true
end
if n4 ~= '' then
table.insert(tTime, n4)
if n4 ~= '1' then
plural = true
end
end
if s == 's' then
table.insert(tTime, pluralize('second', plural))
key = true
end
end
if not key then
table.insert(tTime, pluralize('minute', plural))
end
local sTime = ''
for _, each in ipairs(tTime) do
sTime = sTime .. each .. ' '
end
header:tag('span'):addClass('recipe-header-sub')
:tag('span'):wikitext(' for '):done()
:tag('span'):addClass('recipe-header-text'):wikitext(sTime):done()
end
local function renderCharacter(args, header)
if type(args[param.sCharArg]) ~= 'string' then
return
end
local sCharName = args[param.sCharArg]
header:tag('span'):addClass('recipe-header-sub')
:tag('span'):wikitext('[[File:' .. sCharName .. ' Icon.png|24x24px|link=' .. sCharName .. ']]'):done()
:tag('span'):addClass('recipe-header-text'):wikitext('[[' .. sCharName .. ']]'):done()
end
local function renderKitchenwareHeader(args, header)
if type(args[param.sKitchArg]) ~= 'string' then
return
end
local sKitchName = args[param.sKitchArg]
header:tag('span'):addClass('recipe-header-sub')
:tag('span'):wikitext('[[File:' .. sKitchName .. ' Icon.png|24x24px|link=' .. sKitchName .. ']]'):done()
:tag('span'):addClass('recipe-header-text'):wikitext('[[' .. sKitchName .. ']]'):done()
end
--------------------------------------------------------------------------------
-- Standard recipe rendering
--------------------------------------------------------------------------------
local function isRestrictedStandardParam(sKey)
for _, keyParam in pairs(param) do
if keyParam == sKey then
return true
end
end
return false
end
local function renderStandardYield(args, body)
if args[param.sYieldArg] == '0' then
return
end
local sYield = args[param.sYieldArg] or nil
local pageTitle = getCurrentPageName(args)
local yieldCard = addYieldCard(pageTitle, sYield)
body
:tag('div'):addClass('recipe-body-icon')
:wikitext('➜'):done()
:tag('div'):addClass('recipe-body-yield')
:node(yieldCard)
end
local function renderStandardRecipe(args, frame, output, category)
local tArgsProcessed = {}
local header = renderHeader(args, output, category)
renderTime(args, header)
renderCharacter(args, header)
local body = output:tag('div'):addClass('recipe-body')
local sSortDelim = param.sSortDelim
if ((args[param.sSortArg] or ''):find(param.sSortDelim2) ~= nil) then
sSortDelim = param.sSortDelim2
end
for sKey in string.gmatch(args[param.sSortArg] or '', '([^' .. sSortDelim .. ']+)') do
if type(args[sKey]) ~= 'nil' then
body:node(addRecipeCard(category, args[sKey], sKey))
tArgsProcessed[sKey] = true
end
end
for sKey, sVal in pairs(args) do
if tArgsProcessed[sKey] ~= true and not isRestrictedStandardParam(sKey) then
body:node(addRecipeCard(category, sVal, sKey))
end
end
renderStandardYield(args, body)
body:done()
end
--------------------------------------------------------------------------------
-- Cooking parsing
--------------------------------------------------------------------------------
local function getMaxCookingItemIndex(args)
local maxIndex = 0
for key, _ in pairs(args) do
local index = tostring(key):match('^item_(%d+)')
if index then
index = tonumber(index)
if index and index > maxIndex then
maxIndex = index
end
end
end
return maxIndex
end
local function getCookingIngredient(args, index)
local prefix = 'item_' .. index
local ingredient = {
index = index,
amount = args[prefix .. '_amount'] or nil,
quality = args[prefix .. '_quality'],
item = args[prefix],
types = {},
options = {}
}
if argExists(args, prefix .. '_type') then
table.insert(ingredient.types, args[prefix .. '_type'])
end
local typeIndex = 1
while argExists(args, prefix .. '_type_' .. typeIndex) do
table.insert(ingredient.types, args[prefix .. '_type_' .. typeIndex])
typeIndex = typeIndex + 1
end
local optionIndex = 1
while argExists(args, prefix .. '_option_' .. optionIndex) do
table.insert(ingredient.options, args[prefix .. '_option_' .. optionIndex])
optionIndex = optionIndex + 1
end
local hasIngredient =
argExists(args, prefix)
or #ingredient.types > 0
or #ingredient.options > 0
if not hasIngredient then
return nil
end
return ingredient
end
--------------------------------------------------------------------------------
-- Cooking type split-card helpers
--------------------------------------------------------------------------------
local function makeTypeIcon(typeName)
return '[[File:' .. typeName .. ' Icon.png|74x74px|link=' .. typeName .. ']]'
end
local function joinTypeCaption(types)
local out = {}
for _, typeName in ipairs(types) do
table.insert(out, '[[' .. typeName .. ']]')
end
return table.concat(out, ' / ')
end
local function renderCookingSplitTypeCard(category, body, ingredient)
local qualityClass = getQualityClass(ingredient.quality or 'Gray')
local container = body:tag('span')
:addClass('card-container')
:addClass('recipe-type-split-card')
local wrapper = container:tag('span')
:addClass('card-wrapper')
local cardBody = wrapper:tag('span')
:addClass('card-body')
local imageContainer = cardBody:tag('span')
:addClass('card-image-container')
:addClass('recipe-type-split-image')
imageContainer:tag('span')
:addClass('recipe-type-split-half')
:addClass('recipe-type-split-half-a')
:wikitext(makeTypeIcon(ingredient.types[1]))
:done()
imageContainer:tag('span')
:addClass('recipe-type-split-half')
:addClass('recipe-type-split-half-b')
:wikitext(makeTypeIcon(ingredient.types[2]))
:done()
if qualityClass then
imageContainer:addClass(qualityClass)
end
if tostring(ingredient.amount or '') ~= '' then
container:tag('span')
:addClass('card-label')
:wikitext(tostring(ingredient.amount or '1'))
:done()
end
container:tag('span')
:addClass('card-caption')
:wikitext(joinTypeCaption(ingredient.types))
:done()
for _, typeName in ipairs(ingredient.types) do
addUseCategory(category, typeName)
end
end
--------------------------------------------------------------------------------
-- Cooking display
--------------------------------------------------------------------------------
local function renderCookingSpecificItem(category, body, ingredient)
body:node(addRecipeCard(
category,
ingredient.amount,
ingredient.item,
ingredient.quality
))
end
local function renderCookingTypeFallback(category, body, ingredient)
local wrapper = body:tag('div')
:addClass('recipe-body-cooking-ingredient')
:addClass('recipe-body-cooking-type-cards')
for _, typeName in ipairs(ingredient.types) do
wrapper:node(addMiniCard(
category,
typeName,
ingredient.amount,
ingredient.quality
))
end
end
local function renderCookingTypeCards(category, body, ingredient)
if #ingredient.types == 2 then
renderCookingSplitTypeCard(category, body, ingredient)
else
renderCookingTypeFallback(category, body, ingredient)
end
end
local function renderCookingOptionCards(category, body, ingredient)
local wrapper = body:tag('div')
:addClass('recipe-body-cooking-ingredient')
:addClass('recipe-body-cooking-option-cards')
for _, itemName in ipairs(ingredient.options) do
wrapper:node(addMiniCard(
category,
itemName,
ingredient.amount,
ingredient.quality
))
end
end
local function renderCookingIngredient(category, body, ingredient)
if ingredient.item then
renderCookingSpecificItem(category, body, ingredient)
return
end
if #ingredient.options > 0 then
renderCookingOptionCards(category, body, ingredient)
return
end
if #ingredient.types > 0 then
renderCookingTypeCards(category, body, ingredient)
return
end
end
local function renderCookingYield(args, category, body)
if args[param.sYieldArg] == '0' then
return
end
local sYield = args[param.sYieldArg] or nil
local pageTitle = getCurrentPageName(args)
local yieldCard = addYieldCard(pageTitle, sYield)
body
:tag('div'):addClass('recipe-body-icon')
:wikitext('➜'):done()
:tag('div'):addClass('recipe-body-yield')
:node(yieldCard)
end
local function renderCookingRecipe(args, frame, output, category)
local header = renderHeader(args, output, category)
renderTime(args, header)
renderCharacter(args, header)
renderKitchenwareHeader(args, header)
local body = output:tag('div')
:addClass('recipe-body')
:addClass('recipe-body-cooking')
local foundIngredient = false
local maxIndex = getMaxCookingItemIndex(args)
for index = 1, maxIndex do
local ingredient = getCookingIngredient(args, index)
if ingredient then
foundIngredient = true
renderCookingIngredient(category, body, ingredient)
end
end
if not foundIngredient then
body:tag('span')
:addClass('error')
:wikitext('Cooking recipe error. No cooking ingredients found.')
end
renderCookingYield(args, category, body)
body:done()
end
--------------------------------------------------------------------------------
-- Entry points
--------------------------------------------------------------------------------
function p.main(frame)
local args = require('Module:Arguments').getArgs(frame, {
parentFirst = true,
wrapper = { 'Template:Recipe' }
})
return p._main(args, frame)
end
function p._main(args, frame)
local output = mw.html.create('div')
:addClass('recipe-container')
local category = mw.html.create()
if type(args[param.sTypeArg]) ~= 'string' then
output:tag('span')
:addClass('error')
:wikitext('Recipe type error. Must include recipe type.')
else
local sType = args[param.sTypeArg]
if normalizeText(sType) == 'cooking' then
renderCookingRecipe(args, frame, output, category)
else
renderStandardRecipe(args, frame, output, category)
end
end
output:node(require('Module:Namespace detect').main({
["main"] = category
}))
return output
end
return p