feat: FAKTEN + Bewertungskarte als HTML/CSS statt Grafiken

- .bsn-fakten: 3-Spalten-Grid, mobile-first (1 Spalte auf Handy)
- .bsn-rating-card: dunkelblauer Header, MECHANISMEN/PRO/KONTRA-Spalten, Footer mit Wertung
- CSS in bsn-review.css — ins Joomla-Template einzubinden
- Discord-Modul entfernt, Gallery mit einfachen Klammern
- Alle Stile: mobile-first, globale CSS-Klassen
This commit is contained in:
Hermes Agent
2026-07-13 23:10:03 +02:00
parent 3a26e03510
commit db707f650a
2 changed files with 224 additions and 64 deletions
+48 -64
View File
@@ -2126,64 +2126,42 @@ document.getElementById('publishBtn').addEventListener('click',function(){{submi
autor_name = author_info["name"]
autor_banner = author_info["banner"]
# Infobox-Tabelle
fakten_rows = []
if autoren: fakten_rows.append(f'<tr><td><strong>Autor:innen</strong></td><td>{autoren}</td></tr>')
if illustratoren: fakten_rows.append(f'<tr><td><strong>Illustrator:innen</strong></td><td>{illustratoren}</td></tr>')
if verlag: fakten_rows.append(f'<tr><td><strong>Verlag</strong></td><td>{verlag}</td></tr>')
if personen: fakten_rows.append(f'<tr><td><strong>Personenzahl</strong></td><td>{personen}</td></tr>')
if spielzeit: fakten_rows.append(f'<tr><td><strong>Spielzeit</strong></td><td>{spielzeit}</td></tr>')
if jahr: fakten_rows.append(f'<tr><td><strong>Erscheinungsjahr</strong></td><td>{jahr}</td></tr>')
if preis: fakten_rows.append(f'<tr><td><strong>Preis</strong></td><td>{preis}</td></tr>')
if app: fakten_rows.append(f'<tr><td><strong>App</strong></td><td>{app}</td></tr>')
if alter: fakten_rows.append(f'<tr><td><strong>Alter</strong></td><td>{alter}</td></tr>')
# FAKTEN ZUM SPIEL — 3-Spalten-Grid (CSS: .bsn-fakten)
fakten_items = []
if autoren: fakten_items.append(('Autor:innen', autoren))
if illustratoren: fakten_items.append(('Illustrator:innen', illustratoren))
if verlag: fakten_items.append(('Verlag/Vertrieb', verlag))
if personen: fakten_items.append(('Personenzahl', personen))
if spielzeit: fakten_items.append(('Spielzeit', spielzeit))
if jahr: fakten_items.append(('Erscheinungsjahr', jahr))
if preis: fakten_items.append(('ungefährer Preis', preis))
if app: fakten_items.append(('App', app))
if alter: fakten_items.append(('empfohlenes Alter', alter))
fakten_html = ""
if fakten_rows:
fakten_html = '<table class="bsn-table"><tbody>' + "".join(fakten_rows) + '</tbody></table>'
if fakten_items:
items = "".join(f'<div class="bsn-fakten-item"><span class="bsn-fakten-val">{v}</span><span class="bsn-fakten-lbl">{k}</span></div>' for k, v in fakten_items)
fakten_html = f'<div class="bsn-fakten"><h3>FAKTEN ZUM SPIEL</h3><div class="bsn-fakten-grid">{items}</div></div>'
# Pro/Kontra
pro_html = ""
if pros:
pro_html = '<div><h3>👍 PRO</h3><ul>' + "".join(f"<li>{p}</li>" for p in pros) + '</ul></div>'
kontra_html = ""
if kontras:
kontra_html = '<div><h3>👎 KONTRA</h3><ul>' + "".join(f"<li>{k}</li>" for k in kontras) + '</ul></div>'
# Mechanismen
mech_html = ""
if mech:
mech_html = '<p><strong>Mechanismen:</strong> ' + ", ".join(mech) + '</p>'
# Bewertung
wertung_html = ""
# BEWERTUNGSKARTE — dunkelblauer Header + 3 Spalten + Footer (CSS: .bsn-rating-card)
mech_items = "".join(f'<span class="bsn-rc-mech">{m}</span>' for m in mech) if mech else ""
pro_items = "".join(f'<span class="bsn-rc-pro">{p}</span>' for p in pros) if pros else ""
kontra_items = "".join(f'<span class="bsn-rc-kontra">{k}</span>' for k in kontras) if kontras else ""
rating_html = ""
if wertung:
wertung_html = f'<div class="bsn-rating"><span class="bsn-rating-score">{wertung}</span><span class="bsn-rating-label">/ 100</span></div>'
rating_html = f"""<div class="bsn-rating-card">
<div class="bsn-rc-header"><span class="bsn-rc-title">{spielname}</span><span class="bsn-rc-meta">Komplexität: {komplex or ''}</span><span class="bsn-rc-meta">Sprachen: {sprache}</span></div>
<div class="bsn-rc-body"><div class="bsn-rc-col"><h4>MECHANISMEN</h4>{mech_items or '<span class="bsn-rc-empty">—</span>'}</div>
<div class="bsn-rc-col"><h4>PRO</h4>{pro_items or '<span class="bsn-rc-empty">—</span>'}</div>
<div class="bsn-rc-col"><h4>KONTRA</h4>{kontra_items or '<span class="bsn-rc-empty">—</span>'}</div></div>
<div class="bsn-rc-footer"><span class="bsn-rc-author">Bewertung von: {autor_name}</span><span class="bsn-rc-score">MEINE WERTUNG {wertung} / 100</span></div>
</div>"""
disc_html = ""
if disclosure_text:
disc_html = f'<p style="text-align:center;"><em>{disclosure_text}<br>Dies hat keinen Einfluss auf unsere Bewertung!</em></p>'
aff_html = ""
if fantasywelt_url:
aff_html += f'<p><a href="{fantasywelt_url}" target="_blank" rel="noopener"><img style="margin:10px auto;display:block;" src="images/banners/fantasywelt/banner_fantasywelt-jetzt-kaufen.jpg" alt="Bei Fantasywelt kaufen"></a></p>\n'
if so_url:
aff_html += f'<p><a href="{so_url}" target="_blank" rel="noopener"><img style="margin:10px auto;display:block;" src="images/banners/fantasywelt/SO_kaufen_button.jpg" alt="Bei Spiele-Offensive kaufen"></a></p>\n'
if amazon_url:
aff_html += f'<p><a href="{amazon_url}" target="_blank" rel="noopener"><img style="margin:10px auto;display:block;" src="images/banners/amazon/amazon-kaufen-button.jpg" alt="Bei Amazon kaufen"></a></p>\n'
if allgames4you_url:
aff_html += f'<p><a href="{allgames4you_url}" target="_blank" rel="noopener"><img style="margin:10px auto;display:block;" src="images/banners/allgames4you/allgames4you-kaufen-button.jpg" alt="Bei AllGames4You kaufen"></a></p>\n'
gal_path = f"01/{erster}/{ordner}"
tags_str = ", ".join(tags) if tags else f"{spielname}, Brettspiel, Review, Bewertung, {autor_name}"
title_full = f"{spielname} {zusatz}".strip()
# Artikeltext aus Word in Spielerklärung + Fazit splitten
# Artikeltext aus Word splitten
erklarung_html = ""
fazit_html = ""
if word_text:
# Suche "Fazit"-Überschrift als Trenner
import re as re2
split_marker = re2.search(r'(?i)^Fazit\s*$|^{2,}Fazit\s*$', word_text, re2.MULTILINE)
split_marker = re2.search(r'(?i)^Fazit\s*$', word_text, re2.MULTILINE)
if split_marker:
erkl = word_text[:split_marker.start()].strip()
faz = word_text[split_marker.end():].strip()
@@ -2194,7 +2172,6 @@ document.getElementById('publishBtn').addEventListener('click',function(){{submi
else:
erkl = word_text
faz = ""
# In HTML umwandeln falls Plaintext
if erkl and "<" not in erkl[:100]:
erkl = f"<p>{erkl.replace(chr(10)+chr(10), '</p><p>')}</p>"
if faz and "<" not in faz[:100]:
@@ -2202,30 +2179,37 @@ document.getElementById('publishBtn').addEventListener('click',function(){{submi
erklarung_html = erkl
fazit_html = faz
# Verlag/Autor Fallback
disc_html = ""
if disclosure_text:
disc_html = f'<p class="bsn-disclosure"><em>{disclosure_text}<br>Dies hat keinen Einfluss auf unsere Bewertung!</em></p>'
aff_html = ""
if fantasywelt_url:
aff_html += f'<p class="bsn-affiliate"><a href="{fantasywelt_url}" target="_blank" rel="noopener"><img src="images/banners/fantasywelt/banner_fantasywelt-jetzt-kaufen.jpg" alt="Bei Fantasywelt kaufen"></a></p>\n'
if so_url:
aff_html += f'<p class="bsn-affiliate"><a href="{so_url}" target="_blank" rel="noopener"><img src="images/banners/fantasywelt/SO_kaufen_button.jpg" alt="Bei Spiele-Offensive kaufen"></a></p>\n'
if amazon_url:
aff_html += f'<p class="bsn-affiliate"><a href="{amazon_url}" target="_blank" rel="noopener"><img src="images/banners/amazon/amazon-kaufen-button.jpg" alt="Bei Amazon kaufen"></a></p>\n'
if allgames4you_url:
aff_html += f'<p class="bsn-affiliate"><a href="{allgames4you_url}" target="_blank" rel="noopener"><img src="images/banners/allgames4you/allgames4you-kaufen-button.jpg" alt="Bei AllGames4You kaufen"></a></p>\n'
gal_path = f"01/{erster}/{ordner}"
tags_str = ", ".join(tags) if tags else f"{spielname}, Brettspiel, Review, Bewertung, {autor_name}"
title_full = f"{spielname} {zusatz}".strip()
display_autor = autoren or verlag or meta.get("verlag", "").strip() or "unbekannt"
body = f"""<p>{spielname}{komplex or 'Brettspiel'} von {display_autor}</p>
body = f"""<p class="bsn-dachzeile">{spielname}{komplex or 'Brettspiel'} von {display_autor}</p>
<hr id="system-readmore">
<p>&nbsp;</p>
<p><img style="margin:10px auto;display:block;" src="{base_img}/wertung/info.png" alt="Fakten zum Spiel"></p>
{fakten_html}
{disc_html}
{mech_html}
{erklarung_html}
<h2><img src="images/banners/redaktion/{autor_banner}" alt="Meine Meinung"></h2>
{fazit_html}
{pro_html}
{kontra_html}
{wertung_html}
<p>&nbsp;</p>
<p style="text-align:center;">{{{{module Discord-Hinweis Tests}}}}</p>
{rating_html}
<p>&nbsp;</p>
{aff_html}
<p>&nbsp;</p>
<h2>Bilder vom Spiel</h2>
<p>{{{{gallery}}}}{gal_path}{{{{/gallery}}}}</p>
<p>{{{{module Aktuelle Texte fur Content}}}}</p>"""
<p>{{gallery}}{gal_path}{{/gallery}}</p>"""
datei = datetime.now().strftime("%Y-%m-%d")
safe = spielname.lower().replace(" ", "-").replace(":", "").replace("/", "-")