Obsidian-Syntax `![[slug]]` (optional `![[slug|Anzeige]]`) als Seiten- Einbettung. Im Lese- und öffentlichen Modus wird der Inhalt der Zielseite inline gerendert; im Editier-Modus zeigt die NodeView eine Platzhalter- Karte (Titel + Öffnen-Link). Shared (Vorbild plugin_block): - Neuer Block-Atom-Node `transclusion` (targetSlug + optional displayText). - Markdown: Block-Regel für eine reine `![[…]]`-Zeile (vor `paragraph` registriert; mitten im Absatz greift sie bewusst nicht), Token→Node- Mapping, Serializer — Round-Trip stabil. - html.ts: Platzhalter `<div class="dt-transclusion" data-transclusion>`. - extractWikilinkSlugs erfasst jetzt auch Transklusionen → Einbettung zählt als Backlink/Graph-Kante. Backend (zentraler Render-Pfad): - PublicService expandiert Platzhalter zur gerenderten Body-HTML der Zielseite: SELBER Pond, read-permission-geprüft, Tiefe ≤2 + Zyklen- Guard (visited); Fehlend/unlesbar/zyklisch → neutraler Wikilink. Medien werden EINMAL über den ganzen Baum aufgelöst (kein Doppel-Processing). - Neuer authentifizierter Endpoint GET /read/:pondSlug/:pageSlug (nicht @Public) liefert dieselbe gerenderte HTML — für die NodeView im authentifizierten Lesemodus, auch bei nicht-öffentlichen Seiten. Web: - NodeView `transclusion.tsx`: Editier-Modus → Karte; Lesemodus → holt /read/:pond/:slug und rendert den (server-sanitisierten) Inhalt inline. - WikilinkAutocomplete unterstützt `![[` → fügt einen Transklusions-Block ein (statt Wikilink). - CSS für Karte (.dt-transclusion-card) und Embed (.dt-embed), i18n de+en. Tests: shared Round-Trip-Unit (5), public-DB-Test um Embed-Expansion (zyklus-sicher, Fehlend→Link) erweitert — grün. typecheck/lint/i18n grün. Visuelle Editor-Verifikation folgt auf dem Test-Stage. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0155v2aT8AG1kZDQEZiCLBWC
25 lines
884 B
TypeScript
25 lines
884 B
TypeScript
import { Node } from 'prosemirror-model';
|
|
|
|
/**
|
|
* The distinct target slugs of every `[[wikilink]]` and every `![[embed]]`
|
|
* (transclusion, issue #135) in a document (issue #47). Used server-side to
|
|
* maintain the `page_links` index on every content change, so backlinks and
|
|
* phantom (missing-target) links can be queried — an embed is semantically a
|
|
* reference, so it registers as a link too. Order of first appearance is
|
|
* preserved; duplicates are collapsed.
|
|
*/
|
|
export function extractWikilinkSlugs(doc: Node): string[] {
|
|
const slugs: string[] = [];
|
|
const seen = new Set<string>();
|
|
doc.descendants((node) => {
|
|
if (node.type.name === 'wikilink' || node.type.name === 'transclusion') {
|
|
const slug = node.attrs.targetSlug as string;
|
|
if (slug && !seen.has(slug)) {
|
|
seen.add(slug);
|
|
slugs.push(slug);
|
|
}
|
|
}
|
|
});
|
|
return slugs;
|
|
}
|