jack t
jack t

Reputation: 31

How do I pass an img tag its href value through a Go template successfully?

I am attempting to build a page on a personal website to display a series of posts. The post content is stored in a JSON file so I am reading it, and then ranging over the result using Go to inject the values of each 'post' into an HTML template.

My templates look like:

{{define "post"}}
<div>
    <div class="post-header">
        <h1>{{.Title}}</h1>
    </div>

    <div class="post-image">
        <img href="/static/img/content/{{.ImageRef}}"/>
        <p>{{.ImageCaption}}</p>
    </div>

    <div class="post-body">
        {{.Text}}
    </div>

    <div class="post-footer">
        <p>Published: {{.Created}}</p>
    </div>

</div>
{{end}}

and

{{define "main"}}
 <h2>All Posts</h2>
 <p>posts will go here</p>


 {{range .Posts}}    
    {{template "post" .}}
 {{end}}
{{end}}

Currently the template successfully receives the data from the parsed JSON, and even interpolates the correct value into the href property (viewed though Chrome inspector); however, the image does not display at all (the tag is present with the correct href but has a 0x0 size).

I would like to fix this so that I can dynamically pass part of the URL of various images from my fileserver to posts and have them correctly render the image.

My Go code:

func (app *application) handlePosts(w http.ResponseWriter, r *http.Request) {

//initialise a slice containing all templates we want to load
files := []string{
    "./ui/html/pages/base.tmpl.html",
    "./ui/html/pages/posts.tmpl.html",
    "./ui/html/partials/post.tmpl.html",
    "./ui/html/partials/nav.tmpl.html",
}

posts_json, err := os.Open("./content/posts/test_posts.json")
if err != nil {
    app.serverError(w, err)
    return
}
defer posts_json.Close()

read, err := io.ReadAll(posts_json)
if err != nil {
    app.serverError(w, err)
    return
}

var posts models.Posts
if err := json.Unmarshal(read, &posts); err != nil {
    app.serverError(w, err)
    return
}

// Parse html template.
ts, err := template.ParseFiles(files...)
if err != nil {
    app.serverError(w, err)
    return
}

// Execute template.
if err = ts.ExecuteTemplate(w, "base", posts); err != nil {
    app.serverError(w, err)
    return
}
}

Edit: Further I should mention I saw in other questions that it could have to do with passing URLs to templates and that not being safe. Originally I was passing the entire URL for an image but switched to only the postfix like in the example above; while cleaner, this did not fix the issue. I also tried changing the type of the field containing the ref to template.URL so that un-marshalled data is already in the correct format, however that had no effect either.

Upvotes: 1

Views: 91

Answers (1)

jack t
jack t

Reputation: 31

Somewhat embarrassing but perhaps others might make the same mistake! My intention was to link an image in my static fileserver to an <img> tag to render on a web page.

I mistakenly used the href property instead of src which is why it wasn't working as the URL lead to a .png file, not valid HTML.

Upvotes: 0

Related Questions