Files
dogfather-universe/creator.html
T
DogFatherGitandClaude Opus 5 1afb38258c Anfuehrungszeichen: drei Loecher in meiner eigenen Wache
Die zweite Sitzung hat in den Praesentationen des Vaults 83 Stellen
gefunden — und damit auf Loecher in MEINER Wache gezeigt. Ich habe
sie nachgemessen, alle drei waren echt.

LOCH 1 — SIE SAH NUR `server/workspace-*.js`

Also ausgerechnet nicht `workspace.js`, die groesste Datei des
Hauses. Der weitere Filter fand dort sofort drei Stellen:

    workspace.js:3404  Kanal „Chat-Moderation"     (Protokoll)
    workspace.js:3422  „${titel}" -> ${haus}       (Protokoll)
    workspace.js:3304  „${… || "ohne Titel"}"      (siehe Loch 3)

Das ist heute der DRITTE Fall von „die Wache kennt nur die halbe
Menge" — nach pruef-struktur (sah nur die Pruefdateien, nicht die
Anwendung) und pruef-fingermass (sah keine variable Breite).

LOCH 2 — IHR AUSDRUCK GILT JE ZEILE

Ein `„`, das erst in der naechsten Zeile mit einem geraden `"`
schliesst, fiel durch. Gemessen: drei echte Faelle, zwei davon
sichtbarer Seitentext.

    workspace/leistung.html       „nicht / zugeordnet"
    workspace/leistung.html       „Backstage-Tabelle / einfuegen"
    workspace/assets/js/ampel.js  „noch ' + 'verbessern"

Beim letzten laeuft das Zitat ueber eine Zeichenketten-Verkettung.

Neue Regel ohne Fehlalarme: erst alle RICHTIG geschlossenen Paare
entfernen (auch mehrzeilig), dann die einzeilig falschen (die meldet
die alte Regel). Was danach noch ein `„` hat und binnen drei Zeilen
ein gerades `"`, ist ein Fund. Ausgenommen bleibt das Zeichen ALS
WERT — in `content: "„";` und in den Sprachtabellen ist das `„` der
Inhalt und das `"` die Begrenzung.

LOCH 3 — EINE AUSNAHME, DIE EINEN FUND VERSCHLUCKT HAT

Gefunden durch die ZAHL, nicht durch den Blick: Der weitere Filter
liess die Ausnahmen von 12 auf 13 steigen. Die dreizehnte war

    `… „${zeile[titelSpalte] || "ohne Titel"}"`

Der Ausdruck blieb am `"` von `"ohne Titel"` haengen; als Inhalt kam
`${zeile[titelSpalte] || ` heraus, das endet auf ein Leerzeichen,
und damit galt „der Satz geht in der naechsten Zeile weiter". Das
echte Schlusszeichen stand hinter dem `}` und war gerade.

Dass die Ausnahmen gezaehlt UND genannt werden, hat ihn gefunden.
Genau dafuer steht die Zeile dort.

Behoben an der Wurzel: Anfuehrungszeichen innerhalb einer Einsetzung
`${…}` werden vorher durch X ersetzt, bei gleicher Laenge und
gleichen Zeilenumbruechen. Das nimmt einer ganzen Sorte
Fehlklassifizierung die Grundlage — die Ausnahmen fielen danach von
13 auf 11.

UND EIN VIERTES, BEIM MESSEN AUFGEFALLEN

`„Van-Van”` in assets/js/data-modis.js schliesst mit U+201D, dem
ENGLISCHEN Zeichen. Zweimal, beide Male in einer DEUTSCHEN Zeile
(`de:` und `"de-CH":`) — nicht einmal eine Uebersetzung, in der es
richtig waere. Eigene Regel dafuer, die keine Ausnahme braucht: Wer
mit `„` oeffnet, schliesst deutsch; in fremdsprachigen Zeilen steht
gar kein `„` am Anfang.

DIE AUSNAHMEZAHL IST JETZT STRENG. Sie stand auf „hoechstens 12" —
damit waere der Anstieg auf 13 nicht aufgefallen. Jetzt genau 11,
wie bei den Grundlinien in pruef-fingermass.

GEPRUEFT: pruef-struktur 68 -> 75 Pruefungen, 0 Fehler. Dazu
leistung-optik 59/0, ampel 47/0, treff 85/0, modi-verborgen 87/0 —
die Seiten, deren Text ich angefasst habe. Steuerzeichen: 830
Dateien, keines. Beide Stempel gesetzt.

Sechs echte Stellen berichtigt, vier neue Gegenproben.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-10-01 19:28:38 +02:00

158 lines
7.6 KiB
HTML

<!DOCTYPE html>
<html lang="de" data-theme="spicymedia">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Creator im Team — DOGFATHER UNIVERSE</title>
<meta name="description" content="Content Creator, die Teil von DogFather / Spicy Media sind." />
<link rel="icon" type="image/png" href="/assets/img/app-symbole/universe-32.png?v=202610011927" />
<link rel="apple-touch-icon" href="/assets/img/app-symbole/universe-180.png?v=202610011927" />
<link rel="manifest" href="/manifest.json" />
<meta name="theme-color" content="#065f76" />
<meta property="og:type" content="website" />
<meta property="og:site_name" content="DOGFATHER UNIVERSE" />
<meta property="og:title" content="Creator im Team — DOGFATHER UNIVERSE" />
<meta property="og:description" content="Content Creator, die Teil von DogFather / Spicy Media sind." />
<meta property="og:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
<meta property="og:url" content="https://dogfather-universe.com/creator.html" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Creator im Team — DOGFATHER UNIVERSE" />
<meta name="twitter:description" content="Content Creator, die Teil von DogFather / Spicy Media sind." />
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
<link rel="stylesheet" href="assets/css/main.css?v=202610011927" />
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=202610011927" />
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=202610011927" />
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=202610011927" />
</head>
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-creator.jpg?v=202610011927');--page-bg-mobile:url('/assets/img/bg-creator-mobile.jpg?v=202610011927');">
<div id="site-header"></div>
<main>
<section class="hero page-bg">
<div class="hero-banner"><img src="/assets/img/bg-creator.jpg?v=202610011927" alt="" loading="eager" /></div>
<div class="container">
<span class="eyebrow" data-i18n="crt_eyebrow">Manager DogFather — Team</span>
<h1 data-i18n="crt_h1" data-site-text-key="seitentitel_creator">Creator im Team</h1>
<p class="lead worlds" data-i18n="crt_lead">Content Creator, die bei DogFather / Spicy Media mitmachen.</p>
</div>
</section>
<section class="section-tight">
<div class="container">
<div class="filter-bar" id="creator-filters"></div>
<div id="creator-grid" class="grid grid-4"></div>
<!-- Versteckte Textquelle für die JS-generierten Grid-/Filter-Texte:
main.js übersetzt data-i18n-Elemente automatisch (auch bei
Sprachwechsel), das Inline-Skript unten liest die fertigen Texte
von hier aus, statt sie selbst per JS zu übersetzen. -->
<div id="creator-i18n-strings" style="display:none;" aria-hidden="true">
<span data-i18n="crt_empty">Noch keine Creator-Profile veröffentlicht — bald verfügbar. 🩵</span>
<span data-i18n="crt_filter_alle">alle</span>
<span data-i18n="crt_profil_btn">Profil ansehen</span>
<span data-i18n="crt_kategorie_sonstige">Sonstige</span>
</div>
<!-- TODO: Noch keine Creator-Profile final geklärt. Sobald Namen/Infos feststehen, in assets/js/data-creator.js ergänzen — diese Seite rendert automatisch. -->
<div class="btn-row" style="justify-content:center;">
<a class="btn btn-primary" href="bewerben-creator.html" data-i18n="crt_bewerben_btn">Als Creator bewerben</a>
</div>
</div>
</section>
</main>
<div id="site-footer"></div>
<script src="assets/js/data-creator.js?v=202610011927"></script>
<script src="assets/js/i18n-creator.js?v=202610011927"></script>
<script src="assets/js/main.js?v=202610011927"></script>
<script>
document.addEventListener("DOMContentLoaded", async () => {
const grid = document.getElementById("creator-grid");
const filterBar = document.getElementById("creator-filters");
let list = window.CREATORS || [];
// 21.08.2026: über die Verwaltung angelegte Creator ergänzen, BEVOR
// entschieden wird, ob die Seite "leer" ist (Nutzer-Wunsch "überall wo
// ... Creator ... sind, will ich dass ich die easy über meine
// Verwaltungsseite hinzufüge"). Vorher gab es direkt darunter ein
// "return", sobald window.CREATORS leer war (bisher der Normalfall, da
// noch keine echten Creator-Profile feststehen) -- dadurch wären
// admin-gepflegte Creator NIE geladen worden.
if (window.dogiTeamLaden) {
const neue = await window.dogiTeamLaden("creator");
// Runde 2 (21.08.2026, "wenn ich eine änderung mache ist es auch für
// jeden"): überschreibt bereits importierte Creator (gleicher slug)
// statt sie zu duplizieren.
list = window.dogiTeamZusammenfuehren(list, neue);
}
// Texte fürs JS-generierte Grid/Filter kommen aus den versteckten
// data-i18n-Elementen oben — main.js übersetzt sie ganz normal (auch bei
// Sprachwechsel per "dogi-sprache-geaendert"), wir lesen hier nur den
// fertig übersetzten Text aus.
const uebersetzen = (schluessel) => {
const quelle = [...document.querySelectorAll("#creator-i18n-strings [data-i18n]")]
.find((el) => el.getAttribute("data-i18n") === schluessel);
return quelle ? quelle.textContent : schluessel;
};
if (!list.length) {
const texteNeuSetzen = () => {
grid.innerHTML = `<p class="muted text-center" style="grid-column:1/-1;">${uebersetzen("crt_empty")}</p>`;
};
texteNeuSetzen();
document.addEventListener("dogi-sprache-geaendert", texteNeuSetzen);
filterBar.style.display = "none";
return;
}
// 21.08.2026: über die Verwaltung angelegte Creator haben (noch) kein
// eigenes Genre-Feld (category) -- ohne diesen Fallback würde die
// Filterleiste einen kaputten "undefined"-Knopf zeigen.
list = list.map((c) => (c.category ? c : { ...c, category: uebersetzen("crt_kategorie_sonstige") }));
const categories = ["alle", ...new Set(list.map((c) => c.category))];
let aktiverFilter = "alle";
function zeichneFilterbar() {
filterBar.innerHTML = categories.map((c) =>
`<button class="filter-btn${c === aktiverFilter ? " active" : ""}" data-filter="${c}">${c === "alle" ? uebersetzen("crt_filter_alle") : c}</button>`).join("");
}
const feld = (x) => (window.dogiFeld ? window.dogiFeld(x) : x || "");
function draw(filter) {
const items = filter === "alle" ? list : list.filter((c) => c.category === filter);
grid.innerHTML = items.map((c) => {
const quoteText = feld(c.quote);
return `
<a class="profile-card" href="profil.html?p=${c.slug}">
<div class="avatar">${(c.avatar || c.photo) ? `<img src="${c.avatar || c.photo}" alt="${c.name}" loading="lazy">` : `<span class="avatar-initial">${c.name.charAt(0).toUpperCase()}</span>`}</div>
<h3>${c.name}</h3>
<div class="role">${feld(c.role)}</div>
${quoteText ? `<p class="quote">„${quoteText}“</p>` : ""}
<span class="btn btn-outline" style="margin-top:.7rem;pointer-events:none;">${uebersetzen("crt_profil_btn")}</span>
</a>`;
}).join("");
}
filterBar.addEventListener("click", (e) => {
const btn = e.target.closest(".filter-btn");
if (!btn) return;
aktiverFilter = btn.dataset.filter;
filterBar.querySelectorAll(".filter-btn").forEach((b) => b.classList.remove("active"));
btn.classList.add("active");
draw(aktiverFilter);
});
document.addEventListener("dogi-sprache-geaendert", () => {
zeichneFilterbar();
draw(aktiverFilter);
});
zeichneFilterbar();
draw("alle");
});
</script>
</body>
</html>