Modul:Link: Unterschied zwischen den Versionen
Keine Bearbeitungszusammenfassung |
Keine Bearbeitungszusammenfassung |
||
| (11 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
| Zeile 1: | Zeile 1: | ||
local p = {} | local p = {} | ||
| Zeile 6: | Zeile 5: | ||
local DEFAULT_LIMIT = 220 | local DEFAULT_LIMIT = 220 | ||
local function trim(s) | 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 | end | ||
local function | -- Info per Key, deutschem Titel oder Alias finden | ||
local function find_info(term) | |||
local key = normalize_key(term) | |||
-- 1) direkter Key | |||
return | 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 | ||
local function strip_links(txt) | local function strip_links(txt) | ||
txt = txt or '' | txt = txt or '' | ||
txt = txt:gsub('%[%[([^%]|%]]-)|([^\]]-)%]%]', '%2') | txt = txt:gsub('%[%[([^%]|%]]-)|([^\]]-)%]%]', '%2') | ||
txt = txt:gsub('%[%[([^%]]-)%]%]', function(inner) return inner:gsub('_',' ') end) | txt = txt:gsub('%[%[([^%]]-)%]%]', function(inner) return inner:gsub('_',' ') end) | ||
txt = txt:gsub('%[(https?://[^%s%]]+)%s+([^\]]-)%]', '%2') | txt = txt:gsub('%[(https?://[^%s%]]+)%s+([^\]]-)%]', '%2') | ||
txt = txt:gsub('%[(https?://[^%]]+)%]', '%1') | txt = txt:gsub('%[(https?://[^%]]+)%]', '%1') | ||
return txt | return txt | ||
end | end | ||
| Zeile 39: | Zeile 51: | ||
local function htmlize_plain(txt) | local function htmlize_plain(txt) | ||
txt = tostring(txt or '') | txt = mw.text.encode(tostring(txt or '')) | ||
return txt:gsub('\n','<br/>') | |||
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 = | display = trim(display or '') | ||
if display ~= '' | if allow_trail and not target:find('#') then | ||
return '[[' .. target .. ']]' | |||
end | |||
return (display ~= '' and ('[['..target..'|'..display..']]') or ('[['..target..']]')) | |||
end | end | ||
local function render_hover(link_wt, info, limit) | |||
local function render_hover( | |||
if not info or (not info.title and not info.desc and not info.icon) then | if not info or (not info.title and not info.desc and not info.icon) then | ||
return | return link_wt | ||
end | end | ||
local wrap = mw.html.create('span'):addClass(' | local wrap = mw.html.create('span'):addClass('fs-tt') | ||
wrap:wikitext( | wrap:wikitext(link_wt) | ||
local content = mw.html.create('span'):addClass(' | local content = mw.html.create('span'):addClass('tt-content') | ||
local box = mw.html.create('span'):addClass(' | local box = mw.html.create('span'):addClass('tt-box') | ||
-- Icon (ohne Link) | |||
if info.icon and info.icon ~= '' then | if info.icon and info.icon ~= '' then | ||
box:wikitext('[[File:' .. info.icon .. '| | box:wikitext('[[File:' .. info.icon .. '|48x48px|link=]]') | ||
end | end | ||
-- 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 '' | ||
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 | 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: | box:wikitext(text_html) | ||
content:node(box) | content:node(box) | ||
wrap:node(content) | wrap:node(content) | ||
| Zeile 87: | Zeile 106: | ||
end | end | ||
-- === VIEW = | -- 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'):wikitext(desc or '') | |||
return tostring(tbl) | return tostring(tbl) | ||
end | end | ||
| Zeile 116: | Zeile 150: | ||
if target == '' then return '' end | if target == '' then return '' end | ||
local p2 = | local p2 = trim(args[2] or '') | ||
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 | 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 129: | Zeile 179: | ||
return render_view(info or {}) | return render_view(info or {}) | ||
else | else | ||
local | -- 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) | return render_hover(link_wt, info or {}, limit) | ||
end | end | ||
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