Editing Module:Recipe

Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.
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 1: Line 1:
local p = {}
local p = {}
local Card = require('Module:Card')
local Card = require('Module:Card')
local category = mw.html.create()


-- Arguments for template
--Arguments for template
local param = {
local param = {
   sCharArg = 'character',
   sCharArg = 'character',
  sKitchArg = 'kitchenware',
   sTypeArg = 'type',
   sTypeArg = 'type',
   sSortArg = 'sort',
   sSortArg = 'sort',
   sSortDelim = ';',
   sSortDelim = ';', --Needs to be pattern
   sSortDelim2 = '¤',
   sSortDelim2 = '¤',
   sTimeArg = 'time',
   sTimeArg = 'time',
Line 15: Line 14:
   sPage = 'page'
   sPage = 'page'
}
}
p.param = param
p.param = param


--------------------------------------------------------------------------------
function padLeft(str, amt)
-- Utility
return string.rep('0', amt - str:len()) .. str
--------------------------------------------------------------------------------
 
local function padLeft(str, amt)
  str = tostring(str or '')
  return string.rep('0', math.max(amt - str:len(), 0)) .. str
end
end


local function pluralize(sOut, plural)
function addRecipe(sAmt, sName)
  if plural then
   local cardNode = Card._main({
    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,
     name = sName,
     text = sAmt,
     text = sAmt,
     show_caption = '1'
     show_caption = '1',
  }
     mobile = 'bulleted'
 
   })
  if quality then
   category:wikitext('[[Category:Uses ', sName, '|', padLeft(sAmt:gsub('%D', ''), 10), ']]')
     cardArgs.quality = quality
   end
 
  local cardNode = Card._main(cardArgs)
 
   addUseCategory(
    category,
    sName,
    quality,
    padLeft(tostring(sAmt or ''):gsub('%D', ''), 10)
  )
 
   return cardNode
   return cardNode
end
end


local function addMiniCard(category, sName, sText, quality)
function pluralize(sOut,plural)
   local cardArgs = {
   if plural then
     name = sName,
     sOut = sOut .. 's'
    text = sText or '',
    show_caption = '1',
    mini = '1'
  }
 
  if quality then
    cardArgs.quality = quality
   end
   end
 
   return sOut
  local cardNode = Card._main(cardArgs)
 
  addUseCategory(category, sName)
 
   return cardNode
end
end


local function addYieldCard(pageTitle, sYield)
function p.main(frame)
   return Card._main({
   local args = require('Module:Arguments').getArgs(frame, {
     name = pageTitle,
     parentFirst = true,
     text = sYield,
     wrapper = { 'Template:Recipe' }
    show_caption = '1'
   })
   })
  return p._main(args,frame)
end
end


--------------------------------------------------------------------------------
function p._main(args,frame)
-- Header rendering
  local output = mw.html.create('div')
--------------------------------------------------------------------------------
    :addClass('new_genshin_recipe_container')
  if type(args[param.sTypeArg]) ~= 'string' then
    output:tag('span'):addClass('error'):wikitext('Recipe type error. Must include recipe type.')
  else
    local tArgsProcessed = {}
    local header = output:tag('div'):addClass('new_genshin_recipe_header')


local function renderHeader(args, output, category)
    --Type Parse
  local header = output:tag('div'):addClass('recipe-header')
    local sType = args[param.sTypeArg]
  local sType = args[param.sTypeArg]
    header:tag('span'):addClass('new_genshin_recipe_header_main')
      -- Mobile Icon
      :tag('span'):addClass('mobileHide'):wikitext('[[File:Icon_' .. sType .. '_Small.png|15x15px|link=' .. sType .. '|alt=Icon_' .. sType .. '_Small.png]]'):done()
      -- Desktop Icon
      :tag('span'):addClass('hidden'):wikitext('[[File:Icon_' .. sType .. '_Small.png|37x37px|link=' .. sType .. '|alt=Icon_' .. sType .. '_Small.png]]'):done()
      -- Text
      :tag('span'):addClass('new_genshin_recipe_header_text'):wikitext('[[' ..  sType .. ']]'):done()
    category:wikitext('[[Category:' .. sType .. ']]')


  header:tag('span'):addClass('recipe-header-main')
    --Time Parse
     :tag('span'):addClass('recipe-header-text'):wikitext('[[' .. sType .. ']]'):done()
     if type(args[param.sTimeArg]) == 'string' then
 
      local tTime = {}
  category:wikitext('[[Category:' .. sType .. ']]')
      local key = false
 
      local plural = false
  return header
      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
end
          table.insert(tTime,n1) --insert first value definitely
 
          if n1 ~= '1' then
local function renderTime(args, header)
              plural = true --generate plural
  if type(args[param.sTimeArg]) ~= 'string' then
          end
    return
          if d == 'd' then
  end
              table.insert(tTime, pluralize('day', plural))
 
              plural = false --consume plural
  local tTime = {}
              key = true
  local key = false
          end
  local plural = false
          if n2 ~= '' then
 
              table.insert(tTime, n2)
  for n1, d, n2, h, n3, m, n4, s in mw.ustring.gmatch(
              if n2 ~= '1' then
    args[param.sTimeArg],
                  plural = true --generate plural
    '(%d+)(d?)(%d*)(h?)(%d*)(m?)(%d*)(s?)'
              end
  ) do
          end
    table.insert(tTime, n1)
          if h == 'h' then
 
              table.insert(tTime,pluralize('hour', plural))
    if n1 ~= '1' then
              plural = false --consume plural
      plural = true
              key = true
    end
          end
 
          if n3 ~= '' then
    if d == 'd' then
              table.insert(tTime, n3)
      table.insert(tTime, pluralize('day', plural))
              if n3 ~= '1' then
      plural = false
                  plural = true --generate plural
      key = true
              end
    end
          end
 
          if m == 'm' then
    if n2 ~= '' then
              table.insert(tTime, pluralize('minute', plural))
      table.insert(tTime, n2)
              plural = false --consume plural
 
              key = true
      if n2 ~= '1' then
          end
        plural = true
          if n4 ~= '' then
              table.insert(tTime, n4)
              if n4 ~= '1' then
                  plural = true --generate plural
              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
       end
      header:tag('span'):addClass('new_genshin_recipe_header_sub')
        :tag('span'):addClass('mobileHide'):wikitext(' for '):done()
        :tag('span'):addClass('hidden'):wikitext('[[File:Icon Clock.png|24x24px|link=Time]]'):done()
        :tag('span'):addClass('new_genshin_recipe_header_text'):wikitext(sTime):done()
     end
     end
 
    --Character Parse
     if h == 'h' then
     if type(args[param.sCharArg]) == 'string' then
       table.insert(tTime, pluralize('hour', plural))
       local sCharName = args[param.sCharArg]
      plural = false
      header:tag('span'):addClass('new_genshin_recipe_header_sub')
      key = true
        :tag('span'):addClass('mobileHide'):wikitext(' with '):done()
        :tag('span'):addClass('hidden'):wikitext('[[File:' .. sCharName .. ' Icon.png|24x24px|link=' .. sCharName .. ']]'):done()
        :tag('span'):addClass('new_genshin_recipe_header_text'):wikitext('[[' .. sCharName .. ']]'):done()
     end
     end


    if n3 ~= '' then
local body = output:tag('div'):addClass('new_genshin_recipe_body')
      table.insert(tTime, n3)


       if n3 ~= '1' then
--Check if sSortDelim2 exists in sSortArg
         plural = true
if ((args[param.sSortArg] or ''):find(param.sSortDelim2) ~= nil) then
param.sSortDelim = param.sSortDelim2
end
    --Process Sort Parameter (Split by Delimiter)
    for sKey in string.gmatch(args[param.sSortArg] or '', '([^' .. param.sSortDelim .. ']+)') do
       if type(args[sKey]) ~= 'nil' then
         body:node(addRecipe(args[sKey], sKey))
        tArgsProcessed[sKey] = true
       end
       end
     end
     end


     if m == 'm' then
     --Process Rest of Unrestricted Parameters
      table.insert(tTime, pluralize('minute', plural))
    for sKey,sVal in pairs(args) do
       plural = false
       --Check if restricted parameter
       key = true
       local restricted = false
    end
       for _, keyParam in pairs(param) do
 
        if keyParam == sKey then
    if n4 ~= '' then
          restricted = true
       table.insert(tTime, n4)
        end
 
      if n4 ~= '1' then
        plural = true
       end
       end
    end
       --If not processed, and not a restricted parameter
 
       if tArgsProcessed[sKey] ~= true and not(restricted) then
    if s == 's' then
        body:node(addRecipe(sVal, sKey))
      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
     end
  end


  return maxIndex
     --Yield Parse
end
     if args[param.sYieldArg] ~= '0' then
 
    local sYield = args[param.sYieldArg] or '1'
local function getCookingIngredient(args, index)
    local pageTitle = args.page or mw.title.getCurrentTitle().text
  local prefix = 'item_' .. index
    local yieldCard = Card._main{
 
      name = pageTitle,
  local ingredient = {
      text = sYield,
     index = index,
      show_caption = '1',
     amount = args[prefix .. '_amount'] or nil,
    }
    quality = args[prefix .. '_quality'],
    body
    item = args[prefix],
      :tag('div'):addClass('new_genshin_recipe_body_icon')
    types = {},
        :wikitext('[[File:Icon_' .. sType .. '_Recipe.png|35x35px|link=' .. sType .. ']]'):done()
    options = {}
      :tag('div'):addClass('new_genshin_recipe_body_yield')
  }
        :node(yieldCard)
 
       
  if argExists(args, prefix .. '_type') then
    local itemText = require('Module:Item').main{
    table.insert(ingredient.types, args[prefix .. '_type'])
    [1] = pageTitle,
  end
    [2] = '15',
 
    x = sYield
  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
    body:done()
   end
   end
 
   output:node(require('Module:Namespace detect').main{["main"]=category})
   output:node(require('Module:Namespace detect').main({
    ["main"] = category
  }))
 
   return output
   return output
end
end


return p
return p
Please note that all contributions to The Petit Planet Wiki are considered to be released under the Creative Commons Attribution-ShareAlike (see Petit Planet Wiki:Copyrights for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource. Do not submit copyrighted work without permission!
Cancel Editing help (opens in new window)
Preview page with this template
Below are commonly used wikitext from MediaWiki:Edittools. Click on any to insert them in the edit box.
File Pages==Summary====Licensing=={{Fairuse}}{{File|}}
Dynamic Page List¦²«»²{¦}²«»«/»«!----»
Array in DPL¹^2{}^2^2{¹}^2
Parser Functions{{#if:||}}
{{#ifeq:|||}}
{{#expr:}}
{{#switch:||#default=}}
{{#replace:||}}
{{#titleparts:}}
{{#tag:|}}
Markup{{}}|[][[]][[Category:]]#REDIRECT [[]] [[Category:Redirect Pages]]<code></code><includeonly></includeonly><noinclude></noinclude><nowiki></nowiki><!----><br>§
Notices{{Stub|}}{{Stub Dialogue}}{{Upcoming}}{{Under Construction}}{{Placeholder|}}
Magic Words{{!}}{{formatnum:}}{{lc:}}{{uc:}}{{PAGENAME}}{{FULLPAGENAME}}{{ROOTPAGENAME}}{{BASEPAGENAME}}{{SUBPAGENAME}}{{DISPLAYTITLE:|noreplace}}__TOC____NOTOC____EXPECTUNUSEDCATEGORY____HIDDENCAT__
HTML Entities&mdash;&nbsp;&comma;&shy;