Scribunto: различия между версиями

Материал из Поле цифровой дидактики
Нет описания правки
Метка: ручная отмена
Нет описания правки
Строка 14: Строка 14:
}}
}}
Примеры использования в модулях
Примеры использования в модулях
* [[:Категория:LuaLearning]] }}


{{#ask: [[Категория:LuaLearning]] }}
 
{{Шаблон:Scribunto clue}}

Версия от 08:11, 23 апреля 2026

Краткое описание инструмента Расширение Scribunto добавляет к MediaWiki возможность подключать модуль Lua (Module:...) и вызывать его через шаблоны, превращая статьи в «полуинтерактивные» объекты с динамическими таблицами, визуализациями и вычислениями.
Возможности Lua через Scribunto применяется повсеместно в Википедии для сложных шаблонов (инфобоксы, навигационные панели, автоматические вычисления), что демонстрирует устойчивость и масштабируемость такого подхода.

Встроенность Lua в MediaWiki через расширение Scribunto позволяет использовать один и тот же язык и как «язык курса программирования», и как средство «оживления» учебных wiki‑страниц, формируя у студентов представление о программировании как об инструменте конструирования.

Трудности использования Отдельное пространство MediaWiki, в котором студенты пишут не текст, но код
Область знаний Информатика, Game design
Область применения программирование
Поясняющее видео
Веб-сайт https://github.com/wikimedia/mediawiki-extensions-Scribunto
Пользователи Учащиеся, Преподаватели, Исследователи
Используется для создания (проведения) генерация контента
Разработчик
Сообщество вокруг средства
Лицензия
Год первого релиза
Совместное сетевое использование Да
Какой язык основной English
Есть ли поддержка Искусственным Интеллектом Нет

Примеры использования в модулях


Подсказки 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