- Startseite
- Docs-Builder
- Platzhalter-System
Platzhalter-System
Das Platzhalter-System ermöglicht es Lesern, IP-Adressen, ASNs und andere bereitstellungsspezifische Werte in der gesamten Dokumentation anzupassen. Autoren schreiben Tokens in ihrem Markdown; der Browser ersetzt diese zur Laufzeit durch benutzerdefinierte Werte.
Token-Format
Abschnitt betitelt „Token-Format“Tokens folgen dem Regex-Muster:
x([A-Z][A-Z0-9_]+)xEin Token beginnt und endet mit einem kleingeschriebenen x und enthält einen Bezeichner in Großbuchstaben. Zum Beispiel referenziert xCUSTOMER_ASNx den Platzhalter CUSTOMER_ASN.
Der reguläre Ausdruck ist in src/scripts/placeholder-dom.ts definiert:
const PH_REGEX = /x([A-Z][A-Z0-9_]+)x/g;Platzhalter-Definitionen
Abschnitt betitelt „Platzhalter-Definitionen“Alle Platzhalter werden in src/data/placeholders.json deklariert. Jeder Eintrag hat folgende Struktur:
{ "CUSTOMER_ASN": { "type": "text", "default": "64496", "description": "Your public ASN (registered with ARIN/RIR)" }}| Feld | Erforderlich | Beschreibung |
|---|---|---|
type | ja | "text" für Freitext-Eingabe, "dropdown" für Auswahlmenüs |
default | ja | Anfangswert, der angezeigt wird, bevor der Leser etwas ändert |
description | ja | Beschriftung, die im Formular angezeigt wird |
options | nur für Dropdown | Array der zulässigen Werte |
Zustandsverwaltung
Abschnitt betitelt „Zustandsverwaltung“src/lib/placeholder-store.ts verwaltet den gesamten Platzhalter-Zustand.
Speicherung
Abschnitt betitelt „Speicherung“Werte werden im localStorage unter dem Schlüssel f5xc-placeholders persistiert. Der Store stellt vier Funktionen bereit:
| Funktion | Zweck |
|---|---|
getDefaults() | Gibt eine Map aller Platzhalter-Schlüssel mit ihren default-Werten aus der JSON-Datei zurück |
loadValues() | Liest aus dem localStorage, fällt auf getDefaults() zurück |
saveValues(values) | Schreibt die aktuelle Map in den localStorage |
clearValues() | Entfernt den localStorage-Eintrag |
Feldgruppen
Abschnitt betitelt „Feldgruppen“FIELD_GROUPS organisiert Platzhalter-Schlüssel in beschriftete Abschnitte für die Formular-Oberfläche:
export const FIELD_GROUPS: FieldGroup[] = [ { label: 'Data Center & Scrubbing Centers', keys: ['DC_NAME', 'CENTER_1', 'CENTER_2'] }, { label: 'Protected Prefixes', keys: ['PROTECTED_CIDR_V4', 'PROTECTED_NET_V4', ...] }, { label: 'BGP', keys: ['CUSTOMER_ASN', 'F5_XC_ASN', 'BGP_PASSWORD'] }, // ... weitere Gruppen];Berechnete Werte
Abschnitt betitelt „Berechnete Werte“Einige Werte werden aus Benutzereingaben abgeleitet, anstatt direkt eingegeben zu werden. getComputedValues() berechnet diese aus Nachschlagetabellen:
const cidrToMask: Record<string, string> = { '/24 (256 IPs)': '255.255.255.0', '/23 (512 IPs)': '255.255.254.0', // ...};Zwei berechnete Platzhalter werden erzeugt:
| Berechneter Schlüssel | Abgeleitet von | Beispiel |
|---|---|---|
PROTECTED_MASK_V4 | PROTECTED_CIDR_V4 über cidrToMask-Nachschlagetabelle | 255.255.255.0 |
PROTECTED_PREFIX_V4 | PROTECTED_NET_V4 + PROTECTED_CIDR_V4 über cidrToShort | 192.0.2.0/24 |
getAllValues() führt benutzerdefinierte Werte mit berechneten Werten zusammen und liefert eine vollständige Map für die Ersetzung.
Ereignis-Auslösung
Abschnitt betitelt „Ereignis-Auslösung“emitChange() sendet ein placeholder-change CustomEvent auf document mit der vollständigen Werte-Map als detail:
export function emitChange(values: Record<string, string>) { document.dispatchEvent( new CustomEvent('placeholder-change', { detail: getAllValues(values) }), );}Dieses Ereignis steuert sowohl die DOM-Span-Aktualisierungen als auch das Mermaid-Neurendering.
React-Formularkomponente
Abschnitt betitelt „React-Formularkomponente“src/components/PlaceholderForm.tsx stellt die Bearbeitungsoberfläche bereit.
- Zustand:
useStateinitialisiert mitloadValues() - Beim Einbinden:
useEffectruftemitChange()auf, um die initiale DOM-Ersetzung auszulösen - handleChange: Aktualisiert den React-Zustand, ruft
saveValues()undemitChange()auf - handleReset: Ruft
clearValues()auf, setzt den Zustand aufgetDefaults()zurück, löst ein Change-Ereignis aus - Rendering: Iteriert über
FIELD_GROUPSund rendert ein<fieldset>pro Gruppe. Jeder Schlüssel erhält entweder ein<input>(Typ Text) oder ein<select>(Typ Dropdown) - Layout: Das Formular ist in ein
<details>-Element eingebettet, standardmäßig eingeklappt
Astro-Wrapper
Abschnitt betitelt „Astro-Wrapper“src/components/PlaceholderFormWrapper.astro verbindet die React-Komponente mit der Astro-Seite:
<PlaceholderForm client:only="react" />
<script> import '../scripts/placeholder-dom.ts';</script>client:only="react" weist Astro an, die Komponente ausschließlich auf dem Client zu hydrieren (kein SSR). Das <script>-Tag importiert den DOM-Walker, damit dieser auf jeder Seite ausgeführt wird, die diesen Wrapper einbindet.
Der Wrapper injiziert außerdem globales CSS für das Formular-Styling (.ph-form-wrapper, .ph-grid, .ph-value usw.).
DOM-Walker
Abschnitt betitelt „DOM-Walker“src/scripts/placeholder-dom.ts übernimmt die clientseitige Token-Ersetzung.
Initialer Durchlauf
Abschnitt betitelt „Initialer Durchlauf“Beim Laden der Seite wird init() ausgeführt:
- Wählt
.sl-markdown-contentals Wurzelelement (fällt aufdocument.bodyzurück) - Ruft
walkTextNodes(root, values)auf, dasdocument.createTreeWalkermitNodeFilter.SHOW_TEXTverwendet - Für jeden Textknoten, der dem Token-Regex entspricht, wird dieser in ein Dokumentfragment aus einfachen Textknoten und
<span data-ph="KEY" class="ph-value">-Elementen aufgeteilt - Ersetzt den ursprünglichen Textknoten durch das Fragment
Nach dem Durchlauf enthält das DOM Spans mit data-ph-Attributen anstelle der rohen Tokens.
Nachfolgende Aktualisierungen
Abschnitt betitelt „Nachfolgende Aktualisierungen“Wenn das Formular ein placeholder-change-Ereignis auslöst, wird updateSpans() ausgeführt:
document.querySelectorAll<HTMLSpanElement>('span[data-ph]').forEach((span) => { const name = span.getAttribute('data-ph')!; if (values[name] !== undefined) { span.textContent = values[name]; }});Dies vermeidet ein erneutes Durchlaufen des Baums — es aktualisiert direkt den Textinhalt der Spans.
Ereignis-Listener
Abschnitt betitelt „Ereignis-Listener“Das Skript registriert zwei Listener:
| Ereignis | Handler | Zweck |
|---|---|---|
placeholder-change | handleChange | Aktualisiert Spans und rendert Mermaid-Diagramme neu |
astro:page-load | init | Durchläuft das DOM erneut nach clientseitiger Astro-Navigation |
Anleitung: Einen neuen Platzhalter hinzufügen
Abschnitt betitelt „Anleitung: Einen neuen Platzhalter hinzufügen“-
JSON-Eintrag hinzufügen in
src/data/placeholders.json:"MY_NEW_VALUE": {"type": "text","default": "example","description": "Description shown in the form"} -
Den Schlüssel einer Feldgruppe zuordnen in
src/lib/placeholder-store.ts. Fügen Sie ihn entweder demkeys-Array einer bestehenden Gruppe hinzu oder erstellen Sie eine neue Gruppe inFIELD_GROUPS. -
Das Token im Inhalt verwenden: Schreiben Sie
xMY_NEW_VALUExin einer beliebigen.mdx-Datei. Der DOM-Walker ersetzt es zur Laufzeit.
Anleitung: Einen berechneten Wert hinzufügen
Abschnitt betitelt „Anleitung: Einen berechneten Wert hinzufügen“Berechnete Werte werden aus anderen Platzhaltern abgeleitet. Um einen hinzuzufügen:
-
Fügen Sie eine Nachschlagetabelle (falls erforderlich) in
src/lib/placeholder-store.tshinzu, nach dem Muster voncidrToMask. -
Erweitern Sie
getComputedValues()um den neuen abgeleiteten Schlüssel:export function getComputedValues(values: Record<string, string>): Record<string, string> {// ... bestehende Logikreturn {PROTECTED_MASK_V4: mask,PROTECTED_PREFIX_V4: `${net}${short}`,MY_COMPUTED: derivedValue, // hier hinzufügen};} -
Verwenden Sie
xMY_COMPUTEDxim Inhalt wie jedes andere Token. Berechnete Werte benötigen keinenplaceholders.json-Eintrag und keine Feldgruppe — sie sind für das Formular unsichtbar.