Из Википедии, бесплатной энциклопедии
Перейти к навигации Перейти к поиску
«Шшш! Я читаю о том, как рисовать шаблоны».

Это Руководство по рисованию . Набросок, также известный как 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 endwhile do endfor in do endforfor do endforrepeat untilfunction endlocalreturnbreak#..+-*/^%stringmathmw

Структура шаблона [ править ]

Это просто. Как {{#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:}}на самом деле двоякое:

  1. Модуль загружается, и запускается весь скрипт. Это загружает любые дополнительные модули, которые нужны модулю (с помощью функции), строит (вызываемые) функции, которые модуль предоставит шаблонам, и возвращает их таблицу.require()
  2. Функция с именем in {{#invoke:}}выбирается из таблицы, построенной на этапе 1, и вызывается с аргументами, предоставленными в шаблон, и аргументами, предоставленными для {{#invoke:}}(подробнее об этом позже ).

Первый сценарий Lua довольно явно выполняет фазу 1. Он создает локальную переменную с именем pв строке 1, инициализированную таблицей; строит и добавляет к ней функцию (строки 3–5), присваивая функции имя Indiaв таблице с именем by p( то же самое, что сказать [d] ); а затем возвращает (в строке 7) таблицу как последнюю строку скрипта. Чтобы расширить такой сценарий дополнительными (вызываемыми) функциями, их добавляют между оператором вверху и оператором внизу. (Non-Invocable локальные функции могут быть добавлены до того в заявлении.) Локальная переменная не должна быть названаfunction p.Indiap["India"] = functionlocalreturnlocalp. Его можно назвать любым допустимым именем переменной Lua, которое вам нравится. pпросто условно для этой цели, а также это имя, которое вы можете использовать для тестирования скрипта в консоли отладки редактора модулей.

Второй сценарий Lua делает то же самое, но более «идиоматично». Вместо создания именованной переменной в виде таблицы он создает анонимную таблицу «на лету» в середине returnоператора, который является единственным (выполняемым на первом этапе) оператором в сценарии. В строках 2–4 создается (также анонимная) функция и вставляется в таблицу под именем . Чтобы расширить такой сценарий дополнительными (вызываемыми) функциями, они добавляются в качестве дополнительных полей в таблице. (Non-Invocable локальные функции могут снова быть добавлены до того в заявлении.)India = function(frame) endIndiareturn

В обоих случаях код шаблона, который вы пишете, {{#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=firstargs["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 .

Сноски [ править ]

  1. ^ Название «Скрибунто» на латыни. « scribunto » является будущим активным императивом оттретьего лица множественного числаот « scribere » и означает «они должны писать». « каракули » - это, конечно, английское слово, образованное от этого латинского слова через средневековую латынь « scribillare ». [1]
  2. ^ Чтобы понять, что означает «прикрученный», когда дело доходит до разработки программного обеспечения, см.Мультфильмы Флинтстоунов, где стойка с ребрами жесткости от Drive-Thru настолько тяжелая, что заставляет машину Флинтстоунов упасть на бок.
  3. ^ До тех пор, пока для модулей не станет доступен весь указанный API для Scribunto, может потребоваться включение волшебных слов . См. Раздел советов и приемов . Однако волшебные слова - это не шаблоны.
  4. ^ Изобретатели языка называют это синтаксическим сахаром . [2]
  5. ^ В собственно MediaWiki больше двух фреймов.
  6. ^ Если вы хотите знать, пойдите и прочтите о том, как MediaWiki, отчасти из-за нагрузки, возложенной на нее старой системой шаблонов с условным включением шаблонов, выполняет ленивую оценку аргументов шаблона.
  7. ^ Поэтому не удивляйтесь, если вы обнаружите обратную трассировку вызова, показывающую вызов какого-либо другого модуля в том, что, по вашему мнению, было обычной ссылкой на аргумент шаблона. Это произойдет потому, что расширение этого аргумента включало расширение другого шаблона Scribbled.

Ссылки [ править ]

Перекрестные ссылки [ править ]

  1. ^ MW 2003а , стр. 1116.
  2. ^ Ierusalimschy де Фигуэйред & Целес 2011 , §DATA.
  3. ^ Ierusalimschy де Фигуэйред & Целес 2011 , §EVAL И СРЕДЫ.
  4. ^ 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.