Вкратце об этой странице: Набросок - это способ создания сложных шаблонов, который более надежен, чем функции синтаксического анализатора . Набросанный шаблон состоит только из {{#invoke: Name1 | Name2}}, который вызывает сценарий в модуле: Name1, где написан код. Чтобы начать работу, см. Модуль: Пример . Попробуйте использовать модуль с помощью Template: Basic scribble example in your sandbox. |
Это Руководство по рисованию . Набросок, также известный как Luafication, представляет собой акт написания шаблона или преобразования шаблона таким образом, чтобы он использовал расширение Scribunto для MediaWiki . Расширение Scribunto [a] было разработано Тимом Старлингом и Виктором Васильевым и позволяет встраивать языки сценариев в MediaWiki. В настоящее время единственным поддерживаемым языком сценариев является Lua . Это руководство призвано дать вам широкий обзор Scribbling и указатели на дополнительную информацию в различных местах.
Нарисованные шаблоны состоят из двух частей: самого шаблона и одного или нескольких внутренних модулей в Module:
пространстве имен, которые содержат программы, которые запускаются на вики-серверах для создания вики -текста, до которого расширяется шаблон. Шаблон вызывает функцию в модуле, используя новую функцию синтаксического анализатора с именем {{#invoke:}}
.
Идея Scribbling заключается в улучшении производительности обработки шаблонов. Строчит устраняет необходимость для программирования функции шаблона синтаксического анализа с помощью функции синтаксического анализа , такие как {{#if}}
, {{#ifeq}}
, {{#switch}}
и {{#expr}}
. Вместо этого все это делается в модуле, на языке, который на самом деле был разработан как язык программирования, а не в системе шаблонов, к которой с течением времени были прикреплены различные расширения, чтобы попытаться превратить это в язык программирования. [b] Набросок также устраняет необходимость в расширении шаблонов до дополнительных шаблонов и потенциально достигает предела глубины раскрытия . Полностью набросанный шаблон никогда не должен включать другие шаблоны. [c]
Lua [ править ]
Язык, на котором написаны модули, - Lua. В отличие от системы функций синтаксического анализатора шаблонов, Lua был разработан не только как правильный язык программирования, но и как язык программирования, который подходит для так называемого встроенного скриптинга . Модули в MediaWiki - это пример встроенных скриптов. Можно было бы использовать несколько встроенных языков сценариев, включая REXX и tcl ; и действительно, первоначальная цель Scribunto заключалась в том, чтобы сделать доступным выбор таких языков. Однако на данный момент доступен только Lua.
Официальное справочное руководство для Lua - Ierusalimschy, de Figueiredo & Celes 2006 . Это справочник, а не учебник. Проконсультируйтесь с ним, если хотите узнать синтаксис или семантику чего-либо. Для учебника см. Иерусалимский 2006 ( также доступен Иерусалимский 2003 , хотя он, конечно, устарел) или Jung & Brown 2007. Недостатком этих книг является то, что довольно много вещей, о которых они вам рассказывают, не имеют никакого отношения к использованию Lua в модулях MediaWiki. Вам не нужно знать, как установить Lua и как интегрировать его интерпретатор в программу или запускать автономно. Все это сделали разработчики MediaWiki. Точно так же многие функции библиотеки Lua в целях безопасности недоступны в модулях. (Например, невозможно выполнять файловый ввод-вывод или выполнять вызовы операционной системы в модулях MediaWiki.) Таким образом, многое из того, что эти книги объясняют о функциях стандартной библиотеки Lua и переменных, которые поставляются с языком, здесь либо неуместно, либо неверно. .
Исходная спецификация API - стандартные библиотечные функции и переменные Lua, которые должны быть доступны в модулях - дана в MW: Extension: Scribunto / API spec . Однако даже это неправда. То, что вам действительно доступно, задокументировано в справочном руководстве MW: Extension: Scribunto / Lua , которое представляет собой сокращенную версию руководства по Lua 1-го издания, которое было отредактировано и изменено Тимом Старлингом, чтобы привести его в соответствие с реальность каракулей. Опять же, это справочное руководство, а не учебное пособие.
Вещи в Lua , что вы будете в основном иметь дело с, написание шаблонов нацарапал, являются таблицы , строки числа , булевы , nil
, , , (генерируется ), (числовые ), , , , , , выражения и различные операторы ( в том числе , , то арифметические операторы , , , , , и ), а также , и глобальные таблицы (т.е. библиотеки).if … then … else … end
while … do … end
for … in … do … end
for
for … do … end
for
repeat … until
function … end
local
return
break
#
..
+
-
*
/
^
%
string
math
mw
Структура шаблона [ править ]
Это просто. Как {{#invoke:}}
правило, ваш шаблон состоит из одного расширения . Вот, например, {{ Harvard citation }}:
< includeonly > {{#invoke: Footnotes | harvard_citation| левая скобка = (| скобка_права =)}} </ includeonly > < noinclude >{{документация}}<! - Добавьте категории на подстраницу / doc, вставьте их в Викиданные, а не сюда -> </ noinclude >
Если вы обнаружите, что хотите использовать другие шаблоны в своем шаблоне, или использовать функции синтаксического анализатора шаблона, или вообще что-нибудь, кроме {{#invoke:}}
и, возможно, некоторых переменных в качестве его аргументов, то вы используете неправильный подход .
Основы модуля [ править ]
Общая структура [ править ]
Рассмотрим гипотетический модуль Модуль: Население . (См. Модуль: Часы населения для аналогичного, но более сложного модуля.) Его можно структурировать одним из двух способов:
Именованная локальная таблица [ править ]
местный p = {}функция p . Индия ( кадр ) return "1,21,01,93,422 человек в (номинально) 2011-03-01 00:00:00 +0530"конецвернуть p
Безымянная таблица, созданная на лету [ править ]
return { Индия = функция ( фрейм ) return "1,21,01,93,422 человек в (номинально) 2011-03-01 00:00:00 +0530" конец}
Казнь [ править ]
Выполнение модуля by {{#invoke:}}
на самом деле двоякое:
- Модуль загружается, и запускается весь скрипт. Это загружает любые дополнительные модули, которые нужны модулю (с помощью функции), строит (вызываемые) функции, которые модуль предоставит шаблонам, и возвращает их таблицу.
require()
- Функция с именем in
{{#invoke:}}
выбирается из таблицы, построенной на этапе 1, и вызывается с аргументами, предоставленными в шаблон, и аргументами, предоставленными для{{#invoke:}}
(подробнее об этом позже ).
Первый сценарий Lua довольно явно выполняет фазу 1. Он создает локальную переменную с именем p
в строке 1, инициализированную таблицей; строит и добавляет к ней функцию (строки 3–5), присваивая функции имя India
в таблице с именем by p
( то же самое, что сказать [d] ); а затем возвращает (в строке 7) таблицу как последнюю строку скрипта. Чтобы расширить такой сценарий дополнительными (вызываемыми) функциями, их добавляют между оператором вверху и оператором внизу. (Non-Invocable локальные функции могут быть добавлены до того в заявлении.) Локальная переменная не должна быть названаfunction p.India
p["India"] = function
local
return
local
p
. Его можно назвать любым допустимым именем переменной Lua, которое вам нравится. p
просто условно для этой цели, а также это имя, которое вы можете использовать для тестирования скрипта в консоли отладки редактора модулей.
Второй сценарий Lua делает то же самое, но более «идиоматично». Вместо создания именованной переменной в виде таблицы он создает анонимную таблицу «на лету» в середине return
оператора, который является единственным (выполняемым на первом этапе) оператором в сценарии. В строках 2–4 создается (также анонимная) функция и вставляется в таблицу под именем . Чтобы расширить такой сценарий дополнительными (вызываемыми) функциями, они добавляются в качестве дополнительных полей в таблице. (Non-Invocable локальные функции могут снова быть добавлены до того в заявлении.)India = function(frame) … end
India
return
В обоих случаях код шаблона, который вы пишете, {{#invoke:Population|India}}
должен вызывать функцию, названную India
из модуля Module: Population . Также обратите внимание, что функция function
строится как вызываемый объект. Он не объявляет это, как вы, возможно, привыкли к другим языкам программирования, и функция не выполняется до тех пор, пока не будет вызвана.
Конечно, можно делать и более сложные вещи. Например: можно объявить другие локальные переменные в дополнение p
к таблицам данных (например, спискам языков или названий стран), которые использует модуль. Но это основная структура модуля. Вы наполняете стол вещами и возвращаете его.
Получение аргументов шаблона [ править ]
Обычная функция в Lua может принимать (эффективно) произвольное количество аргументов. Посмотрите на эту функцию из Module: Wikitext, которую можно вызвать с любым числом от нуля до трех аргументов:
функция z . оксфордлист ( аргументы , разделитель , амперсанд )
Функции, вызываемые by, {{#invoke:}}
являются особенными. Они ожидают, что будет передан ровно один аргумент, таблица, которая называется фреймом (и поэтому обычно ей дается имя frame
параметра в списке параметров функции). Он называется фреймом, потому что, к сожалению, разработчики назвали его для удобства. Он назван в честь внутренней структуры в коде самой MediaWiki, которую он вроде представляет. [e]
В этом фрейме есть (под) таблица с именем args
. У него также есть средства для доступа к его родительскому фрейму (опять же, названному в честь объекта в MediaWiki). В родительском фрейме также есть (под) таблица, также названная args
.
- Аргументы в (предположительно дочернем) фрейме - то есть значение
frame
параметра функции - являются аргументами, передаваемыми{{#invoke:}}
в вики-текст вашего шаблона . Так, например, если вы должны написать{{#invoke:Population|India|a|b|class="popdata"}}
в своем шаблоне, тогда подтаблица аргументов дочернего фрейма будет (как написано в форме Lua) .{ "a", "b", class="popdata" }
- Аргументы в родительском фрейме - это аргументы, переданные вашему шаблону при его включении . Так, например, если бы пользователь вашего шаблона написал,
{{Population of India|c|d|language=Hindi}}
тогда подтаблица аргументов родительского фрейма была бы (как написано в форме Lua) .{ "c", "d", language="Hindi" }
Удобная идиома программистов, которую вы можете использовать, чтобы все это немного упростить, - это иметь локальные переменные с именами (скажем) config
и args
в вашей функции, которые указывают на эти две таблицы аргументов. Смотрите это из модуля: WikidataCheck :
функция p . wikidatacheck ( frame ) local pframe = frame : getParent () local config = frame . args - аргументы, переданные шаблоном, в викитексте самого шаблона local args = pframe . args - аргументы, переданные в шаблон в викитексте, который включает шаблон
config
Таким образом, все в является аргументом, который вы указали в своем шаблоне, на который вы можете ссылаться с помощью кода, такого как и . Это будут вещи, которые сообщают функции вашего модуля его «конфигурацию» (например, имя класса CSS, которое может варьироваться в зависимости от того, какой шаблон используется).config[1]
config["class"]
args
Таким образом, все в является аргументом, который указал пользователь шаблона , где он был включен, и на который вы можете ссылаться с помощью кода, такого как и . Это будут обычные аргументы шаблона, как описано на странице вашего шаблона .args[1]
args["language"]
/doc
См. {{ Другие места }} и {{ другие корабли }}, чтобы узнать о двух шаблонах, которые оба делают, {{#invoke:Other uses|otherX|x}}
но делают это с разными аргументами вместо x
, тем самым получая разные результаты от одной общей функции Lua.
Для обоих наборов аргументов имя и значение аргумента точно такие же, как в викитексте, за исключением того, что начальные и конечные пробелы в именованных параметрах не учитываются. Это повлияет на ваш код, если вы решите поддерживать или использовать имена аргументов включения / вызова, которые не являются допустимыми именами переменных Lua. В таких случаях нельзя использовать "точечную" форму поиска в таблице. Например: как вы можете видеть из раскрашивания синтаксиса здесь, это не ссылка на аргумент, а ссылка на аргумент и переменную с оператором вычитания посередине. Чтобы получить доступ к такому аргументу, использовать «квадратную скобку» форму таблицы поиска: .args.author-first
|author-first=
|author=
first
args["author-first"]
Именованные аргументы args
, конечно же, индексируются в таблице по строкам их имен. Позиционные аргументы (явные 1=
или иные) индексируются в args
таблицах по номеру, а не по строке. не то же самое , что и, и последний фактически не может быть изменен из вики-текста. args[1]
args["1"]
Наконец, обратите внимание, что модули Lua могут различать аргументы, которые были использованы в викитексте и просто устанавливаются в пустую строку, и аргументы, которых нет в викитексте вообще. Последние не существуют в args
таблице, и любая попытка их проиндексировать будет оценена как nil
. В то время как бывший делать в таблице есть и оценить в пустую строку, ""
.
Ошибки [ править ]
С самого начала давайте проясним одну вещь: ошибка скрипта - это гиперссылка. Вы можете навести на него указатель мыши и щелкнуть.
Мы настолько привыкли к тому, что наши (не написанные на набросках) шаблоны выводят сообщения об ошибках красным цветом, что мы думаем, что сообщение об ошибке Scribunto «Ошибка сценария» - не что иное, как то же самое. Это не так. Если у вас включен JavaScript в вашем WWW-браузере, появится всплывающее окно с подробностями об ошибке, трассировкой вызовов и даже гиперссылками, которые переместят вас в то место кода, где произошла ошибка в соответствующем модуле.
Вы можете вызвать ошибку, вызвав функцию. error()
Советы и хитрости [ править ]
Таблицы аргументов являются «специальными». [ редактировать ]
По причинам , которые находятся вне сферы действия настоящего Руководства, [е]args
подтаблица кадра не совсем как обычный стол. Он начинается пустым и заполняется аргументами по мере выполнения кода, который их ищет. [g] (В программе Lua можно создавать таблицы, которые работают подобным образом, используя вещи, называемые метатаблицами . Это тоже выходит за рамки настоящего Руководства.)
Прискорбным побочным эффектом этого является то, что некоторые из обычных операторов таблицы Lua не работают с args
таблицей. Оператор длины,, #
не будет работать, как и функции в table
библиотеке Lua . Они работают только со стандартными таблицами и не работают при использовании специальной args
таблицы. Тем не менее, и функции будут как работать, так как код , чтобы сделать их использование возможно было добавлено разработчиками.pairs()
ipairs()
Скопируйте содержимое таблицы в локальные переменные. [ редактировать ]
Имя в Lua - это либо доступ к локальной переменной, либо поиск по таблице. [3] math.floor
- это, например, поиск в таблице (строки "floor"
) в (глобальной) math
таблице. Поиск в таблице выполняется медленнее во время выполнения, чем поиск в локальной переменной. Поиск в таблицах, таких как args
таблица с ее «особенностями» , выполняется намного медленнее.
Функция в Lua может иметь до 250 локальных переменных. [4] Так что используйте их либерально:
- Если вы вызываете
math.floor
много раз, скопируйте его в локальную переменную и используйте вместо этого: [4]local floor = math.floor local a = floor (( 14 - date . mon ) / 12 ) local y = date . год + 4800 - местный м = дата . пн + 12 * a - 3 дата возвращения . день + этаж (( 153 * м + 2 ) / 5 ) + 365 * y + этаж ( y / 4 ) - этаж ( y / 100 ) + этаж ( y / 400 ) - 2432046
- Не используйте снова и снова. Скопируйте его в локальную переменную и используйте:
args.something
(Даже самалокальная вкладка = args . вкладка
args
переменная - это способ не заглядывать"args"
вframe
таблицу снова и снова.)
При копировании аргументов в локальные переменные есть две полезные вещи, которые вы можете делать на этом пути:
- В альтернативные названия одного и того же аргумента трюк. Если аргумент шаблона может иметь разные имена - например, прописные и строчные буквы или разные английские написания - тогда вы можете использовать
or
оператор Lua, чтобы выбрать имя с наивысшим приоритетом, которое фактически предоставляется:Это работает по двум причинам:местный Title = args . заголовок или аргументы . энциклопедия или аргументы . энциклопедия или аргументы . словарь локальный ISBN = args . isbn13 или args . isbn или args . ISBN
nil
то же самое,false
насколько этоor
касается.or
Оператор Lua имеет так называемую "сокращенную" семантику. Если левый операнд оценивает что-то, чего нетfalse
илиnil
, он не беспокоит даже вычисление значения правого операнда. (Таким образом, хотя этот первый пример может на первый взгляд выглядеть так, как будто он выполняет четыре поиска, в самом общем случае, когда|title=
он используется с шаблоном, на самом деле он выполняет только один.)
- По умолчанию пустой строки трюк. Иногда
nil
полезен тот факт, что опущенный аргумент шаблона является полезным. Однако в других случаях это не так, и вы хотите, чтобы поведение отсутствующих аргументов было пустыми строками. Достаточно простого в конце выражения:or ""
локальный идентификатор = аргументы . id или аргументы . ID или аргументы [ 1 ] или ""
Не расширяйте шаблоны, даже если можете. [ редактировать ]
Если локальные переменные дешевы, а поиск в таблицах обходится дорого, то расширение шаблона намного выше вашей ценовой категории.
Избегайте чумы. В конце концов, расширение вложенных шаблонов с использованием препроцессора MediaWiki - это то, от чего мы пытаемся уйти. Большинство вещей, которые вы бы с этим делали, выполняются проще, быстрее и удобнее с помощью простых функций Lua.frame:preprocess()
Точно так же избегайте таких вещей, как использование w: Template: ISO 639 name aze ( удалено в августе 2020 г. ) для хранения того, что фактически является записью в базе данных. Чтение этого было бы вызовом вложенного парсера с сопутствующими запросами к базе данных, все для отображения строки на другую строку. Поместите простую прямую таблицу данных в свой модуль, например, в Module: Language .
Сноски [ править ]
- ^ Название «Скрибунто» на латыни. « scribunto » является будущим активным императивом оттретьего лица множественного числаот « scribere » и означает «они должны писать». « каракули » - это, конечно, английское слово, образованное от этого латинского слова через средневековую латынь « scribillare ». [1]
- ^ Чтобы понять, что означает «прикрученный», когда дело доходит до разработки программного обеспечения, см.Мультфильмы Флинтстоунов, где стойка с ребрами жесткости от Drive-Thru настолько тяжелая, что заставляет машину Флинтстоунов упасть на бок.
- ^ До тех пор, пока для модулей не станет доступен весь указанный API для Scribunto, может потребоваться включение волшебных слов . См. Раздел советов и приемов . Однако волшебные слова - это не шаблоны.
- ^ Изобретатели языка называют это синтаксическим сахаром . [2]
- ^ В собственно MediaWiki больше двух фреймов.
- ^ Если вы хотите знать, пойдите и прочтите о том, как MediaWiki, отчасти из-за нагрузки, возложенной на нее старой системой шаблонов с условным включением шаблонов, выполняет ленивую оценку аргументов шаблона.
- ^ Поэтому не удивляйтесь, если вы обнаружите обратную трассировку вызова, показывающую вызов какого-либо другого модуля в том, что, по вашему мнению, было обычной ссылкой на аргумент шаблона. Это произойдет потому, что расширение этого аргумента включало расширение другого шаблона Scribbled.
Ссылки [ править ]
Перекрестные ссылки [ править ]
- ^ MW 2003а , стр. 1116.
- ^ Ierusalimschy де Фигуэйред & Целес 2011 , §DATA.
- ^ Ierusalimschy де Фигуэйред & Целес 2011 , §EVAL И СРЕДЫ.
- ^ a b Иерусалимский 2008 , с. 17.
Цитаты [ править ]
- "каракули". Энциклопедический словарь Мерриам-Вебстера: одиннадцатое издание . Энциклопедический словарь Мерриам-Вебстера (11-е изд.). Мерриам-Вебстер. 2003. с. 1116. ISBN 9780877798095.
- Иерусалимский, Роберто; де Фигейредо, Луис Энрике; Селес, Вальдемар (12 мая 2011 г.). «Прохождение языка через игольное ушко» . Очередь . Ассоциация вычислительной техники. 9 (5). АСМ 1542-7730 / 11/0500.
- Иерусалимский, Роберто (декабрь 2008 г.). «Советы по производительности Lua» (PDF) . Ин де Фигейредо, Луис Энрике; Селес, Вальдемар; Иерусалимский, Роберто (ред.). Жемчужины программирования Lua . Lua.org. ISBN 978-85-903798-4-3.
Дальнейшее чтение [ править ]
Lua [ править ]
- Иерусалимский, Роберто; де Фигейредо, Луис Энрике; Селес, Вальдемар (август 2006 г.). Справочное руководство по Lua 5.1 . Lua.org. ISBN 85-903798-3-3.
- Иерусалимский, Роберто (март 2006 г.). Программирование на Lua (Второе изд.). Lua.org. ISBN 9788590379829.
- Иерусалимский, Роберто (декабрь 2003 г.). Программирование на Lua (Первое изд.). Lua.org. ISBN 85-903798-1-7.
- Юнг, Курт; Браун, Аарон (февраль 2007 г.). Начало программирования на Lua . Wrox. ISBN 978-0-470-06917-2.