diff --git a/README.md b/README.md index 3906dea..be24f6c 100644 --- a/README.md +++ b/README.md @@ -181,6 +181,24 @@ der Workflow fuer diesen Artikel ab. Fehlt `stand_datum`, setzt der Workflow das heutige Datum. Fehlt `seo_titel`, wird `titel` verwendet. +### Ausgabeform in WordPress + +Der Node **Konfiguration** hat den Schalter `elementor_ausgabe`. + +Steht er auf `true` (Standard), baut der Workflow aus dem Artikel eine +Elementor-Struktur: Der Text wird an den H2-Grenzen in einzelne +Text-Editor-Widgets zerlegt, die Kurzantwort bekommt einen eigenen Block, und +das FAQ wird zu einem **nested-accordion** mit aktiviertem `faq_schema`. +Das ist dasselbe Widget, das die Leistungsseiten von skrift.de verwenden, der +Beitrag laesst sich also im Builder wie jede andere Seite bearbeiten und +WordPress gibt automatisch FAQPage-Schema aus. + +Steht er auf `false`, landet der Artikel als klassischer Beitragsinhalt. Das FAQ +gibt dann der Shortcode `[skrift_faq]` aus, den das Mu-Plugin mitbringt. + +Die Meta-Felder `kurzantwort`, `faq`, `cta_ziel` und `stand_datum` werden in +beiden Faellen geschrieben, unabhaengig von der Darstellung. + ### Schreibregeln fuer content_html **Preise niemals ausschreiben.** Sie werden zentral gepflegt und per Shortcode @@ -192,10 +210,21 @@ eingesetzt: | Parameter | Bedeutung | |---|---| -| `key` | Produkt- oder Positionsschluessel, z. B. `briefe`, `postkarten`, `porto_inland` | +| `key` | Produktschluessel, siehe Liste unten | | `ab=1` | guenstigster Staffelpreis; `ab=0` der Standardpreis | | `brutto=1` | inkl. MwSt.; `brutto=0` netto | +Gueltige Schluessel, am 20.09.2026 gegen das Plugin geprueft: +`briefe`, `postkarten`, `muster`, `unterschriftenservice`, `follow_ups`. +Fuer die letzten drei liefert das Plugin 0,00 Euro, dort gehoert kein Preis in +den Text. + +**Nicht verwechseln:** `[skrift_preis_exkl produkt="..."]` und +`[skrift_preis_inkl produkt="..."]` rendern den kompletten interaktiven +Preisrechner mit Mengenfeld. Die gehoeren auf Leistungsseiten, nicht in den +Fliesstext eines Ratgebers. Nur `[skrift_preis key="..."]` liefert eine +reine Zahl. + Das Wort "ab" gehoert in den Fliesstext, der Shortcode liefert nur die Zahl: ``` diff --git a/build/elementor_bauen.py b/build/elementor_bauen.py new file mode 100644 index 0000000..8817982 --- /dev/null +++ b/build/elementor_bauen.py @@ -0,0 +1,91 @@ +# -*- 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"
{f.get('antwort', '')}
")], 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{artikel["kurzantwort"]}
${f.antwort || ''}
`).join('\n'); +const bewertungs_html = [ + artikel.kurzantwort ? `${artikel.kurzantwort}
` : '', + artikel.content_html || '', + faqText ? `