Шаблон:Scribunto clue

Материал из Поле цифровой дидактики
Подсказки Scribunto Lua
task realisation
Простейший модуль: вернуть фиксированный текст
local p = {}

function p.hello(frame)
  return "Это текст из Lua-модуля"
end

return p

На странице: {{#invoke:MyModule|hello}}

Вывести аргумент вызова: {{#invoke:...|echo|Привет}}
local p = {}

function p.echo(frame)
  local text = frame.args[1] or "пусто"
  return "Вы передали: " .. text
end

return p
Считать все именованные аргументы и собрать их в список
local p = {}

function p.listArgs(frame)
  local out = {}
  for name, value in pairs(frame.args) do
    table.insert(out, name .. "=" .. value)
  end
  table.sort(out)
  return "* " .. table.concat(out, "\n* ")
end

return p

Использование: {{#invoke:ArgsDemo|listArgs|a=1|b=2}}

Доступ к аргументам родительского шаблона (frame:getParent)
local p = {}

function p.parentArgs(frame)
  local parent = frame:getParent()
  local title = parent:getTitle()
  local arg1  = parent.args[1] or "(нет)"
  return "Шаблон: " .. title .. ", арг1=" .. arg1
end

return p
Простая статистика по числу страниц в категории
local p = {}

function p.catSize(frame)
  local cat = frame.args[1] or "Scratch studios"
  local stats = mw.site.stats.pagesInCategory(cat, "*")
  -- stats.all, stats.pages, stats.subcats, stats.files
  return string.format(
    "В категории '%s': страниц=%d, подкатегорий=%d, файлов=%d",
    cat, stats.pages, stats.subcats, stats.files
  )
end

return p

Вызов: {{#invoke:Stats|catSize|Scratch studios}}

Получить число страниц в пространстве имён (например, Модуль:)
local p = {}

function p.nsCount(frame)
  local ns = tonumber(frame.args[1]) or 0 -- 828 для Module:
  local count = mw.site.stats.pagesInNamespace(ns)
  return "Страниц в пространстве " .. ns .. ": " .. count
end

return p
Вывести список страниц категории (через #categorymembers)
local p = {}

function p.catPages(frame)
  local cat = frame.args[1] or "Scratch studios"
  local t = mw.smw.eval and mw.smw.eval
  local res = mw.smw.ask(
    string.format("[[Category:%s]]|?HasDescription|limit=5", cat)
  )
  if not res then return "Нет данных" end
  local out = {}
  for _, row in ipairs(res) do
    table.insert(out, "* [[" .. row.fulltext .. "]]")
  end
  return table.concat(out, "\n")
end

return p

(Пример для SMW-установки с `mw.smw.ask`)[page:1]

Получить внешние данные (CSV) через External Data и показать таблицу
local p = {}

function p.showFruits(frame)
  local data, err = mw.ext.externalData.getExternalData{
    url   = "https://discoursedb.org/wiki/Special:GetData/Fruits_data",
    data  = "name=Name,color=Color,shape=Shape",
    format = "CSV with header"
  }
  if err then return "Ошибка: " .. (err or "?") end

  local rows = {"{| class=\"wikitable\"\n! Name !! Color !! Shape"}
  for _, row in ipairs(data) do
    table.insert(rows,
      string.format("|-\n| %s || %s || %s",
        row.name or "", row.color or "", row.shape or "")
    )
  end
  table.insert(rows, "|}")
  return table.concat(rows, "\n")
end

return p
Визуализировать внешние данные в виде списка топ‑N
local p = {}

function p.topFruits(frame)
  local data, err = mw.ext.externalData.getExternalData{
    url = frame.args.url,
    data = "name=Name,count=Count",
    format = "CSV with header"
  }
  if err or not data then return "нет данных" end

  table.sort(data, function(a, b)
    return tonumber(a.count or 0) > tonumber(b.count or 0)
  end)

  local n = tonumber(frame.args.n) or 5
  local out = {}
  for i = 1, math.min(n, #data) do
    local row = data[i]
    table.insert(out,
      string.format("* %s — %s", row.name, row.count)
    )
  end
  return table.concat(out, "\n")
end

return p

Вызов: {{#invoke:Fruits|topFruits|url=...|n=5}}[web:40]

Сформировать mini‑инфобокс по данным страницы (через SMW)
local p = {}

function p.infobox(frame)
  local title = mw.title.getCurrentTitle().prefixedText
  local res = mw.smw.ask(string.format(
    "[[%s]]|?Fieldofknowledge|?Inventor|?launch year|limit=1",
    title
  ))
  if not res or not res[1] then return "" end
  local row = res[1]
  local t = {"{| class=\"wikitable\"\n! Свойство !! Значение"}
  local function add(label, v)
    if v then
      table.insert(t, "|-\n| " .. label .. " || " .. v)
    end
  end
  add("Поле знания", row.Fieldofknowledge)
  add("Автор", row.Inventor)
  add("Год запуска", row["launch year"])
  table.insert(t, "|}")
  return table.concat(t, "\n")
end

return p

(Для курсовых объектов на digida с полями SMW)[page:1]

Подсчитать, сколько HowTo‑страниц относится к данному Environment
local p = {}

function p.howtoCount(frame)
  local env = frame.args[1] or "NetLogo"
  local query = string.format(
    "[[Category:HowTo]][[Environment::%s]]|limit=500",
    env
  )
  local res = mw.smw.ask(query) or {}
  return string.format(
    "HowTo для среды %s: %d страниц",
    env, #res
  )
end

return p
Сгенерировать список ссылок на свежие учебные события (Curriculum/Event)
local p = {}

function p.events(frame)
  local res = mw.smw.ask(
    "[[Category:Event]]|?has start|?Description|sort=has start|order=desc|limit=5"
  ) or {}
  local out = {}
  for _, row in ipairs(res) do
    local title = row.fulltext
    local date  = row["has start"] or "?"
    local desc  = row.Description or ""
    table.insert(out,
      string.format("* '''[[%s]]''' (%s) — %s", title, date, desc)
    )
  end
  return table.concat(out, "\n")
end

return p
Объединить данные двух запросов SMW (пример «join» в Lua)
local p = {}

local function indexByTitle(rows)
  local idx = {}
  for _, r in ipairs(rows or {}) do
    idx[r.fulltext] = r
  end
  return idx
end

function p.mergeToolsAndModels(frame)
  local tools = mw.smw.ask("[[Category:DigitalTool]]|?Fieldofknowledge|limit=200") or {}
  local models = mw.smw.ask("[[Category:Model]]|?Fieldofknowledge|limit=200") or {}
  local toolsByField  = indexByTitle(tools)
  local modelsByField = indexByTitle(models)

  local out = {"{| class=\"wikitable\"\n! Объект !! Поле знания"}
  for title, row in pairs(toolsByField) do
    table.insert(out, "|-\n| [[ " .. title .. " ]] || " .. (row.Fieldofknowledge or ""))
  end
  for title, row in pairs(modelsByField) do
    table.insert(out, "|-\n| [[ " .. title .. " ]] || " .. (row.Fieldofknowledge or ""))
  end
  table.insert(out, "|}")
  return table.concat(out, "\n")
end

return p
Простейшая «оценка сложности» кода: посчитать строки в блоке
local p = {}

function p.countLines(frame)
  local code = frame.args[1] or ""
  local _, n = code:gsub("\n", "\n")
  return string.format("Строк кода: %d", n + 1)
end

return p

Вызов с nowiki‑блоком или аргументом, куда студент вставляет свой код.

Создать блок с предупреждением/подсветкой для учебного задания
local p = {}

function p.warning(frame)
  local text = frame.args[1] or "Внимательно прочитайте условие!"
  return string.format(
    '<div class="alert alert-warning">%s</div>',
    text
  )
end

return p
Сгенерировать таблицу распределения студентов по темам проектов
local p = {}

function p.topicStats(frame)
  local res = mw.smw.ask(
    "[[Category:StudentProject]]|?Topic|limit=500"
  ) or {}
  local counts = {}
  for _, row in ipairs(res) do
    local t = row.Topic or "Нет темы"
    counts[t] = (counts[t] or 0) + 1
  end
  local out = {"{| class=\"wikitable\"\n! Тема !! Проектов"}
  for topic, c in pairs(counts) do
    table.insert(out,
      string.format("|-\n| %s || %d", topic, c)
    )
  end
  table.insert(out, "|}")
  return table.concat(out, "\n")
end

return p