From 4baf2b8e7693f12a023d4d8c2e443550885becdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Fri, 21 Feb 2025 16:22:01 +0100 Subject: [PATCH] Add transform.PortableText Using this in a content adapter could look like this: ```handlebars {{ $projectID := "" }} {{ $useCached := true }} {{ $api := "api" }} {{ if $useCached }} {{/* See https://www.sanity.io/docs/api-cdn */}} {{ $api = "apicdn" }} {{ end }} {{ $url := printf "https://%s.%s.sanity.io/v2021-06-07/data/query/production" $projectID $api }} {{/* prettier-ignore-start */ -}} {{ $q := `*[_type == 'post']{ title, publishedAt, summary, slug, body[]{ ..., _type == "image" => { ..., asset->{ _id, path, url, altText, title, description, metadata { dimensions { aspectRatio, width, height } } } } }, }` }} {{/* prettier-ignore-end */ -}} {{ $body := dict "query" $q | jsonify }} {{ $opts := dict "method" "post" "body" $body }} {{ $t := debug.Timer "sanity.get" }} {{ $r := resources.GetRemote $url $opts }} {{ $t.Stop }} {{ $m := $r | transform.Unmarshal }} {{ $result := $m.result }} {{ $t := debug.Timer "sanity.parse" }} {{ range $result }} {{ if not .slug }} {{ continue }} {{ end }} {{ $markdown := transform.PortableText .body }} {{ $t.Stop }} {{ $content := dict "mediaType" "text/markdown" "value" $markdown }} {{ $params := dict "portabletext" (.body | jsonify (dict "indent" " ")) }} {{ $page := dict "content" $content "kind" "page" "path" .slug.current "title" .title "date" (.publishedAt | time ) "summary" .summary "params" $params }} {{ $.AddPage $page }} {{ end }} ``` --- go.mod | 1 + go.sum | 4 +++ tpl/transform/transform.go | 19 +++++++++++++ tpl/transform/transform_integration_test.go | 30 +++++++++++++++++++++ 4 files changed, 54 insertions(+) diff --git a/go.mod b/go.mod index 76e83d05bac..5f29e5cff81 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/bep/goat v0.5.0 github.com/bep/godartsass/v2 v2.3.2 github.com/bep/golibsass v1.2.0 + github.com/bep/goportabletext v0.1.0 github.com/bep/gowebp v0.3.0 github.com/bep/helpers v0.5.0 github.com/bep/imagemeta v0.8.4 diff --git a/go.sum b/go.sum index fa9ff4083c9..f9a3b1541fc 100644 --- a/go.sum +++ b/go.sum @@ -133,6 +133,8 @@ github.com/bep/godartsass/v2 v2.3.2 h1:meuc76J1C1soSCAnlnJRdGqJ5S4m6/GW+8hmOe9tO github.com/bep/godartsass/v2 v2.3.2/go.mod h1:Qe5WOS9nVJy7G0jHssXPd3c+Pqk/f7+Tm6k/vahbVgs= github.com/bep/golibsass v1.2.0 h1:nyZUkKP/0psr8nT6GR2cnmt99xS93Ji82ZD9AgOK6VI= github.com/bep/golibsass v1.2.0/go.mod h1:DL87K8Un/+pWUS75ggYv41bliGiolxzDKWJAq3eJ1MA= +github.com/bep/goportabletext v0.1.0 h1:8dqym2So1cEqVZiBa4ZnMM1R9l/DnC1h4ONg4J5kujw= +github.com/bep/goportabletext v0.1.0/go.mod h1:6lzSTsSue75bbcyvVc0zqd1CdApuT+xkZQ6Re5DzZFg= github.com/bep/gowebp v0.3.0 h1:MhmMrcf88pUY7/PsEhMgEP0T6fDUnRTMpN8OclDrbrY= github.com/bep/gowebp v0.3.0/go.mod h1:ZhFodwdiFp8ehGJpF4LdPl6unxZm9lLFjxD3z2h2AgI= github.com/bep/helpers v0.5.0 h1:rneezhnG7GzLFlsEWO/EnleaBRuluBDGFimalO6Y50o= @@ -217,6 +219,8 @@ github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1 github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI= +github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/gobuffalo/flect v1.0.3 h1:xeWBM2nui+qnVvNM4S3foBhCAL2XgPU+a7FdpelbTq4= diff --git a/tpl/transform/transform.go b/tpl/transform/transform.go index fc29a46df99..bc6d97cf25e 100644 --- a/tpl/transform/transform.go +++ b/tpl/transform/transform.go @@ -25,6 +25,10 @@ import ( "strings" "sync/atomic" + bp "github.com/gohugoio/hugo/bufferpool" + + "github.com/bep/goportabletext" + "github.com/gohugoio/hugo/cache/dynacache" "github.com/gohugoio/hugo/common/hashing" "github.com/gohugoio/hugo/common/hugio" @@ -197,6 +201,21 @@ func (ns *Namespace) Plainify(s any) (template.HTML, error) { return template.HTML(tpl.StripHTML(ss)), nil } +// PortableText converts the portable text in v to Markdown. +// We may add more options in the future. +func (ns *Namespace) PortableText(v any) (string, error) { + buf := bp.GetBuffer() + defer bp.PutBuffer(buf) + opts := goportabletext.ToMarkdownOptions{ + Dst: buf, + Src: v, + } + if err := goportabletext.ToMarkdown(opts); err != nil { + return "", err + } + return buf.String(), nil +} + // ToMath converts a LaTeX string to math in the given format, default MathML. // This uses KaTeX to render the math, see https://katex.org/. func (ns *Namespace) ToMath(ctx context.Context, args ...any) (template.HTML, error) { diff --git a/tpl/transform/transform_integration_test.go b/tpl/transform/transform_integration_test.go index b9a98185c80..ceb80309bc6 100644 --- a/tpl/transform/transform_integration_test.go +++ b/tpl/transform/transform_integration_test.go @@ -349,3 +349,33 @@ disableKinds = ['page','rss','section','sitemap','taxonomy','term'] b.AssertFileExists("public/index.html", true) b.AssertFileContent("public/index.html", `{"a":{"b":1},"c":{"d":2}}`) } + +func TestPortableText(t *testing.T) { + files := ` +-- hugo.toml -- +-- assets/sample.json -- +[ + { + "_key": "a", + "_type": "block", + "children": [ + { + "_key": "b", + "_type": "span", + "marks": [], + "text": "Heading 2" + } + ], + "markDefs": [], + "style": "h2" + } +] +-- layouts/index.html -- +{{ $markdown := resources.Get "sample.json" | transform.Unmarshal | transform.PortableText }} +Markdown: {{ $markdown }}| + +` + b := hugolib.Test(t, files) + + b.AssertFileContent("public/index.html", "Markdown: ## Heading 2\n|") +}