Repository: caddyserver/caddy
File: modules/caddyhttp/fileserver/browsetplcontext.go (Go)

Code before:
			continue
		}

		isDir := entry.IsDir() || fsrv.isSymlinkTargetDir(info, root, urlPath)

		// add the slash after the escape of path to avoid escaping the slash as well
		if isDir {
			name += "/"
			tplCtx.NumDirs++
		} else {
			tplCtx.NumFiles++
		}

		size := info.Size()
		fileIsSymlink := isSymlink(info)
		symLinkRepresentation := ""
		if fileIsSymlink {
			path := caddyhttp.SanitizedPathJoin(root, path.Join(urlPath, info.Name()))
			fileInfo, err := fs.Stat(fsrv.fileSystem, path)
			if err == nil {
				size = fileInfo.Size()
			}

			symLinkTarget, err := filepath.EvalSymlinks(path)
			if err == nil {
				symLinkRepresentation = name + " -> " + symLinkTarget
			}
			// An error most likely means the symlink target doesn't exist,
			// which isn't entirely unusual and shouldn't fail the listing.
			// In this case, just use the size of the symlink itself, which
			// was already set above.
		}

		u := url.URL{Path: "./" + name} // prepend with "./" to fix paths with ':' in the name

		// Switch the name to the symlink representation if the entry is a symlink
		if fsrv.Browse.RevealSymlink && symLinkRepresentation != "" {
			name = symLinkRepresentation
		}

		tplCtx.Items = append(tplCtx.Items, fileInfo{
			IsDir:     isDir,
			IsSymlink: fileIsSymlink,
			Name:      name,
			Size:      size,
			URL:       u.String(),
			ModTime:   info.ModTime().UTC(),
			Mode:      info.Mode(),
			Tpl:       tplCtx, // a reference up to the template context is useful
		})
	}

Review comment (suggestion):
Actually, how about if we use a Tabler SVG icon for this arrow?

```
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-arrow-narrow-right" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M5 12l14 0" /><path d="M15 16l4 -4" /><path d="M15 8l4 4" /></svg>
```

Code after:
			continue
		}

		isDir := entry.IsDir() || fsrv.isSymlinkTargetDir(fileSystem, info, root, urlPath)

		// add the slash after the escape of path to avoid escaping the slash as well
		if isDir {
			name += "/"
			tplCtx.NumDirs++
		} else {
			tplCtx.NumFiles++
		}

		size := info.Size()
		fileIsSymlink := isSymlink(info)
		symlinkPath := ""
		if fileIsSymlink {
			path := caddyhttp.SanitizedPathJoin(root, path.Join(urlPath, info.Name()))
			fileInfo, err := fs.Stat(fileSystem, path)
			if err == nil {
				size = fileInfo.Size()
			}

			if fsrv.Browse.RevealSymlinks {
				symLinkTarget, err := filepath.EvalSymlinks(path)
				if err == nil {
					symlinkPath = symLinkTarget
				}
			}

			// An error most likely means the symlink target doesn't exist,
			// which isn't entirely unusual and shouldn't fail the listing.
			// In this case, just use the size of the symlink itself, which
			// was already set above.
		}

		if !isDir {
			tplCtx.TotalFileSize += size
		}

		u := url.URL{Path: "./" + name} // prepend with "./" to fix paths with ':' in the name

		tplCtx.Items = append(tplCtx.Items, fileInfo{
			IsDir:       isDir,
			IsSymlink:   fileIsSymlink,
			Name:        name,
			Size:        size,
			URL:         u.String(),
			ModTime:     info.ModTime().UTC(),
			Mode:        info.Mode(),
			Tpl:         tplCtx, // a reference up to the template context is useful