a-h / templ

A language for writing HTML user interfaces in Go.
https://templ.guide/
MIT License
7.14k stars 236 forks source link

Script application/ld+json #799

Closed ainsleyclark closed 1 week ago

ainsleyclark commented 1 week ago

Hi,

When trying to output JSON data in <script type="application/ld+json"> the data is escaped:

.templ

if props.Org != nil {
    <script type="application/ld+json">
        { marshal(props.Org) }
    </script>
}

.go

_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<script type=\"application/ld+json\">\n\t \t\t{ marshal(props.Org) }\n\t\t</script>")

As a result I'm appending the script type to a marshal func:

func marshal(v any) string {
    b, err := json.Marshal(v)
    if err != nil {
        slog.Error(err.Error())
        return ""
    }
    return `<script type="application/ld+json">` + string(b) + `</script>`
}

Is there a way to do this inine?

a-h commented 1 week ago

There's a feature in the next release that will allow you to write script tags that contain JSON: https://github.com/a-h/templ/blob/main/jsonscript.go

But, I notice that it doesn't have a way to override the "type" attribute to ld+json, so I'll add that.

So, in the next release, you'll be able to do:

if props.Org != nil {
    @templ.JSONScript(props.Org).WithType("application/ld+json")
}
ainsleyclark commented 1 week ago

Amazing thank you @a-h!

a-h commented 1 week ago

Added in https://github.com/a-h/templ/commit/94c1028906535eba5b8a33c2c5babd82ea785ca8

In the meantime, you can copy the code into your own app, or you could implement the templ.Component interface on whatever the Org type is:

type Org struct {
  FieldA string
}

func (o Org) Render(ctx context.Context, w io.Writer) (err error) {
    if _, err = io.WriteString(w, "<script type\"application/ld+json\">"); err != nil {
        return err
    }
    if err = json.NewEncoder(w).Encode(j.Data); err != nil {
        return err
    }
    if _, err = io.WriteString(w, "</script>"); err != nil {
        return err
    }
    return nil
}
ainsleyclark commented 1 week ago

Thanks @a-h