қуттӣ

Этот модуль составлен в 2014 году как проект новой реализации шаблона }.

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

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

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

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

Для тестирования в боевых условиях замените в частном шаблоне-карточке {{қуттӣ}} на {{қуттӣ/модул}}.

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

  • Все параметры переведены. Исключение составляет 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', '125%')                 .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', '-2px')                     .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('subheaderrowstyle','сабки_зерсарлавҳа')     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:

Модул:InfoboxШаблон:Қуттӣ

🔥 Trending searches on Wiki Тоҷикӣ:

Ибни СиноБаҳористонВолейболҶанги Бузурги ВатанӣОрҳан БийиклӣҲуқуқи меҳнатӣНизоми молияи давлатии Ҷумҳурии ТоҷикистонАвстралияМирзо ТурсунзодаҲуқуқу озодиҳои конститутсионии инсон ва шаҳрвандБарномаи компютерӣШайбониёнБулбулИстилоҳШафтолу (мева)Вилояти ХатлонВикипедияАмрикоТуркияҶанги ҷаҳонии дувумҚоидаҳои имлои забони тоҷикӣГандумФарҳанги луғатВаколатномаҶамъияти дорои масъулияти маҳдудСиғаи хабарӣАҳдАбуҳомид Муҳаммади ҒазолӣКамол (гиёҳ)Нерӯгоҳи барқи обии НоракШахси ҳуқуқӣИттиҳоди АврупоИқтисоди ҷаҳонӣБаскетболАдабиёти классикӣДарахтЁддоштҳо (Айнӣ)ТарбузАбрешимАввалин Бонки Молиявии ХурдОзоносфераСуғуртакунӣВикиОриёӣИнтихобот дар ТоҷикистонФисоғурисҲамлаи Муғул ба Осиёи МарказӣГурҷистонДастгоҳи иҷроияи Президенти ТоҷикистонДонишномаГоҳшумории ҳиҷрӣТақсими кори байналмилалӣҚоҳир РасулзодаРаҳмат НазрӣДонишкадаи исломии ТоҷикистонИсм (дастури забон)Алифбои форсӣПойтахтДилрабо МансурӣҲол (забоншиносӣ)Суғд872НавзодКитобНомҳои Худо дар исломСиёсатшиносӣГули бобунаҶӯрабек НазриевСомонБадоеъу-л-вақоеъГурбаЧилахон ХоловШушСурайё ҚосимоваНишони ТоҷикистонШутурҶуғрофиё🡆 More