Split combined trade-fair bookmark links and add shared-ticket notes

This commit is contained in:
2026-02-21 20:02:43 +01:00
parent 758ffd158f
commit 4b1e935000
2 changed files with 79 additions and 26 deletions

View File

@@ -1944,6 +1944,18 @@ h1 {
text-align: left; text-align: left;
} }
.bookmark-subpage__messe-links {
display: inline-flex;
flex-wrap: wrap;
align-items: center;
row-gap: 2px;
}
.bookmark-subpage__messe-separator {
color: #6b7280;
margin: 0 2px;
}
.bookmark-subpage__messe-link:hover { .bookmark-subpage__messe-link:hover {
color: #1d4ed8; color: #1d4ed8;
} }

View File

@@ -222,6 +222,7 @@
{ {
rang: 11, rang: 11,
messe: 'Leipziger Buchmesse / Manga Comic Con', messe: 'Leipziger Buchmesse / Manga Comic Con',
bookmark_suchbegriffe: ['Leipziger Buchmesse', 'Manga Comic Con'],
thema: 'Buchmarkt, Medien, Manga/Comic', thema: 'Buchmarkt, Medien, Manga/Comic',
stadt: 'Leipzig', stadt: 'Leipzig',
bundesland: 'Sachsen', bundesland: 'Sachsen',
@@ -233,7 +234,7 @@
ausstellungsflaeche_m2: 20788, ausstellungsflaeche_m2: 20788,
ticketpreis_we_eur: 35, ticketpreis_we_eur: 35,
ticketpreis_unterderwoche_eur: 28, ticketpreis_unterderwoche_eur: 28,
notiz: 'Ticketpreise laut offizieller Leipzig-Messe-Preisliste 2026 (Sa am hoechsten).', notiz: 'Ein Ticket gilt fuer Leipziger Buchmesse und Manga Comic Con (parallel, inkl. Antiquariatsmesse).',
quelle_homepage: 'https://www.leipziger-buchmesse.de' quelle_homepage: 'https://www.leipziger-buchmesse.de'
}, },
{ {
@@ -391,7 +392,8 @@
}, },
{ {
rang: 21, rang: 21,
messe: 'f.re.e München', messe: 'f.re.e München / IMOT',
bookmark_suchbegriffe: ['f.re.e München', 'IMOT'],
thema: 'Reisen, Freizeit, Caravaning, Outdoor', thema: 'Reisen, Freizeit, Caravaning, Outdoor',
stadt: 'München', stadt: 'München',
bundesland: 'Bayern', bundesland: 'Bayern',
@@ -403,7 +405,7 @@
ausstellungsflaeche_m2: null, ausstellungsflaeche_m2: null,
ticketpreis_we_eur: 17, ticketpreis_we_eur: 17,
ticketpreis_unterderwoche_eur: 14, ticketpreis_unterderwoche_eur: 14,
notiz: 'Preisniveau aus zuletzt veroeffentlichtem Ticketstand (Wochenende hoeher).', notiz: 'Ein Ticket gilt fuer f.re.e und IMOT (sowie meist auch Muenchner Auto Tage) laut offiziellem Ticketshop.',
quelle_homepage: 'https://free-muenchen.de' quelle_homepage: 'https://free-muenchen.de'
}, },
{ {
@@ -459,7 +461,8 @@
}, },
{ {
rang: 25, rang: 25,
messe: 'Heim+Handwerk', messe: 'Heim+Handwerk / FOOD & LIFE',
bookmark_suchbegriffe: ['Heim+Handwerk', 'FOOD & LIFE'],
thema: 'Wohnen, Handwerk, Lifestyle', thema: 'Wohnen, Handwerk, Lifestyle',
stadt: 'München', stadt: 'München',
bundesland: 'Bayern', bundesland: 'Bayern',
@@ -471,7 +474,7 @@
ausstellungsflaeche_m2: null, ausstellungsflaeche_m2: null,
ticketpreis_we_eur: 15, ticketpreis_we_eur: 15,
ticketpreis_unterderwoche_eur: 15, ticketpreis_unterderwoche_eur: 15,
notiz: 'Ticketpreis als zuletzt verfuegbares Preisniveau; finale 2026-Staffel folgt i.d.R. spaeter.', notiz: 'Ein Ticket gilt fuer Heim+Handwerk und FOOD & LIFE (parallel in Muenchen).',
quelle_homepage: 'https://www.heim-handwerk.de' quelle_homepage: 'https://www.heim-handwerk.de'
}, },
{ {
@@ -493,7 +496,8 @@
}, },
{ {
rang: 27, rang: 27,
messe: 'Reise + Camping Essen', messe: 'Reise + Camping Essen / Fahrrad Essen',
bookmark_suchbegriffe: ['Reise + Camping Essen', 'Fahrrad Essen'],
thema: 'Reisen, Camping, Fahrrad, Outdoor', thema: 'Reisen, Camping, Fahrrad, Outdoor',
stadt: 'Essen', stadt: 'Essen',
bundesland: 'Nordrhein-Westfalen', bundesland: 'Nordrhein-Westfalen',
@@ -505,7 +509,7 @@
ausstellungsflaeche_m2: null, ausstellungsflaeche_m2: null,
ticketpreis_we_eur: 12, ticketpreis_we_eur: 12,
ticketpreis_unterderwoche_eur: 12, ticketpreis_unterderwoche_eur: 12,
notiz: 'Online-Tagesticket laut Messe-Essen-Presse (EUR 12).', notiz: 'Ein Ticket gilt fuer Reise + Camping und Fahrrad Essen (parallel in den Messehallen).',
quelle_homepage: 'https://www.reise-camping.de' quelle_homepage: 'https://www.reise-camping.de'
}, },
{ {
@@ -1021,14 +1025,28 @@
return td; return td;
} }
function buildTradeFairBaseQuery(row) { function getTradeFairBookmarkQueries(row) {
const base = String(row.messe || '').trim(); if (Array.isArray(row.bookmark_suchbegriffe) && row.bookmark_suchbegriffe.length) {
if (base) { return [...new Set(
return base; row.bookmark_suchbegriffe
.map((entry) => String(entry || '').trim())
.filter(Boolean)
)];
} }
const fallback = [row.messe, row.stadt].map((value) => String(value || '').trim()).filter(Boolean).join(' '); const messe = String(row.messe || '').trim();
return fallback.trim(); if (!messe) {
return [];
}
if (messe.includes(' / ')) {
const split = messe.split(' / ').map((part) => part.trim()).filter(Boolean);
if (split.length > 1) {
return [...new Set(split)];
}
}
return [messe];
} }
function openBookmarkLikeFallback(baseQuery) { function openBookmarkLikeFallback(baseQuery) {
@@ -1060,8 +1078,10 @@
return opened; return opened;
} }
function openTradeFairSearch(row) { function openTradeFairSearch(row, explicitBaseQuery) {
const baseQuery = buildTradeFairBaseQuery(row); const baseQuery = explicitBaseQuery
? String(explicitBaseQuery).trim()
: getTradeFairBookmarkQueries(row)[0];
if (!baseQuery) { if (!baseQuery) {
return 0; return 0;
} }
@@ -1084,19 +1104,40 @@
function createMesseCell(row) { function createMesseCell(row) {
const td = document.createElement('td'); const td = document.createElement('td');
td.dataset.column = 'messe'; td.dataset.column = 'messe';
const bookmarkQueries = getTradeFairBookmarkQueries(row);
if (!bookmarkQueries.length) {
td.textContent = row.messe || 'k.A.';
return td;
}
const linksWrap = document.createElement('div');
linksWrap.className = 'bookmark-subpage__messe-links';
bookmarkQueries.forEach((query, index) => {
const button = document.createElement('button'); const button = document.createElement('button');
button.type = 'button'; button.type = 'button';
button.className = 'bookmark-subpage__messe-link'; button.className = 'bookmark-subpage__messe-link';
button.textContent = row.messe || 'k.A.'; button.textContent = query;
button.title = getTradeFairHoverTitle(row); button.title = getTradeFairHoverTitle(row);
button.addEventListener('click', () => { button.addEventListener('click', () => {
const opened = openTradeFairSearch(row); const opened = openTradeFairSearch(row, query);
if (opened > 0) { if (opened > 0) {
button.title = getTradeFairHoverTitle(row); button.title = getTradeFairHoverTitle(row);
render(); render();
} }
}); });
td.appendChild(button); linksWrap.appendChild(button);
if (index < bookmarkQueries.length - 1) {
const separator = document.createElement('span');
separator.className = 'bookmark-subpage__messe-separator';
separator.textContent = ' / ';
linksWrap.appendChild(separator);
}
});
td.appendChild(linksWrap);
return td; return td;
} }