1
0
mirror of https://github.com/a-h/templ.git synced 2025-02-06 09:45:21 +00:00

feat: templ.JSONScript: support setting type attribute

This commit is contained in:
Adrian Hesketh 2024-06-22 12:00:33 +01:00
parent 69bfdb1faa
commit 94c1028906
No known key found for this signature in database
GPG Key ID: 9E01387222323123
3 changed files with 35 additions and 5 deletions

View File

@ -1 +1 @@
0.2.725
0.2.726

View File

@ -14,11 +14,19 @@ var _ Component = JSONScriptElement{}
func JSONScript(id string, data any) JSONScriptElement {
return JSONScriptElement{
ID: id,
Type: "application/json",
Data: data,
Nonce: GetNonce,
}
}
// WithType sets the value of the type attribute of the script element.
func (j JSONScriptElement) WithType(t string) JSONScriptElement {
j.Type = t
return j
}
// WithNonceFromString sets the value of the nonce attribute of the script element to the given string.
func (j JSONScriptElement) WithNonceFromString(nonce string) JSONScriptElement {
j.Nonce = func(context.Context) string {
return nonce
@ -26,6 +34,7 @@ func (j JSONScriptElement) WithNonceFromString(nonce string) JSONScriptElement {
return j
}
// WithNonceFrom sets the value of the nonce attribute of the script element to the value returned by the given function.
func (j JSONScriptElement) WithNonceFrom(f func(context.Context) string) JSONScriptElement {
j.Nonce = f
return j
@ -34,6 +43,8 @@ func (j JSONScriptElement) WithNonceFrom(f func(context.Context) string) JSONScr
type JSONScriptElement struct {
// ID of the element in the DOM.
ID string
// Type of the script element, defaults to "application/json".
Type string
// Data that will be encoded as JSON.
Data any
// Nonce is a function that returns a CSP nonce.
@ -43,11 +54,25 @@ type JSONScriptElement struct {
}
func (j JSONScriptElement) Render(ctx context.Context, w io.Writer) (err error) {
var nonceAttr string
if nonce := j.Nonce(ctx); nonce != "" {
nonceAttr = fmt.Sprintf(" nonce=\"%s\"", EscapeString(nonce))
if _, err = io.WriteString(w, "<script"); err != nil {
return err
}
if _, err = fmt.Fprintf(w, "<script id=\"%s\" type=\"application/json\"%s>", EscapeString(j.ID), nonceAttr); err != nil {
if j.ID != "" {
if _, err = fmt.Fprintf(w, " id=\"%s\"", EscapeString(j.ID)); err != nil {
return err
}
}
if j.Type != "" {
if _, err = fmt.Fprintf(w, " type=\"%s\"", EscapeString(j.Type)); err != nil {
return err
}
}
if nonce := j.Nonce(ctx); nonce != "" {
if _, err = fmt.Fprintf(w, " nonce=\"%s\"", EscapeString(nonce)); err != nil {
return err
}
}
if _, err = io.WriteString(w, ">"); err != nil {
return err
}
if err = json.NewEncoder(w).Encode(j.Data); err != nil {

View File

@ -38,6 +38,11 @@ func TestJSONScriptElement(t *testing.T) {
e: templ.JSONScript("idf", data).WithNonceFrom(func(context.Context) string { return "nonce-from-function" }),
expected: "<script id=\"idf\" type=\"application/json\" nonce=\"nonce-from-function\">{\"foo\":\"bar\"}\n</script>",
},
{
name: "if a type is provided, it is used",
e: templ.JSONScript("idt", data).WithType("application/ld+json"),
expected: "<script id=\"idt\" type=\"application/ld+json\">{\"foo\":\"bar\"}\n</script>",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {