;; Phase 4 — external CMS sync via injected adapter. Import/export round-trip. (st-bootstrap-classes!) (content-bootstrap-blocks!) (content-bootstrap-doc!) (content-bootstrap-render!) ;; ── a Ghost post (external shape) ── (define post {:sections (list {:id "h" :text "Hello" :kind "heading" :level 1} {:id "p" :text "World" :kind "paragraph"} {:id "i" :src "/c.png" :alt "cat" :kind "image"} {:id "d" :kind "hr"} {:items (list "a" "b") :id "l" :kind "list" :ordered true}) :title "Hello"}) ;; ── import (delegates to adapter) ── (define doc (content/import ghost-adapter post "post")) (content-test "import doc-id" (doc-id doc) "post") (content-test "import ids" (doc-ids doc) (list "h" "p" "i" "d" "l")) (content-test "import types" (doc-types doc) (list "heading" "text" "image" "divider" "list")) (content-test "import renders" (content/render doc "html") "

Hello

World

\"cat\"
  1. a
  2. b
") (content-test "import preserves heading level" (blk-send (doc-find doc "h") "level") 1) (content-test "import preserves list items" (blk-send (doc-find doc "l") "items") (list "a" "b")) ;; ── export (delegates to adapter) ── (define out (content/export ghost-adapter doc)) (content-test "export sections round-trip" (get out :sections) (get post :sections)) ;; ── round-trip: export then import yields the same document ── (define doc2 (content/round-trip ghost-adapter doc)) (content-test "round-trip ids" (doc-ids doc2) (doc-ids doc)) (content-test "round-trip render" (content/render doc2 "html") (content/render doc "html")) ;; ── round-trip the external form: import . export . import == import ── (content-test "external round-trip sections" (get (content/export ghost-adapter (content/import ghost-adapter post "post")) :sections) (get post :sections)) ;; ── core knows nothing about Ghost: a different (stub) adapter works the same ── (define raw-adapter {:export (fn (d) (str (blk-send (doc-find d "only") "text"))) :import (fn (ext doc-id) (doc-new doc-id (list (mk-text "only" ext))))}) (define rdoc (content/import raw-adapter "just text" "r")) (content-test "alt adapter import" (doc-ids rdoc) (list "only")) (content-test "alt adapter export" (content/export raw-adapter rdoc) "just text") ;; ── code / quote / embed kinds round-trip ── (define post2 {:sections (list {:id "c" :text "(+ 1 2)" :kind "code" :language "sx"} {:cite "Ada" :id "q" :text "to err" :kind "quote"} {:id "e" :provider "vimeo" :kind "embed" :url "https://v/1"})}) (define d3 (content/import ghost-adapter post2 "p2")) (content-test "code/quote/embed types" (doc-types d3) (list "code" "quote" "embed")) (content-test "code/quote/embed round-trip" (get (content/export ghost-adapter d3) :sections) (get post2 :sections))