Шаблон:Lua clue

Материал из Поле цифровой дидактики
Lua в MediaWiki: аффордансы и решения (Scribunto + SMW)
Аффорданс / проблема Решение (фрагмент кода Lua)

1. Принять параметры из вики-страницы

Студент хочет передать аргументы в модуль через {{#invoke:}} и получить что-то назад.

local p = {}
function p.hello(frame)
  local name = frame.args.name or "мир"
  return "Привет, " .. name .. "!"
end
return p

Вызов: {{#invoke:MyModule|hello|name=Иван}}

2. Построить wikitable из аргументов

Вывести список данных в виде красивой таблицы прямо на странице.

local p = {}
function p.table(frame)
  local out = '{| class="wikitable"\n! №\n! Значение\n'
  local i = 1
  while frame.args[i] do
    out = out .. "|-\n| " .. i .. " || " .. frame.args[i] .. "\n"
    i = i + 1
  end
  return out .. "|}"
end
return p

Вызов: {{#invoke:MyModule|table|Lua|SMW|NetLogo}}

3. Прочитать содержимое wiki-страницы

Нужно проанализировать текст другой страницы — посчитать слова, ссылки, заголовки.

local p = {}
function p.words(frame)
  local titleObj = mw.title.new(frame.args.title or "")
  if not titleObj then return "Страница не найдена" end
  local content = titleObj:getContent()
  if not content then return "Нет содержимого" end
  local n = 0
  for _ in mw.ustring.gmatch(content, "%S+") do n = n + 1 end
  return "Слов в исходном тексте: " .. n
end
return p

Вызов: {{#invoke:MyModule|words|title=Lua/Tutorial}}

4. Получить SMW-свойство страницы

Нужно программно прочитать значение семантического свойства, записанного на странице.

local p = {}
function p.getprop(frame)
  if not mw.smw then return "mw.smw недоступен" end
  local val = mw.smw.getPropertyValue(
    frame.args.property or "Modification date"
  )
  if val == nil then return "(нет значения)" end
  return tostring(val)
end
return p

Вызов: {{#invoke:MyModule|getprop|property=Дата создания}}

5. Выполнить #ask-запрос из Lua

Нужно получить список страниц по SMW-запросу и обработать результаты программно.

local p = {}
function p.ask(frame)
  if not mw.smw then return "mw.smw недоступен" end
  local results = mw.smw.ask("[[Категория:Модули]]|?#-=page|limit=5")
  if not results then return "Нет результатов" end
  local out = '{| class="wikitable"\n! Страница\n'
  for _, row in ipairs(results) do
    out = out .. "|-\n| " .. (row.page or "?") .. "\n"
  end
  return out .. "|}"
end
return p

Вызов: {{#invoke:MyModule|ask}}

6. Записать SMW-свойство из Lua

Нужно программно задать семантическое свойство страницы — например, при создании карточки.

local p = {}
function p.setprop(frame)
  if not mw.smw then return "mw.smw недоступен" end
  local data = {
    ["Автор модуля"] = frame.args.author or "",
    ["Тип модуля"]   = frame.args.type   or "remix"
  }
  local result = mw.smw.set(data)
  if result == true then
    return "Свойства сохранены"
  else
    return "Ошибка: " .. (result.error or "неизвестная")
  end
end
return p

Вызов: {{#invoke:MyModule|setprop|author=Иванов|type=remix}}

7. Вызвать парсер-функцию из Lua

Нужно использовать #time, #if или другую parser function прямо внутри модуля.

local p = {}
function p.today(frame)
  local date = frame:callParserFunction(
    "#time", {"d F Y"}
  )
  return "Сегодня: " .. date
end
return p

Вызов: {{#invoke:MyModule|today}}

8. Загрузить внешний CSV и посчитать строки

Нужно прочитать данные с GitHub или другого URL и агрегировать их.

local p = {}
function p.rows(frame)
  if not (mw.ext and mw.ext.externalData) then
    return "Extension:External Data недоступен"
  end
  local url = frame.args.url or ""
  if url == "" then return "Укажите url=" end
  local data, errors = mw.ext.externalData.getExternalData{
    source = url,
    format = "csv with header"
  }
  if not data then return "Ошибка загрузки" end
  return "Строк в CSV: " .. #data
end
return p

Вызов: {{#invoke:DatasetAggregator|rows|url=https://raw.githubusercontent.com/…/data.csv}}

9. Строка с Юникодом: считать буквы, не байты

При подсчёте символов русского/японского текста стандартный # считает байты, а не символы.

local p = {}
function p.ulen(frame)
  local text = frame.args.text or ""
  local bytes  = #text
  local chars  = mw.ustring.len(text)
  return "Байт: " .. bytes .. " / Символов Unicode: " .. chars
end
return p

Вызов: {{#invoke:MyModule|ulen|text=Привет}}

10. Отдать HTML через mw.html

Нужно сгенерировать сложный HTML-элемент (прогресс-бар, карточку) без конкатенации строк.

local p = {}
function p.bar(frame)
  local val = tonumber(frame.args[1]) or 0
  val = math.max(0, math.min(100, val))
  local wrap = mw.html.create("div")
    :css("background", "#eee")
    :css("border-radius", "4px")
    :css("width", "200px")
  wrap:tag("div")
    :css("background", "#4caf50")
    :css("width", val .. "%")
    :css("padding", "3px 6px")
    :css("color", "white")
    :wikitext(val .. "%")
  return tostring(wrap)
end
return p

Вызов: {{#invoke:MyModule|bar|75}}