ФЭНДОМ


Lua-logo

Lua (лу́а, с порт. — «луна») — скриптовый язык программирования с открытым исходным кодом. В движке MediaWiki Lua версии 5.1 подключается при помощи расширения Scribunto.

Расширение доступно на всех википроектах от 13 июня 2014 года[1], а до этого некоторое время оно использовалось лишь на определённых проектах в рамках тестирования.

Использование

Code compare

Сравнение кода до и после использования Lua (оба фрагмента дают одинаковый результат)

Lua достаточно часто используется для создания скриптов, дополнительных программ для решения конкретных задач. К примеру, именно этот язык часто применяется в игровой индустрии для создания, расширения интерфейса; на нём работают такие известные видеоигры, как World of Warcraft или Angry Birds. Исключением в определении задач языка не стал и ФЭНДОМ, где Lua играет своего рода вспомогательную роль, ведь, в отличие от CSS или JavaScript, этот язык программирования вполне себе заменим традиционной викиразметкой (вместе с функциями парсера). Более того, в некоторых случаях он оказывается эффективнее привычных средств, в частности:

  • При использовании в инфобоксах. Хотя функции парсера[2] позволяют производить самые разнообразные операции внутри шаблона и создавать довольно сложные конструкции, они обладают рядом значительных недостатков: обработка сложных шаблонов требует от сервера множество ресурсов и времени, что в итоге сказывается на времени загрузки страницы, а код таких шаблонов обычно сложно прочитать. При использовании Lua можно увеличить скорость загрузки страницы, а также — в теории — сделать код более понятным.
    • При создании новых инфобоксов с помощью Infoboxbuilder’a[3] (не стоит путать с одноимённой служебной страницей). На текущий момент данная возможность считается устаревшей и имеет ограниченную поддержку на ФЭНДОМЕ.
  • При создании текста с использованием HTML или викиразметки в тех случаях, когда нужно вывести конкретные данные с большого их массива. Например, данные об эпизодах сериала, что используются в сносках.

Характеристика

Lua предоставляет совершенно иной опыт использования в сравнении с традиционной викиразметкой вкупе с функциями парсера. Причиной тому является тот факт, что язык походит на «стандартный» синтаксис языков программирования, а это открывает целый ряд преимуществ. Первое и основное — логические операции в привычном для программирования понимании. Вместо ряда «шаблонов» вида {{#if:{{{1|}}}|...|...}} здесь доступны операторы ветвления («if/else»), циклы for и while, переменные (можно сохранить промежуточный результат выполнения кода). Это значительной облегчает решение большого количества задач, а также, что не менее важно, делает код более понятным для человека. Например, такой код (в сравнении с {{#ifeq: x| 100 | identical | different}}):

if 1 == 100 then
    'identical'
else
    'different'
end

выглядит логичнее и проще для понимания (особенно для тех, кто хоть как-то знаком с английским языком). Хотя стоит отметить, что это утверждение верно не всегда. Lua довольно нетипичен для викисреды и незнакомых с языком участников может и отпугнуть код шаблон, использующий Lua: {{#invoke:loop|appendloop}} — вместо функций парсера здесь просто вызывается соответствующий модуль Lua.

Другим плюсом языка является производительность. При правильном использовании возможностей языка можно ускорить обработку страниц в разы или даже десятки раз. Например, громоздкие конструкции {{#switch:}} (подвид ветвления) заменяются поиском данных из определённой таблицы — базового типа данных Lua, и такая миграция ускоряет работу на ~50 % при количестве ветвлений {{#switch:}} равном 150. Однако, вместе с тем некоторые операции, как {{#switch:}} (проверка существования страницы) остаются дорогостоящими и в Lua (за исключением некоторых реализаций модулей), а потому выигрыш в производительности либо отсутствует, либо и вовсе становится проигрышем (при неправильной реализации модуля).

Язык поддерживает основные типы данных: логические значения, числа, строки, функции, потоки, а также nil — особый тип для неопределённого значения. Такие привычные структуры данных, как массивы, наборы или списки, отсутствуют, вместо всех них используется одна базовая структура — таблица. Таблица в Lua — это множество пар «ключ-значение». В отличие от того же JavaScript, ключами могут быть значения любых типов Lua, кроме nil. Запись nil в элемент таблицы равносильна удалению данного элемента.

Классическая программа Hello, world! на Lua помещается в одну строку:

print("Hello World!")

Однако на ФЭНДОМЕ данная программа должна быть написана несколько иначе:

local p = {}
 
function p.hello()
    return 'Hello World!'
end
 
return p

Особенности использования Lua на ФЭНДОМЕ

В отличие от JS и CSS, скрипты на Lua может редактировать каждый участник[4]. Для этого необходимо создать страницу Module:НазваниеМодуля с необходимым кодом. Во время работы может помочь консоль отладки[5] — особая функция редактора Lua.

Встраивание скриптов на страницу

Для использования модуля необходимо встроить его на страницу. Это можно сделать с помощью следующей конструкции: {{#invoke:НазваниеМодуля|НазваниеФункции|параметр1|параметр2|параметр3|…}}. Если у функции отсутствуют какие-либо параметры, то после названия нужно поставить закрывающие фигурные скобки.

Если модуль был корректно написан и вызван, то результат его работы станет (или не станет, в зависимости от кода) виден, в противном случае будет выведен текст «Ошибка скрипта», а страница добавится в особую категорию «Pages with script errors».

Примечание: не следует встраивать скрипты таким образом прямо на страницу, лучше всего создать отдельный шаблон и использовать скрипт через него; тем не менее встраивание скрипта напрямую не возбраняется.

Написание кода

После того как страница модуля была создана, необходимо добавить на неё код (иначе создание модуля не имеет смысла). Если требуется начать написание модуля с нуля, на страницу нужно добавить следующий код:

local p = {}
 
function p.hello()
    --Код функции
    --Возврат значения
end
 
return p

Чтобы передать в функцию аргументы, необходимо внутри круглых скобок добавить frame.

Внутри функции hello происходят различные операции (какие именно — зависит от написанного кода), результат которых затем будет возвращён пользователю. Внутри модуля можно реализовать несколько функций, которые могут быть основными (непосредственно возвращая результат своей работы при вызове модуля) или вспомогательными (возвращая результат для другой функции).

Примером вспомогательной функции может быть получение данных из объекта frame, в котором содержатся параметры, указанные при вызове модуля:

Код Результат
local str = {}
local result = ''
 
-- Основная функция
function str.build( frame )
    local new_args = str._getP(frame.args, {'name', 'text'});
    local n = new_args['name'] or "новый участник";
    local t = new_args['text'] or "Как дела?";
    local result='';
    result = "Привет, " .. n .. "! " .. t .. "<br/>"
 
    return result;
end
 
-- Получение параметров
function str._getP( frame_args, arg_list )
    local new_args = {};
    local index = 1;
    local value;
 
    for i,arg in ipairs( arg_list ) do
        value = frame_args[arg]
        if value == nil then
            value = frame_args[index];
            index = index + 1;
        end
        new_args[arg] = value;
    end
 
    return new_args;
end 
 
return str;
Данный модуль выводит строку, в которой есть два переменных: первая из них отвечает за «получателя» приветствия, а вторая — за дополнительный текст. При вызове такого модуля с помощью кода {{#invoke:Test2|build|аноним|Это — тестовый модуль!}} будет получен такой результат:
Module output example

Для того чтобы облегчить процесс создания нового модуля, можно воспользоваться различными библиотеками или импортом уже готовых скриптов.

Библиотеки

Lua div create example

Пример создания тега с текстом внутри

Всего на ФЭНДОМЕ используются два вида библиотек: стандартные и библиотеки Scribunto.

Стандартные библиотеки содержат:

  • базовые функции (вывод версии, сообщения об ошибке и т. д.);
  • математические функции (генерация случайных чисел, вычисление различных функций);
  • функции для вывода времени;
  • функции для загрузки модулей;
  • функции для работы со строками;
  • функции для работы с таблицами (table).

В свою очередь, библиотеки Scribunto в большей степени предназначены для работы на ФЭНДОМЕ и используются для работы со страницами: получение URL-адреса, доступ к frame и дальнейшая работа с ним, работа со строками, создание HTML тегов и многое другое. Подробнее изучить содержимое библиотек можно на FANDOM Open Source Library[6].

На ФЭНДОМЕ также доступны различные глобальные модули; их можно найти на FANDOM Open Source Library[7]. Они могут использоваться как в качестве основы для других модулей, так и самостоятельно.

Импорт

После 25 июня 2015 года на ФЭНДОМЕ появилась возможность напрямую импортировать скрипты на Lua с FANDOM Open Source Library[8]. Для этого нужно добавить на страницу следующий код:

return require("Dev:ModuleName")

То есть, если вы хотите импортировать на свою вики Модуль: Quote, то вам будет нужно создать новую страницу модуля, после чего добавить на неё следующий код:

return require("Dev:Quote")

После этого новый модуль можно будет вызвать так же, как и оригинальный (для этого стоит предварительно изучить документацию или самому найти необходимую функцию для вызова).

Если же вы хотите создать модуль, который использует не только скопированный код, но и свой — можно поместить модуль в отдельную переменную, после чего вызывать его при необходимости. Ниже приведён пример из глобального модуля Asof (который, в свою очередь, использует другие глобальные модули)[9]:

local u = require("Dev:Utility")
local dateHelper = require("Dev:Date")

Ссылки

Примечания

  1. Lua — язык разметки для более быстрых и мощных шаблонов
  2. Extension:ParserFunctions
  3. Lua templating/InfoboxBuilder
  4. Тем не менее страницу с кодом можно защитить от редактирования, как и любую другую.
  5. Debug console
  6. Scribunto libraries & Standard_libraries|Standard libraries
  7. Лист глобальных модулей
  8. Техническое обновление от 25 июня 2015
  9. Module:Asof