Module:UnitLinker: Difference between revisions

From Heroes of Might and Magic: Olden Era Official Wiki
Created page with "local p = {} -- Fonction pour déterminer la langue à partir du titre de la page local function getLanguage() local title = mw.title.getCurrentTitle().text local lang = mw.ustring.match(title, "/([a-z_]+)$") if not lang or lang == "en" then return "en" end return lang end -- Fonction pour vérifier si un nom d'unité est valide et obtenir son nom anglais de base local function resolveUnit(name) -- Recherche dans la table Translation pour trouver le..."
 
No edit summary
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
local p = {}
local p = {}


-- Fonction pour déterminer la langue à partir du titre de la page
-- Charge la table de correspondance en mémoire avec filtrage strict
local function getLanguage()
local function getUnitRegistry(lang)
    local title = mw.title.getCurrentTitle().text
     local registry = {}
    local lang = mw.ustring.match(title, "/([a-z_]+)$")
     if not lang or lang == "en" then return "en" end
    return lang
end
 
-- Fonction pour vérifier si un nom d'unité est valide et obtenir son nom anglais de base
local function resolveUnit(name)
    -- Recherche dans la table Translation pour trouver le nom anglais (target_id)
    -- si le nom fourni est déjà une traduction
    local res = mw.ext.cargo.query("Translation", "target_id", {
        where = "type = 'unit' AND name = '" .. name .. "'",
        limit = 1
    })
      
      
     if res and #res > 0 then return res[1].target_id end
     -- On ajoute bien 'type = "unit"' pour garantir l'unicité du contexte
    local query = "type = 'unit' AND (language = 'en' OR language = '" .. lang .. "')"
      
      
     -- Sinon, vérifier si le nom est déjà un nom anglais valide dans la table Unit
     -- On récupère target_id et name
     local unitCheck = mw.ext.cargo.query("Unit", "id", { where = "id = '" .. name .. "'", limit = 1 })
     local results = mw.ext.cargo.query("Translation", "target_id, name", {  
    if unitCheck and #unitCheck > 0 then return name end
        where = query,
        -- On définit un orderBy pour que les traductions écrasent éventuellement
        -- les entrées en double si nécessaire, bien que le type 'unit' devrait suffire
        orderBy = "language DESC"  
    })
      
      
     return nil
    for _, row in ipairs(results) do
        -- row.name est le nom détectable (ex: "Swordsman" ou "Épéiste")
        -- row.target_id est la référence unique (ex: "Swordsman")
        if row.name and row.target_id then
            registry[row.name] = row.target_id
        end
    end
     return registry
end
end


-- Fonction principale appelée par {{#invoke:UnitLinker|link|Ton texte ici}}
function p.link(frame)
function p.link(frame)
     local text = frame.args[1] or ""
     local text = frame.args[1] or ""
     local lang = getLanguage()
     if not text or text == "" then return "" end
      
      
     -- On utilise une fonction de remplacement globale
     local title = mw.title.getCurrentTitle().text
     local processedText = mw.ustring.gsub(text, "([%a%s]+)", function(match)
     local lang = mw.ustring.match(title, "/([a-z_]+)$") or "en"
         local unitName = mw.text.trim(match)
   
         local baseName = resolveUnit(unitName)
    local registry = getUnitRegistry(lang)
   
    -- Trier par longueur décroissante pour traiter "Temple Swordsman" avant "Swordsman"
    local keys = {}
    for k in pairs(registry) do table.insert(keys, k) end
    table.sort(keys, function(a, b) return #a > #b end)
   
    -- Remplacement
    for _, unitName in ipairs(keys) do
         local engName = registry[unitName]
       
        -- Construction du lien
        local target = (lang == "en") and engName or (engName .. "/" .. lang)
         local link = "[[" .. target .. "|" .. unitName .. "]]"
          
          
         if baseName then
         -- Pattern pour éviter de casser des liens existants
            -- Si anglais, lien simple
        -- On cherche le nom de l'unité avec des frontières de mot
            if lang == "en" then
        local escapedName = mw.ustring.gsub(unitName, "([%(%)%.%%%+%-%*%?%[%^%$])", "%%%1")
                return "[[" .. baseName .. "]]"
        local pattern = "(%f[%a])" .. escapedName .. "(%f[%A])"
            else
       
                -- Si autre langue, on cherche le nom traduit pour le display
        text = mw.ustring.gsub(text, pattern, function(prefix, suffix)
                local trans = mw.ext.cargo.query("Translation", "name", {
            -- Si le texte contient déjà [[ devant, on ne touche à rien
                    where = "type = 'unit' AND target_id = '" .. baseName .. "' AND language = '" .. lang .. "'",
            if mw.ustring.find(text, "%[%[" .. escapedName) then return prefix .. unitName .. suffix end
                    limit = 1
            return prefix .. link .. suffix
                })
         end)
                local displayName = (trans and #trans > 0) and trans[1].name or unitName
     end
                return "[[" .. baseName .. "/" .. lang .. "|" .. displayName .. "]]"
            end
         end
        return match
     end)
      
      
     return processedText
     return text
end
end


return p
return p

Latest revision as of 15:44, 13 June 2026

Documentation for this module may be created at Module:UnitLinker/doc

local p = {}

-- Charge la table de correspondance en mémoire avec filtrage strict
local function getUnitRegistry(lang)
    local registry = {}
    
    -- On ajoute bien 'type = "unit"' pour garantir l'unicité du contexte
    local query = "type = 'unit' AND (language = 'en' OR language = '" .. lang .. "')"
    
    -- On récupère target_id et name
    local results = mw.ext.cargo.query("Translation", "target_id, name", { 
        where = query,
        -- On définit un orderBy pour que les traductions écrasent éventuellement 
        -- les entrées en double si nécessaire, bien que le type 'unit' devrait suffire
        orderBy = "language DESC" 
    })
    
    for _, row in ipairs(results) do
        -- row.name est le nom détectable (ex: "Swordsman" ou "Épéiste")
        -- row.target_id est la référence unique (ex: "Swordsman")
        if row.name and row.target_id then
            registry[row.name] = row.target_id
        end
    end
    return registry
end

function p.link(frame)
    local text = frame.args[1] or ""
    if not text or text == "" then return "" end
    
    local title = mw.title.getCurrentTitle().text
    local lang = mw.ustring.match(title, "/([a-z_]+)$") or "en"
    
    local registry = getUnitRegistry(lang)
    
    -- Trier par longueur décroissante pour traiter "Temple Swordsman" avant "Swordsman"
    local keys = {}
    for k in pairs(registry) do table.insert(keys, k) end
    table.sort(keys, function(a, b) return #a > #b end)
    
    -- Remplacement
    for _, unitName in ipairs(keys) do
        local engName = registry[unitName]
        
        -- Construction du lien
        local target = (lang == "en") and engName or (engName .. "/" .. lang)
        local link = "[[" .. target .. "|" .. unitName .. "]]"
        
        -- Pattern pour éviter de casser des liens existants
        -- On cherche le nom de l'unité avec des frontières de mot
        local escapedName = mw.ustring.gsub(unitName, "([%(%)%.%%%+%-%*%?%[%^%$])", "%%%1")
        local pattern = "(%f[%a])" .. escapedName .. "(%f[%A])"
        
        text = mw.ustring.gsub(text, pattern, function(prefix, suffix)
            -- Si le texte contient déjà [[ devant, on ne touche à rien
            if mw.ustring.find(text, "%[%[" .. escapedName) then return prefix .. unitName .. suffix end
            return prefix .. link .. suffix
        end)
    end
    
    return text
end

return p