Jump to content
Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
If you make an edit, a temporary account will be created for you.

Editing Module:Sandbox/Stevium

From The Petit Planet Wiki
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 getArgs = require('Module:Arguments').getArgs


function p.show(frame)
local Card = require('Module:Card')
local args = getArgs(frame)
 
local bucket_name = mw.text.trim(args[1] or '')
-- Arguments for template
local select_field = mw.text.trim(args[2] or '')
local param = {
  sCharArg = 'character',
local b = mw.bucket(bucket_name).select(select_field)
  sKitchArg = 'kitchenware',
  sTypeArg = 'type',
for k, v in pairs(args) do
  sSortArg = 'sort',
if k ~= 1 and k ~= 2 then
  sSortDelim = ';',
b.where(k, v)
  sSortDelim2 = '¤',
end
  sTimeArg = 'time',
end
  sYieldArg = 'yield',
  sPage = 'page'
return b.run()
}
 
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, sort)
  if not name or tostring(name) == '' then
    return
  end
 
  if 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',
    mobile = 'bulleted'
  }
 
  if quality then
    cardArgs.quality = quality
  end
 
  local cardNode = Card._main(cardArgs)
 
  addUseCategory(
    category,
    sName,
    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',
    mobile = 'bulleted',
    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('mobileHide'):wikitext('<big>' .. sType .. '</big>'):done()
    :tag('span'):addClass('mobileHide'):wikitext('<big>' .. sType .. '</big>'):done()
    :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'):addClass('mobileHide'):wikitext(' for '):done()
    :tag('span'):addClass('hidden'):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'):addClass('mobileHide'):wikitext(' with '):done()
    :tag('span'):addClass('hidden'):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'):addClass('mobileHide'):wikitext(' with '):done()
    :tag('span'):addClass('hidden'):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 '1'
  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 '1',
    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)
 
  local container = body:tag('span')
    :addClass('card-container')
    :addClass('recipe-type-split-card')
 
  if qualityClass then
    container:addClass(qualityClass)
  end
 
  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 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 '1'
  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
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;