Modul:Link: Unterschied zwischen den Versionen
Keine Bearbeitungszusammenfassung  | 
				Keine Bearbeitungszusammenfassung  | 
				||
| (8 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
| Zeile 1: | Zeile 1: | ||
local p = {}  | local p = {}  | ||
| Zeile 10: | Zeile 9: | ||
   s = US.lower(trim(s or '')):gsub('_',' '):gsub('%s+',' ')  |    s = US.lower(trim(s or '')):gsub('_',' '):gsub('%s+',' ')  | ||
   return s  |    return s  | ||
end  | |||
-- Info per Key, deutschem Titel oder Alias finden  | |||
local function find_info(term)  | |||
  local key = normalize_key(term)  | |||
  -- 1) direkter Key  | |||
  local bykey = data[key] or data[key:gsub(' ','_')]  | |||
  if bykey then return bykey end  | |||
  -- 2) Titel oder Aliases  | |||
  for _, entry in pairs(data) do  | |||
    if entry.title and normalize_key(entry.title) == key then  | |||
      return entry  | |||
    end  | |||
    if entry.aliases then  | |||
      for _, a in ipairs(entry.aliases) do  | |||
        if normalize_key(a) == key then return entry end  | |||
      end  | |||
    end  | |||
  end  | |||
  return nil  | |||
end  | end  | ||
| Zeile 36: | Zeile 55: | ||
end  | end  | ||
local function make_link(target, display)  | -- Angepasst: allow_trail lässt unpiped [[Ziel]] zu (für MediaWiki-LinkTrail)  | ||
local function make_link(target, display, allow_trail)  | |||
   target  = trim(target)  |    target  = trim(target)  | ||
   display = trim(display or '')  |    display = trim(display or '')  | ||
   return display ~= '' and ('[['..target..'|'..display..']]') or ('[['..target..']]')  |   if allow_trail and not target:find('#') then  | ||
    return '[[' .. target .. ']]'  | |||
  end  | |||
   return (display ~= '' and ('[['..target..'|'..display..']]') or ('[['..target..']]'))  | |||
end  | end  | ||
| Zeile 55: | Zeile 78: | ||
   -- Icon (ohne Link)  |    -- Icon (ohne Link)  | ||
   if info.icon and info.icon ~= '' then  |    if info.icon and info.icon ~= '' then  | ||
     box:wikitext('[[File:' .. info.icon .. '|48x48px|link=  |      box:wikitext('[[File:' .. info.icon .. '|48x48px|link=]]')  | ||
   end  |    end  | ||
   -- Titel + Beschreibung (gekürzt & link-bereinigt)   |    -- Titel + Beschreibung (gekürzt & link-bereinigt)  | ||
   local title = info.title or ''  |    local title = info.title or ''  | ||
   local desc  = info.desc  or ''  |    local desc  = info.desc  or ''  | ||
| Zeile 67: | Zeile 88: | ||
   local function esc(s)  |    local function esc(s)  | ||
     s = tostring(s or '')  |      s = tostring(s or '')  | ||
     s = mw.text.encode(s)   |      s = mw.text.encode(s)  | ||
     s = s:gsub('\n','<br/>')  |      s = s:gsub('\n','<br/>')  | ||
     return s  |      return s  | ||
| Zeile 85: | Zeile 106: | ||
end  | end  | ||
-- Helper: Anchor-ID nur aus dem Title, Spaces -> "_"  | |||
local function anchor_id_from_title(title)  | |||
  local t = mw.text.trim(title or '')  | |||
  if t == '' then return nil end  | |||
  return mw.ustring.gsub(t, '%s+', '_')  | |||
end  | |||
-- VIEW: wikitable mit id + width="100%"  | |||
local function render_view(info)  | local function render_view(info)  | ||
   local title = info and info.title or ''  |    local title = (info and info.title) or ''  | ||
   local desc  = info and info.desc  or ''  |    local desc  = (info and info.desc)  or ''  | ||
   local icon  = info and info.icon  or ''  |    local icon  = (info and info.icon)  or ''  | ||
  local id    = anchor_id_from_title(title)  | |||
  local tbl = mw.html.create('table')  | |||
    :addClass('wikitable')  | |||
    :attr('width', '100%')  | |||
  if id then  | |||
    tbl:attr('id', id)  | |||
  end  | |||
   local trh = tbl:tag('tr')  |    local trh = tbl:tag('tr')  | ||
   trh:tag('th'):attr('colspan','2'):wikitext(title ~= '' and title or ' ')  |    trh:tag('th'):attr('colspan','2'):wikitext(title ~= '' and title or ' ')  | ||
   local tr = tbl:tag('tr')  |    local tr = tbl:tag('tr')  | ||
   local tdIcon = tr:tag('td'):  |    local tdIcon = tr:tag('td'):attr('width','110'):attr('align','center')  | ||
   if icon ~= '' then  |    if icon ~= '' then  | ||
     tdIcon:wikitext('[[File:'..icon..'|  |      tdIcon:wikitext('[[File:'..icon..'|x64px|link=]]')  | ||
   else  |    else  | ||
     tdIcon:wikitext(' ')  |      tdIcon:wikitext(' ')  | ||
   end  |    end  | ||
   tr:tag('td  | |||
   tr:tag('td'):wikitext(desc or '')  | |||
   return tostring(tbl)  |    return tostring(tbl)  | ||
end  | end  | ||
| Zeile 115: | Zeile 153: | ||
   local mode_view = (US.lower(p2) == 'view')  |    local mode_view = (US.lower(p2) == 'view')  | ||
   local key = trim(args.key or (mode_view and target or (p2 ~= '' and p2 or target)))  |    local key = trim(args.key or (mode_view and target or (p2 ~= '' and p2 or target)))  | ||
   local info = data[normalize_key(key)] or data[normalize_key(key):gsub(' ','_')]  |    local info = data[normalize_key(key)] or data[normalize_key(key):gsub(' ','_')]  | ||
  if not info then  | |||
    -- per deutschem Titel / evtl. Aliases suchen  | |||
    local function find_info(term)  | |||
      local k = normalize_key(term)  | |||
      local bykey = data[k] or data[k:gsub(' ','_')]  | |||
      if bykey then return bykey end  | |||
      for _, entry in pairs(data) do  | |||
        if entry.title and normalize_key(entry.title) == k then return entry end  | |||
        if entry.aliases then  | |||
          for _,a in ipairs(entry.aliases) do  | |||
            if normalize_key(a) == k then return entry end  | |||
          end  | |||
        end  | |||
      end  | |||
      return nil  | |||
    end  | |||
    info = find_info(target)  | |||
  end  | |||
   local limit = tonumber(args.limit or '') or DEFAULT_LIMIT  |    local limit = tonumber(args.limit or '') or DEFAULT_LIMIT  | ||
| Zeile 124: | Zeile 179: | ||
     return render_view(info or {})  |      return render_view(info or {})  | ||
   else  |    else  | ||
     -- 1) expliziter Anzeigename (2. Param, sofern nicht 'view')  | |||
    local explicit_display = (p2 ~= '' and US.lower(p2) ~= 'view') and p2 or nil  | |||
    -- 2) Suffix-Unterstützung: |s=… oder Kurzform |+… im 2. Param  | |||
    local suffix = trim(args.s or '')  | |||
    if suffix == '' and explicit_display and explicit_display:sub(1,1) == '+' then  | |||
      suffix = explicit_display:sub(2)  | |||
      explicit_display = nil  | |||
    end  | |||
    local baseTitle = (info and info.title) or target  | |||
    local display = explicit_display or (suffix ~= '' and (baseTitle .. suffix)) or (info and info.title) or nil  | |||
    -- LinkTrail erlauben, wenn kein eigener Display gesetzt wurde  | |||
    -- und target == Titel (ohne Anker)  | |||
    local allow_trail = (explicit_display == nil and suffix == '')  | |||
      and info and info.title  | |||
      and (normalize_key(target) == normalize_key(info.title))  | |||
      and not target:find('#')  | |||
    local link_wt = make_link(target, display, allow_trail)  | |||
    return render_hover(link_wt, info or {}, limit)  | |||
   end  |    end  | ||
end  | end  | ||
return p  | return p  | ||
Aktuelle Version vom 27. Oktober 2025, 09:08 Uhr
Erzeugt interne Links mit Hover-Tooltip (Icon, Titel, Kurzbeschreibung) aus Modul:LinkData. Optional kann eine „Detailansicht“ (Wikitable) ausgegeben werden.
Grundsyntax
- Tooltip-Link
 {{Link|Ziel}}
- Tooltip-Link mit eigenem Anzeigenamen
 {{Link|Ziel|Anzeigename}}
- Detailansicht (Tabelle) statt Link
 {{Link|Ziel|view}}
Parameter
| Param | Name | Typ/Standard | Beschreibung | 
|---|---|---|---|
| 1 | Ziel | Pflicht | Seitentitel oder „Titel#Abschnitt“. Wird als Linkziel verwendet. | 
| 2 | Anzeigename / view / Kurz-Suffix | 
optional | 
  | 
| s | s (Suffix) | 
optional | Hängt Text an den Anzeigenamen aus LinkData an (z. B. s=e → „Biere“).
 | 
| key | key | 
optional | Erzwingt den Datensatz-Schlüssel für LinkData (falls Ziel und title nicht übereinstimmen).
 | 
| limit | limit | 
Zahl (220) | Maximale Länge der Tooltip-Beschreibung; bei Überschreitung wird abgeschnitten (…). | 
Verhalten
Anzeigename
- Standardmäßig wird als Anzeigename der deutsche Titel aus Modul:LinkData verwendet (Feld 
title). - Eigener Anzeigename (2. Parameter) überschreibt den Titel.
 - Groß-/Kleinschreibung bleibt genau wie im Wikitext/LinkData.
 
Plural / LinkTrail
MediaWikis LinkTrail funktioniert nur bei direkt geschriebenen Links, nicht bei Vorlagen. Dafür gibt es zwei Wege:
- Suffix-Kurzform im 2. Parameter:
 
{{Link|Bier|+e}}→Biere
BierBier schaltet sich auf Charakterlevel 15 frei. Biere droppen mit einer Rate von 1 Bier pro 28,8 Sekunden auf dem Schlachtfeld (entspricht 3000 Bier pro Tag). Zusätzlich ist Bier als mögliche Belohnung aus T…{{Link|Bier|+en}}→Bieren
BierBier schaltet sich auf Charakterlevel 15 frei. Biere droppen mit einer Rate von 1 Bier pro 28,8 Sekunden auf dem Schlachtfeld (entspricht 3000 Bier pro Tag). Zusätzlich ist Bier als mögliche Belohnung aus T…
- Expliziter Suffix über 
s=: 
{{Link|Bier|s=e}}→Biere
BierBier schaltet sich auf Charakterlevel 15 frei. Biere droppen mit einer Rate von 1 Bier pro 28,8 Sekunden auf dem Schlachtfeld (entspricht 3000 Bier pro Tag). Zusätzlich ist Bier als mögliche Belohnung aus T…
Hinweise:
- Sobald ein eigener Anzeigename gesetzt ist, wird 
s=ignoriert. - Bei „unpiped“ Links (also wirklich 
Biere) greift LinkTrail – das ist mit Vorlagen technisch nicht möglich. Nutze dahers=/+…. 
Anker/Abschnitte
- Bei Zielen mit 
#(z. B.Währungen#Bier) wird immer ein gepipter Link erzeugt (kein LinkTrail / ToolTip möglich). - Die Detailansicht (
view) setzt die Tabellen-IDanhand des Titels (Leerzeichen → Unterstrich). 
Tooltip
- Holt 
title/icon/descaus Modul:LinkData. - Links in der Beschreibung werden im Hover-Tooltip zu normalem Text neutralisiert.
 - Zeilenumbrüche werden unterstützt; lange Texte werden nach 
limitZeichen abgeschnitten. 
Fallbacks
- Gibt es keinen Datensatz in LinkData, wird ein normaler Link ohne Tooltip ausgegeben.
 
Beispiele
- Standard
 {{Link|Bier}}→ Bier
BierBier schaltet sich auf Charakterlevel 15 frei. Biere droppen mit einer Rate von 1 Bier pro 28,8 Sekunden auf dem Schlachtfeld (entspricht 3000 Bier pro Tag). Zusätzlich ist Bier als mögliche Belohnung aus T…
- Eigener Anzeigename
 {{Link|Währungen#Bier|Bier}}→ Bier
- Plural via Suffix (Kurzform)
 {{Link|Bier|+e}}→ Biere
BierBier schaltet sich auf Charakterlevel 15 frei. Biere droppen mit einer Rate von 1 Bier pro 28,8 Sekunden auf dem Schlachtfeld (entspricht 3000 Bier pro Tag). Zusätzlich ist Bier als mögliche Belohnung aus T…
- Plural via 
s= {{Link|Bier|s=en}}→ Bieren
BierBier schaltet sich auf Charakterlevel 15 frei. Biere droppen mit einer Rate von 1 Bier pro 28,8 Sekunden auf dem Schlachtfeld (entspricht 3000 Bier pro Tag). Zusätzlich ist Bier als mögliche Belohnung aus T…
- Detailansicht (Wikitable)
 {{Link|Bier|view}}→Bier 
Bier schaltet sich auf Charakterlevel 15 frei. Biere droppen mit einer Rate von 1 Bier pro 28,8 Sekunden auf dem Schlachtfeld (entspricht 3000 Bier pro Tag). Zusätzlich ist Bier als mögliche Belohnung aus Taverne-Kartenziehungen erhältlich. Die Anzahl der droppenden Biere kann mit den Cheers-Gildenperks und Kampagnenperks sowie dem Talent „Zwillingsdrachen“ erhöht werden. Bier wird im Taverne-Markt zum Kauf von Spielmarken verwendet. 
- Limit anpassen
 {{Link|Bier|limit=50}}→ Bier
BierBier schaltet sich auf Charakterlevel 15 frei.…
- Abweichender Datensatz (engl. key)
 {{Link|Währungen|key=Beer}}→ Bier
BierBier schaltet sich auf Charakterlevel 15 frei. Biere droppen mit einer Rate von 1 Bier pro 28,8 Sekunden auf dem Schlachtfeld (entspricht 3000 Bier pro Tag). Zusätzlich ist Bier als mögliche Belohnung aus T…
local p = {}
local data = mw.loadData('Modul:LinkData')
local US = mw.ustring
local DEFAULT_LIMIT = 220
local function trim(s) return type(s)=='string' and (s:gsub('^%s+',''):gsub('%s+$','')) or '' end
local function normalize_key(s)
  s = US.lower(trim(s or '')):gsub('_',' '):gsub('%s+',' ')
  return s
end
-- Info per Key, deutschem Titel oder Alias finden
local function find_info(term)
  local key = normalize_key(term)
  -- 1) direkter Key
  local bykey = data[key] or data[key:gsub(' ','_')]
  if bykey then return bykey end
  -- 2) Titel oder Aliases
  for _, entry in pairs(data) do
    if entry.title and normalize_key(entry.title) == key then
      return entry
    end
    if entry.aliases then
      for _, a in ipairs(entry.aliases) do
        if normalize_key(a) == key then return entry end
      end
    end
  end
  return nil
end
local function strip_links(txt)
  txt = txt or ''
  txt = txt:gsub('%[%[([^%]|%]]-)|([^\]]-)%]%]', '%2')
  txt = txt:gsub('%[%[([^%]]-)%]%]', function(inner) return inner:gsub('_',' ') end)
  txt = txt:gsub('%[(https?://[^%s%]]+)%s+([^\]]-)%]', '%2')
  txt = txt:gsub('%[(https?://[^%]]+)%]', '%1')
  return txt
end
local function shorten(txt, limit)
  limit = tonumber(limit) or DEFAULT_LIMIT
  local len = US.len(txt or '')
  if len <= limit then return txt end
  local cut = US.sub(txt, 1, limit)
  local lastSpace = cut:match('^.*()%s')
  if lastSpace and lastSpace > 15 then cut = US.sub(cut, 1, lastSpace - 1) end
  return cut .. '…'
end
local function htmlize_plain(txt)
  txt = mw.text.encode(tostring(txt or ''))
  return txt:gsub('\n','<br/>')
end
-- Angepasst: allow_trail lässt unpiped [[Ziel]] zu (für MediaWiki-LinkTrail)
local function make_link(target, display, allow_trail)
  target  = trim(target)
  display = trim(display or '')
  if allow_trail and not target:find('#') then
    return '[[' .. target .. ']]'
  end
  return (display ~= '' and ('[['..target..'|'..display..']]') or ('[['..target..']]'))
end
local function render_hover(link_wt, info, limit)
  if not info or (not info.title and not info.desc and not info.icon) then
    return link_wt
  end
  local wrap   = mw.html.create('span'):addClass('fs-tt')
  wrap:wikitext(link_wt)
  local content = mw.html.create('span'):addClass('tt-content')
  local box     = mw.html.create('span'):addClass('tt-box')
  -- Icon (ohne Link)
  if info.icon and info.icon ~= '' then
    box:wikitext('[[File:' .. info.icon .. '|48x48px|link=]]')
  end
  -- Titel + Beschreibung (gekürzt & link-bereinigt)
  local title = info.title or ''
  local desc  = info.desc  or ''
  desc = shorten(strip_links(desc), limit)
  local function esc(s)
    s = tostring(s or '')
    s = mw.text.encode(s)
    s = s:gsub('\n','<br/>')
    return s
  end
  local text_html = table.concat({
    '<span class="tt-text">',
      '<span class="tt-title">', esc(title), '</span>',
      '<span class="tt-desc">',  esc(desc),  '</span>',
    '</span>'
  })
  box:wikitext(text_html)
  content:node(box)
  wrap:node(content)
  return tostring(wrap)
end
-- Helper: Anchor-ID nur aus dem Title, Spaces -> "_"
local function anchor_id_from_title(title)
  local t = mw.text.trim(title or '')
  if t == '' then return nil end
  return mw.ustring.gsub(t, '%s+', '_')
end
-- VIEW: wikitable mit id + width="100%"
local function render_view(info)
  local title = (info and info.title) or ''
  local desc  = (info and info.desc)  or ''
  local icon  = (info and info.icon)  or ''
  local id    = anchor_id_from_title(title)
  local tbl = mw.html.create('table')
    :addClass('wikitable')
    :attr('width', '100%')
  if id then
    tbl:attr('id', id)
  end
  local trh = tbl:tag('tr')
  trh:tag('th'):attr('colspan','2'):wikitext(title ~= '' and title or ' ')
  local tr = tbl:tag('tr')
  local tdIcon = tr:tag('td'):attr('width','110'):attr('align','center')
  if icon ~= '' then
    tdIcon:wikitext('[[File:'..icon..'|x64px|link=]]')
  else
    tdIcon:wikitext(' ')
  end
  tr:tag('td'):wikitext(desc or '')
  return tostring(tbl)
end
function p.main(frame)
  local parent = frame:getParent()
  local args = parent and parent.args or frame.args
  local target = trim(args[1] or '')
  if target == '' then return '' end
  local p2 = trim(args[2] or '')
  local mode_view = (US.lower(p2) == 'view')
  local key = trim(args.key or (mode_view and target or (p2 ~= '' and p2 or target)))
  local info = data[normalize_key(key)] or data[normalize_key(key):gsub(' ','_')]
  if not info then
    -- per deutschem Titel / evtl. Aliases suchen
    local function find_info(term)
      local k = normalize_key(term)
      local bykey = data[k] or data[k:gsub(' ','_')]
      if bykey then return bykey end
      for _, entry in pairs(data) do
        if entry.title and normalize_key(entry.title) == k then return entry end
        if entry.aliases then
          for _,a in ipairs(entry.aliases) do
            if normalize_key(a) == k then return entry end
          end
        end
      end
      return nil
    end
    info = find_info(target)
  end
  local limit = tonumber(args.limit or '') or DEFAULT_LIMIT
  if mode_view then
    return render_view(info or {})
  else
    -- 1) expliziter Anzeigename (2. Param, sofern nicht 'view')
    local explicit_display = (p2 ~= '' and US.lower(p2) ~= 'view') and p2 or nil
    -- 2) Suffix-Unterstützung: |s=… oder Kurzform |+… im 2. Param
    local suffix = trim(args.s or '')
    if suffix == '' and explicit_display and explicit_display:sub(1,1) == '+' then
      suffix = explicit_display:sub(2)
      explicit_display = nil
    end
    local baseTitle = (info and info.title) or target
    local display = explicit_display or (suffix ~= '' and (baseTitle .. suffix)) or (info and info.title) or nil
    -- LinkTrail erlauben, wenn kein eigener Display gesetzt wurde
    -- und target == Titel (ohne Anker)
    local allow_trail = (explicit_display == nil and suffix == '')
      and info and info.title
      and (normalize_key(target) == normalize_key(info.title))
      and not target:find('#')
    local link_wt = make_link(target, display, allow_trail)
    return render_hover(link_wt, info or {}, limit)
  end
end
return p