Files
Skrift-Auto-Article/build/elementor_bauen.py

92 lines
3.0 KiB
Python

# -*- coding: utf-8 -*-
"""Baut aus content_html und faq eine Elementor-Struktur (_elementor_data).
Der Artikel wird an den H2-Grenzen in einzelne Text-Editor-Widgets zerlegt,
damit er im Builder abschnittsweise bearbeitbar bleibt. Das FAQ wird zu einem
nested-accordion mit aktiviertem faq_schema, also demselben Widget, das die
Leistungsseiten von skrift.de bereits verwenden.
"""
import json, re, secrets
def eid():
return secrets.token_hex(4)[:7]
def text_widget(html):
return {"id": eid(), "elType": "widget", "settings": {"editor": html},
"elements": [], "widgetType": "text-editor"}
def container(kinder, innen=False):
s = {"content_width": "full"}
if innen:
s.update({"_title": "Element", "padding": {"unit": "px", "top": "8", "right": "8",
"bottom": "8", "left": "8", "isLinked": True},
"flex_gap": {"column": "20", "row": "20", "isLinked": True,
"unit": "px", "size": 20}})
c = {"id": eid(), "elType": "container", "settings": s, "elements": kinder}
if innen:
c["isInner"] = True
c["isLocked"] = True
return c
def accordion(faq, titel="Häufige Fragen"):
"""nested-accordion: settings.items und elements laufen parallel."""
items, kinder = [], []
for f in faq:
if not f.get("frage"):
continue
items.append({"item_title": f["frage"], "_id": eid()})
kinder.append(container([text_widget(f"<p>{f.get('antwort', '')}</p>")], innen=True))
return {
"id": eid(), "elType": "widget", "widgetType": "nested-accordion",
"settings": {"items": items, "faq_schema": "yes", "default_state": "all_collapsed"},
"elements": kinder,
}
def teile_an_h2(html):
"""Zerlegt den Artikel an <h2>, behält alles davor als Einleitung."""
stellen = [m.start() for m in re.finditer(r'<h2[ >]', html)]
if not stellen:
return [html]
bloecke = []
if stellen[0] > 0:
kopf = html[:stellen[0]].strip()
if kopf:
bloecke.append(kopf)
for i, s in enumerate(stellen):
ende = stellen[i + 1] if i + 1 < len(stellen) else len(html)
bloecke.append(html[s:ende].strip())
return [b for b in bloecke if b]
def baue(artikel, faq_ueberschrift="Häufige Fragen"):
wurzel = []
# Kurzantwort als eigener, hervorgehobener Block
if artikel.get("kurzantwort"):
wurzel.append(container([text_widget(
f'<div class="skrift-kurzantwort"><p>{artikel["kurzantwort"]}</p></div>')]))
for block in teile_an_h2(artikel.get("content_html", "")):
wurzel.append(container([text_widget(block)]))
faq = artikel.get("faq") or []
if faq:
wurzel.append(container([
text_widget(f"<h2>{faq_ueberschrift}</h2>"),
accordion(faq),
]))
return wurzel
if __name__ == "__main__":
import sys
a = json.load(open(sys.argv[1], encoding="utf-8"))
baum = baue(a)
print(json.dumps(baum, ensure_ascii=False))