-3

I am trying to use http templates in Go to render all the files in a specific folder on the webpage in a list. Every file or folder should also link to it's respective path. I've achieved reading all the items in a folder and saving them to these structs

type Item struct {
    Name     string      
    IsFolder bool        
    Info     os.FileInfo 
}

// Items contains a slice of all items in a folder
type Items struct {
    Parent string 
    Items  []Item 
}

This is then passed on to a template.ExecuteTemplate function. The template in question looks like this:

<html>
<head>
    <title>website</title>
</head>
<body>
    <h1>Welcome to my website</h1>
    <p>Files in {{.Parent}}</p>
    <ul>
        <li><a href="ftp?f={{ .Parent }}">{{.Parent}}</a></li>
        {{range .Items}} {{if .IsFolder}}
        <li><a href="ftp?f={{ .Parent }}/{{ .Name }}">{{ .Name }}</a></li>
        {{else}}
        <li><a href="ftp?f={{ .Parent }}/{{ .Name }}">{{.Name}}</a></li>
        {{end}} {{end}}
    </ul>
</body>
</html>

My problem however, is that when loading the page, the only thing that is returned is the beginning up until

<li><a href="ftp?f={{ .Parent }}/{{ .Name }}">{{ .Name }}</a></li>

And it stops right after the ?f= Now, I've tested it before with only {{ .Name }} and that worked absolutely fine, except of course, the link doesn't go anywhere. Rendering {{ .Parent }} in the list place above that one works absolutely fine. It also doesn't work if I simply remove the /, that produces exactly the same problem.

Of course my question is Why this happens and how I would go about fixing it.

Ps. you might notice a small security vulnerability, that if you put ../ in the ftp?f= field, you go up the filetree. Yes I know about this, and I will try and fix that. If you have a suggestion on how to fix that, you can also tell me :)

2 Answers2

1

After {{range .Items}} until the matching {{end}}, the template runs with the context set to the loop variable, i.e. an Item. An Item does not have parent. You can reach the global context using $: use {{$.Parent}} instead.

Burak Serdar
  • 46,455
  • 3
  • 40
  • 59
0

Inside your loop, . is the current Item, and since there is no Item.Parent field, there is no .Parent in the loop.

Adrian
  • 42,911
  • 6
  • 107
  • 99