Модуль:ТранспортнаяСхема: различия между версиями

мНет описания правки
мНет описания правки
Строка 1: Строка 1:
local p = {}
local p = {}


-- Безопасная загрузка JSON из пространства Шаблонов
-- Универсальное слияние аргументов (из инфобокса, шаблона и вызова)
local function loadData(frame)
local function getArgs(frame)
     local dataParam = frame.args['данные'] or frame.args[1]
    local args = {}
    if frame.getParent then
        local parent = frame:getParent()
        if parent and parent.args then
            for k, v in pairs(parent.args) do args[k] = v end
        end
    end
    if frame.args then
        for k, v in pairs(frame.args) do args[k] = v end
    end
    return args
end
 
-- Безопасная загрузка JSON
local function loadData(args)
     local dataParam = args['данные'] or args[1]
     if not dataParam or dataParam == '' then
     if not dataParam or dataParam == '' then
         error('Не указано имя базы данных или страница JSON (параметр 1 или |данные=)')
         error('Не указано имя базы данных или страница JSON (параметр 1 или |данные=)')
Строка 13: Строка 28:
     end
     end
      
      
    -- Способ 1: mw.loadJsonData
     local success, jsonData = pcall(mw.loadJsonData, dataPageTitle)
     local success, jsonData = pcall(mw.loadJsonData, dataPageTitle)
     if success and jsonData then
     if success and jsonData then
Строка 19: Строка 33:
     end
     end
      
      
    -- Способ 2: Резервная загрузка текста
     local titleObj = mw.title.new(dataPageTitle)
     local titleObj = mw.title.new(dataPageTitle)
     if titleObj and titleObj.exists then
     if titleObj and titleObj.exists then
Строка 32: Строка 45:
                 return decodedData
                 return decodedData
             else
             else
                 error('Ошибка в синтаксисе JSON на странице [[' .. dataPageTitle .. ']]! Проверьте запятые и кавычки.')
                 error('Ошибка в синтаксисе JSON на странице [[' .. dataPageTitle .. ']]!')
             end
             end
         end
         end
     end
     end
      
      
     error('Страница данных [[' .. dataPageTitle .. ']] не найдена. Убедитесь, что она создана.')
     error('Страница данных [[' .. dataPageTitle .. ']] не найдена.')
end
end


-- Генерация кода <imagemap>
-- Генерация кода <imagemap> с учётом ширины
local function buildImageMap(jsonData, imageFile, width, defaultRadius)
local function buildImageMap(jsonData, imageFile, width, defaultRadius)
     local radius = defaultRadius or '16'
     local radius = defaultRadius or '16'
     local mapText = 'Файл:' .. imageFile .. '|' .. width .. '|center|alt=' .. (jsonData.title or 'Схема скоростного транспорта Муроморска') .. '\n'
     local mapText = 'Файл:' .. imageFile .. '|' .. width .. '|center|alt=' .. (jsonData.title or 'Схема транспорта') .. '\n'
      
      
     for _, line in ipairs(jsonData.lines or {}) do
     for _, line in ipairs(jsonData.lines or {}) do
Строка 62: Строка 75:
end
end


-- Названия категорий транспорта
local function getModeLabel(mode)
local function getModeLabel(mode)
     local modes = {
     local modes = {
Строка 72: Строка 84:
end
end


-- Рендеринг схемы
function p.render(frame)
function p.render(frame)
     local args = frame:getParent().args
     local args = getArgs(frame)
    if not args['данные'] and not frame.args['данные'] then
     local jsonData = loadData(args)
        args = frame.args
    end
 
     local jsonData = loadData(frame)
    local isInfobox = (args['карточка'] == 'да' or args['тип'] == 'карточка' or frame.args['карточка'] == 'да')
      
      
    local isInfobox = (args['карточка'] == 'да' or args['тип'] == 'карточка')
     local defaultWidth = isInfobox and '280px' or '850px'
     local defaultWidth = isInfobox and '280px' or '850px'
   
    -- Ширина теперь строго приоритезирует параметр вызова, затем режим карточки
    local width = args['ширина'] or (isInfobox and '280px') or jsonData.width or '850px'
     local imageFile = args['файл'] or jsonData.image or 'Схема_Муроморского_метрополитена.png'
     local imageFile = args['файл'] or jsonData.image or 'Схема_Муроморского_метрополитена.png'
    local width = args['ширина'] or (not isInfobox and jsonData.width) or defaultWidth
     local caption = args['подпись'] or jsonData.caption or ''
     local caption = args['подпись'] or jsonData.caption or ''
     local defaultRadius = args['радиус'] or jsonData.defaultRadius or '16'
     local defaultRadius = args['радиус'] or jsonData.defaultRadius or '16'
Строка 97: Строка 106:
         })
         })


     -- 1. Карточка карты с imagemap
     -- Контейнер карты
     local mapCard = root:tag('div')
     local mapCard = root:tag('div')
         :addClass('ts-transport-map-card')
         :addClass('ts-transport-map-card')
Строка 132: Строка 141:
     end
     end


     -- В режиме карточки (инфобокса) скрываем громоздкую легенду и реестр
     -- Легенда и список выводятся только вне карточки инфобокса
     if not isInfobox then
     if not isInfobox then
        -- 2. Легенда линий
         if jsonData.lines and #jsonData.lines > 0 then
         if jsonData.lines and #jsonData.lines > 0 then
             local legend = root:tag('div')
             local legend = root:tag('div')
Строка 153: Строка 161:
                     ['color'] = '#57606a',
                     ['color'] = '#57606a',
                     ['text-transform'] = 'uppercase',
                     ['text-transform'] = 'uppercase',
                     ['margin-bottom'] = '6px',
                     ['margin-bottom'] = '6px'
                    ['letter-spacing'] = '0.5px'
                 })
                 })
                 :wikitext(jsonData.legendTitle or 'Линии скоростного транспорта')
                 :wikitext(jsonData.legendTitle or 'Линии скоростного транспорта')
Строка 200: Строка 207:
         end
         end


        -- 3. Каталог станций
         if jsonData.lines and #jsonData.lines > 0 then
         if jsonData.lines and #jsonData.lines > 0 then
             local listCard = root:tag('div')
             local listCard = root:tag('div')
Строка 209: Строка 215:
                     ['text-align'] = 'left',
                     ['text-align'] = 'left',
                     ['background'] = 'var(--background-color-neutral-subtle, #f8f9fa)',
                     ['background'] = 'var(--background-color-neutral-subtle, #f8f9fa)',
                     ['border'] = '1px solid var(--border-color-base, #d0d7de)',
                     ['border'] = '1px solid #d0d7de',
                     ['border-radius'] = '8px',
                     ['border-radius'] = '8px',
                     ['overflow'] = 'hidden'
                     ['overflow'] = 'hidden'
Строка 220: Строка 226:
                     ['background'] = 'linear-gradient(180deg, #f6f8fa 0%, #eaeef2 100%)',
                     ['background'] = 'linear-gradient(180deg, #f6f8fa 0%, #eaeef2 100%)',
                     ['padding'] = '9px 14px',
                     ['padding'] = '9px 14px',
                     ['border-bottom'] = '1px solid var(--border-color-base, #d0d7de)'
                     ['border-bottom'] = '1px solid #d0d7de'
                 })
                 })
                 :wikitext(jsonData.listTitle or '📋 Реестр станций метрополитена и МЖД')
                 :wikitext(jsonData.listTitle or '📋 Реестр станций')


             local listContent = listCard:tag('div')
             local listContent = listCard:tag('div')