карточка

Этот модуль составлен для реализации шаблон }.

Документация по использованию шаблона расположена на странице соответствующего шаблона.

Тестирование

Модуль развёрнут в двух вариантах: боевая версия (привязана к {{карточка/модуль}}, в дальнейшем будет перевязана к {{карточка}}) и песочница для тестирования (привязана к {{карточка/песочница}}).

Для песочницы развёрнут модуль юнит-тестирования ([1]).

Для тестирования в боевых условиях замените в частном шаблоне-карточке {{карточка}} на {{карточка/модуль}}. Несколько малоиспользуемых шаблонов, взятых на боевое тестирование:

  • {{Дзюдоист-паралимпиец}}
  • ...

Что следует учитывать при портировании карточек из английской Википедии

  • Все параметры переведены. Исключение составляет nocat. Внимание: при переводе шаблонов-карточек нужно заменять decat на nocat!
  • cellspacing заменён с 3 на 2 (польза от 3 неизвестна).
  • Очищены стандартные style-стили — этим занимается MediaWiki:Common.css, а не модуль. Стили по умолчанию в английской карточке немного отличаются от переведённой карточки.
  • Изменён способ обработки заголовок_курсивом на более привычный для раздела:
      В английской Википедии если italic title пустой, yes или force, то заголовок выводится курсивом.
      В переведённой версии если заголовок_курсивом не пустой (обычно пишется заголовок_курсивом=1), то заголовок выводится курсивом.
  • Изменён способ обработки nocat на более привычный для раздела:
      В английской Википедии если decat установлен в yes, то категоризация не выполняется.
      В переведённой версии если nocat не пустой (обычно пишется nocat=1), то категоризация не выполняется.

Изменения, которые, возможно, стоит внести перед интеграцией

  • Документировать параметры, которых раньше не было из-за технических ограничений (снятие ограничений на количество изображений, полей вверху, внизу)
  • Документировать новые параметры стилей и классов.
  • Документировать режимы внедрения и подкарточки.
  • Избавиться от scope — польза от него сомнительна, читалки с высокой вероятностью в состоянии определить порядок чтения карточек.

Проблемы внедрения

Используемый в коде подход гарантирует корректную работу только при шаге между подзаголовками и парами метка-текст не больше 50! В разных карточках можно встретить что-то вроде метка12=...|текст12=...|метка13=...|текст13=...|метка120=... — такие места нужно исправлять вручную.


-- -- Модуль для реализации шаблона {{Карточка}} --  local p = {}  local HtmlBuilder = require('Module:HtmlBuilder')  local args = {} local origArgs local argsAliases = {} local root  local function union(t1, t2)     -- Возвращает объединение значений двух таблиц в виде последовательности.     local vals = {}     for k, v in pairs(t1) do         vals[v] = true     end     for k, v in pairs(t2) do         vals[v] = true     end     local ret = {}     for k, v in pairs(vals) do         table.insert(ret, k)     end     return ret end  local function getArgNums(prefix)     -- Возвращает таблицу индексов существующих полей с заданным префиксом,     -- например, для префикса 'текст' и установленных 'текст1', 'текст2' и     -- 'текст5' возвращает {1, 2, 5}.     local nums = {}     for k, v in pairs(args) do         local num = tostring(k):match('^' .. prefix .. '([1-9]%d*)$')         if num then table.insert(nums, tonumber(num)) end     end     table.sort(nums)     return nums end  local function addRow(rowArgs)     -- Добавляет строку в карточку (заголовок или метку/текст).     if rowArgs.header then         root             .tag('tr')                 .addClass(rowArgs.rowclass)                 .attr('id', rowArgs.rowid)                 .tag('th')                     .attr('colspan', 2)                     .attr('id', rowArgs.headerid)                     .addClass(rowArgs.class)                     .addClass(args['класс_заголовков'])                     .css('text-align', 'center')                     .cssText(args['стиль_заголовков'])                     .wikitext(rowArgs.header)     elseif rowArgs.data then         local row = root.tag('tr')         row.addClass(rowArgs.rowclass)         row.attr('id', rowArgs.rowid)         if rowArgs.label then             row                 .tag('th')                     .attr('scope', 'row')                     .attr('id', rowArgs.labelid)                     .cssText(args['стиль_меток'])                     .wikitext(rowArgs.label)                     .done()         end          local dataCell = row.tag('td')         if not rowArgs.label then              dataCell                 .attr('colspan', 2)                 .css('text-align', 'center')          end         dataCell             .attr('id', rowArgs.dataid)             .addClass(rowArgs.class)             .cssText(rowArgs.datastyle)             .newline()             .wikitext(rowArgs.data)     end end  local function renderTitle()     if not args['название'] then return end      root         .tag('caption')             .addClass(args['класс_названия'])             .cssText(args['стиль_названия'])             .wikitext(args['название']) end  local function renderAboveRow()     if not args['вверху'] then return end      root         .tag('tr')             .tag('th')                 .attr('colspan', 2)                 .addClass(args['класс_вверху'])                 .css('text-align', 'center')                 .css('font-size', '120%')                 .css('font-weight', 'bold')                 .cssText(args['стиль_вверху'])                 .wikitext(args['вверху']) end  local function renderAbove2Row()     if not args['вверху2'] then return end      root         .tag('tr')             .tag('th')                 .attr('colspan', 2)                 .addClass(args['класс_вверху2'])                 .css('text-align', 'center')                 .css('font-style', 'oblique')                 .cssText(args['стиль_вверху2'])                 .wikitext(args['вверху2']) end  local function renderBelowRow()     if not args['внизу'] then return end      root         .tag('tr')             .tag('td')                 .attr('colspan', 2)                 .addClass(args['класс_внизу'])                 .css('text-align', 'center')                 .cssText(args['стиль_внизу'])                 .newline()                 .wikitext(args['внизу']) end  local function renderSubheaders()     if args['подзаголовок'] then         args['подзаголовок1'] = args['подзаголовок']     end     if args['класс_ряда_подзаголовка'] then         args['класс_ряда_подзаголовка1'] = args['класс_ряда_подзаголовка']     end     local subheadernums = getArgNums('подзаголовок')     for k, num in ipairs(subheadernums) do         addRow({             data = args['подзаголовок' .. tostring(num)],             datastyle = args['стиль_подзаголовков'] or args['стиль_подзаголовка' .. tostring(num)],             class = args['класс_подзаголовков'],             rowclass = args['класс_ряда_подзаголовка' .. tostring(num)]         })     end end  local function renderImages()     if args['изображение'] then         args['изображение1'] = args['изображение']     end     if args['подпись'] then         args['подпись1'] = args['подпись']     end     local imagenums = getArgNums('изображение')     for k, num in ipairs(imagenums) do         local caption = args['подпись' .. tostring(num)]         local data = HtmlBuilder.create().wikitext(args['изображение' .. tostring(num)])         if caption then             data                 .tag('div')                     .cssText(args['стиль_подписи'])                     .wikitext(caption)         end         addRow({             data = tostring(data),             datastyle = args['стиль_изображения'],             class = args['класс_изображения'],             rowclass = args['класс_ряда_изображения' .. tostring(num)]         })     end end  local function renderRows()     -- Объединяет индексы заголовков и текстовых строк карточки     -- и визуализирует их в правильном порядке через addRow.     local rownums = union(getArgNums('заголовок'), getArgNums('текст'))     table.sort(rownums)     for k, num in ipairs(rownums) do         addRow({             header = args['заголовок' .. tostring(num)],             label = args['метка' .. tostring(num)],             data = args['текст' .. tostring(num)],             datastyle = args['стиль_текста'],             class = args['класс' .. tostring(num)],             rowclass = args['класс_ряда' .. tostring(num)],             dataid = args['id_текста' .. tostring(num)],             labelid = args['id_метки' .. tostring(num)],             headerid = args['id_заголовка' .. tostring(num)],             rowid = args['id_ряда' .. tostring(num)]         })     end end  local function renderNavBar()     if not args['имя'] then return end      root         .tag('tr')             .tag('td')                 .attr('colspan', 2)                 .css('text-align', 'right')                 .wikitext(mw.getCurrentFrame():expandTemplate({                      title = 'Tnavbar',                      args = { args['имя'] }                 })) end  local function isSet(x)     -- Возвращает истину, если x задан и не пустой     -- Внимание: отличается от enwiki! В enwiki проверяется на равенство 'yes'     return x and x ~= '' end  local function renderItalicTitle()     -- Внимание: отличается от enwiki. В enwiki ожидается yes или force, здесь работает любое значение     if isSet(args['заголовок_курсивом']) then         root.wikitext(mw.getCurrentFrame():expandTemplate({title = 'Заголовок курсивом'}))     end end  local function renderTrackingCategories()     if not isSet(args.nocat) then         if #(getArgNums('текст')) == 0 and mw.title.getCurrentTitle().namespace == 0 then             root.wikitext('[[Категория:Статьи с карточкой без заполненных данных]]')         end         if isSet(args['внедрение']) and args['название'] then             root.wikitext('[[Категория:Статьи со встроенной карточкой и параметром названия]]')         end     end end  local function _infobox()     -- Задание общей страктуры карточки с добавлением стилей      -- для карточек-потомков.     if not isSet(args['внедрение']) then         root = HtmlBuilder.create('table')          root             .addClass('infobox')             .addClass(args['класс_тела'])              if isSet(args['подкарточка']) then                 root                     .css('padding', '0')                     .css('border', 'none')                     .css('margin', '-1px')                     .css('width', 'auto')                     .css('min-width', '100%')                     .css('font-size', '100%')                     .css('clear', 'none')                     .css('float', 'none')                     .css('background-color', 'transparent')             end                  -- Микроразметка         if isSet(args['микр_тела']) then         root           .attr('itemscope', 'itemscope')           .attr('itemtype', args['микр_тела'])         end                  root             .cssText(args['стиль_тела'])          renderTitle()         renderAboveRow()         renderAbove2Row()     else         root = HtmlBuilder.create()          root             .wikitext(args['название'])     end      renderSubheaders()     renderImages()      renderRows()      renderBelowRow()       renderNavBar()     renderItalicTitle()     renderTrackingCategories()      return tostring(root) end  local function preprocessSingleArg(argName)     -- Добавляет аргумент в таблицу аргументов, если он определён и не пустой.     -- Пустые аргументы не обрабатываются, как и в ParserFunctions.     if origArgs[argName] and origArgs[argName] ~= '' then         args[argName] = origArgs[argName]     end end  local function translateArg(aliasArgName,localArgName) -- Функция добавляет поддержку алиасов параметров (например, на другом языке)  -- Добавляем алиас параметра в таблицу алиасов -- Для одного параметра может быть несколько алиасов -- Нумерованные параметры(текст1 и т.д.) заносятся без номера if not argsAliases[localArgName] then argsAliases[localArgName] = {} end table.insert(argsAliases[localArgName], aliasArgName)  -- Пока для тестирования: значения алиасов добавляются в таблицу аргументов -- Нумерованные параметры работать не будут     if origArgs[localArgName] and origArgs[localArgName] ~= '' then     -- параметр уже задан на локальном языке     else     -- если алиас задан и не пустой     if origArgs[aliasArgName] and origArgs[aliasArgName] ~= '' then         origArgs[localArgName] = origArgs[aliasArgName]     end     end end  local function preprocessArgs(prefixTable, step)     -- Сохраняет параметры с заданными префиксами в таблицу args, последовательно обходя     -- аргументы в нужном порядке и с нужным шагом. Благодаря этому сноски и пр. появляются     -- в правильном порядке. prefixTable — массив таблиц, каждая из которых может содержать     -- два поля: поле-строку префикса (обязательно) и поле-таблицу зависимых параметров.     -- Эта функция всегда обрабатывает параметры с префиксом, но зависимые параметры     -- обрабатываются, только если параметр с префиксом задан и не пустой.     if type(prefixTable) ~= 'table' then         error("В качестве таблицы префиксов должна использоваться таблица", 2)     end     if type(step) ~= 'number' then         error("Недопустимый тип параметра шага", 2)     end      -- Проверка правильности данных и обработка параметров без суффиксов.     for i,v in ipairs(prefixTable) do         if type(v) ~= 'table' or type(v.prefix) ~= "string" or (v.depend and type(v.depend) ~= 'table') then             error('Недопустимая таблица префиксов preprocessArgs', 2)         end         preprocessSingleArg(v.prefix)         -- Зависимые параметры обрабатываются, только если параметр с префиксом задан и не пустой.         if args[v.prefix] and v.depend then             for j, dependValue in ipairs(v.depend) do                 if type(dependValue) ~= 'string' then                     error('Недопустимый тип зависимого параметра в таблице preprocessArgs')                 end                 preprocessSingleArg(dependValue)             end         end     end      -- Обход нумерованных аргументов.     local a = 1 -- Переменная-счётчик.     local moreArgumentsExist = true     while moreArgumentsExist == true do         moreArgumentsExist = false         for i = a, a + step - 1 do             for j,v in ipairs(prefixTable) do                 local prefixArgName = v.prefix .. tostring(i)                 if origArgs[prefixArgName] then                     moreArgumentsExist = true -- Искать аргументы дальше, если был хотя бы один (в т. ч. пустой)                     preprocessSingleArg(prefixArgName)                 end                 -- Обрабатываем зависимые аргументы, если определена таблица зависимостей,                 -- а также задан не пустой аргумент с префиксом, либо обрабатывается                  -- "префикс1" и "префикс" задан (например, "изображение1" является синонимом для "изображение").                 if v.depend and (args[prefixArgName] or (i == 1 and args[v.prefix])) then                     for j,dependValue in ipairs(v.depend) do                         local dependArgName = dependValue .. tostring(i)                         preprocessSingleArg(dependArgName)                     end                 end             end         end         a = a + step     end end  function p.infobox(frame)     -- При запуске через #invoke аргументы передаются через стандартную систему.     -- При тестировании также можно передавать таблицу аргументов через frame.     if frame == mw.getCurrentFrame() then         origArgs = frame:getParent().args     else         origArgs = frame     end          -- Поддержка параметров из англовики     translateArg('child','внедрение')     translateArg('bodyclass','класс_тела')     translateArg('subbox','подкарточка')     translateArg('bodystyle','стиль_тела')     translateArg('title','название')     translateArg('titleclass','класс_названия')     translateArg('titlestyle','стиль_названия')     translateArg('above','вверху')     translateArg('aboveclass','класс_вверху')     translateArg('abovestyle','стиль_вверху')          translateArg('subheader','подзаголовок')     translateArg('subheaderstyle','стиль_подзаголовка')     translateArg('subheaderrowclass','класс_подзаголовка')      translateArg('subheaderstyle','стиль_подзаголовков')     translateArg('subheaderclass','класс_подзаголовков')       translateArg('image','изображение')     translateArg('caption','подпись')     translateArg('imagerowclass','класс_ряда_изображения')      translateArg('captionstyle','стиль_подписи')     translateArg('imagestyle','стиль_изображения')     translateArg('imageclass','класс_изображения')           translateArg('header','заголовок')     translateArg('data','текст')     translateArg('label','метка')     translateArg('rowclass','класс_ряда')     translateArg('class','класс')     translateArg('dataid','id_текста')     translateArg('labelid','id_метки')     translateArg('headerid','id_заголовка')     translateArg('rowid','id_ряда')      translateArg('headerclass','класс_заголовков')     translateArg('headerstyle','стиль_заголовков')     translateArg('labelstyle','стиль_меток')     translateArg('datastyle','стиль_текста')     translateArg('below','внизу')     translateArg('belowclass','класс_внизу')     translateArg('belowstyle','стиль_внизу')     translateArg('name','имя')     --translateArg('italic title','заголовок_курсивом')     --translateArg('','')           -- Параметры обрабатываются по направлению чтения карточки, чтобы     -- сноски и др. отображались в нужных местах. Параметры, зависящие      -- от других параметров, обрабатываются только при наличии других параметров,     -- чтобы в списке сносок не возникали нежелательные сноски.     preprocessSingleArg('внедрение')     preprocessSingleArg('класс_тела')     preprocessSingleArg('подкарточка')     preprocessSingleArg('стиль_тела')     preprocessSingleArg('название')     preprocessSingleArg('класс_названия')     preprocessSingleArg('стиль_названия')     preprocessSingleArg('вверху')     preprocessSingleArg('класс_вверху')     preprocessSingleArg('стиль_вверху')     preprocessSingleArg('вверху2')     preprocessSingleArg('класс_вверху2')     preprocessSingleArg('стиль_вверху2')     preprocessArgs({         {prefix = 'подзаголовок', depend = {'стиль_подзаголовка', 'класс_подзаголовка'}}     }, 10)     preprocessSingleArg('стиль_подзаголовков')     preprocessSingleArg('класс_подзаголовков')     preprocessArgs({         {prefix = 'изображение', depend = {'подпись', 'класс_ряда_изображения'}}     }, 10)     preprocessSingleArg('стиль_подписи')     preprocessSingleArg('стиль_изображения')     preprocessSingleArg('класс_изображения')     preprocessArgs({         {prefix = 'заголовок'},         {prefix = 'текст', depend = {'метка'}},         {prefix = 'класс_ряда'},         {prefix = 'класс'},         {prefix = 'id_текста'},         {prefix = 'id_метки'},         {prefix = 'id_заголовка'},         {prefix = 'id_ряда'}     }, 50)     preprocessSingleArg('класс_заголовков')     preprocessSingleArg('стиль_заголовков')     preprocessSingleArg('стиль_меток')     preprocessSingleArg('стиль_текста')     preprocessSingleArg('внизу')     preprocessSingleArg('класс_внизу')     preprocessSingleArg('стиль_внизу')     preprocessSingleArg('имя')     preprocessSingleArg('заголовок_курсивом')     preprocessSingleArg('nocat')      return _infobox() end  return p 

Tags:

Ҡалып:Карточка

🔥 Trending searches on Wiki Башҡорт:

ӘрмәнстанМиланКәкүкҠулаев Мөхәмәтхан Сәхипгәрәй улыМуса ЙәлилКәбиров Артур Зиннур улыҠошсо кантоныВикиНазар НәжмиДаянова Тәскирә Байрам ҡыҙыМәғрифәтселек дәүереӨфө «Нур» татар дәүләт театрыБәйләүесБашҡорт алфавиты5 февральФлоридаМайкл Джексон1990 йылБанкнотаИлШвейцария1873 йылДиего ВеласкесYouTube1922 йылПортугалияИзраиль1809 йылОтто фон Бисмарк27 мартКонституцион монархияДжордано Бруно11 ноябрьҠояшЭкология3 октябрьСайтАрҡайымТатарстан РеспубликаһыИсем (һүҙ төркөмө)ДинамоҺүҙ төркөмдәреҒиндуллин Фәрит Хөрмәтулла улыБарабанСатурн (планета)Абай ҠонанбаевГалилео ГалилейНазаров Рәшит Сәйетбаттал улы7 апрель2009 йылЖурналистикаХагенВикикитапханаTendenceБаймөхәмәтов Айгиз Ғиззәт улыБөжәктәрОперацион системаМария Чеботарь20 апрельӘхмәтзәки Вәлиди ТуғанИнглиз телеМәҙрәсәИсландияУйынсыҡ🡆 More