Živý náhled v adminu
Aby admin uměl živý náhled (změny z editoru hned v iframu, bez rebuildu), web musí mít PreviewBridge skript + markery na editovatelných prvcích. Funguje i cross-origin (admin contenta.cz načte tvou doménu).
Markery
Sekce “Markery”| Marker | Použití |
|---|---|
data-cn="hero.title" | textContent z cesty v site-config (homepage/hlavička/patička) |
data-cn-html="…" | innerHTML (rich-text v landingu) |
data-cn-field="title" | textContent pole na detailu (článek/pojem) — title, perex |
data-cn-html="body" | innerHTML těla na detailu |
data-cn-src="cover" | atribut src obrázku na detailu |
URL flagy: homepage ?preview=1&cnpreview=1, detaily ?cnpreview=1. Pole u detailu posílá admin jako
{ title, perex, body, cover }.
Skript
Sekce “Skript”Vlož jako <script is:inline> do layoutu. Aktivní jen v iframu adminu s ?cnpreview=1:
(function () { if (window === window.parent) return; // jen v iframu if (new URLSearchParams(location.search).get("cnpreview") !== "1") return; function allowed(o) { return /^https?:\/\/localhost(:\d+)?$/.test(o) || /^https?:\/\/([a-z0-9-]+\.)*contenta\.cz$/.test(o); } function get(o, p) { return p.split(".").reduce((a, k) => (a == null ? undefined : a[k]), o); } function patchText(L) { document.querySelectorAll("[data-cn]").forEach((el) => { const v = get(L, el.getAttribute("data-cn")); if (typeof v === "string" || typeof v === "number") el.textContent = String(v); }); } function patchFields(f) { document.querySelectorAll("[data-cn-field]").forEach((el) => { const v = f[el.getAttribute("data-cn-field")]; if (typeof v === "string" || typeof v === "number") el.textContent = String(v); }); document.querySelectorAll("[data-cn-html]").forEach((el) => { const v = f[el.getAttribute("data-cn-html")]; if (typeof v === "string") el.innerHTML = v; }); document.querySelectorAll("[data-cn-src]").forEach((el) => { const v = f[el.getAttribute("data-cn-src")]; if (typeof v === "string" && v) el.setAttribute("src", v); }); } window.addEventListener("message", (e) => { if (!allowed(e.origin)) return; const d = e.data; if (!d || d.source !== "contenta-admin") return; if (d.type === "preview") patchText(d.landing || {}); else if (d.type === "preview-fields") patchFields(d.fields || {}); }); try { window.parent.postMessage({ source: "contenta-preview", type: "ready" }, "*"); } catch (e) {}})();