rclone/lib/http/template.go
Nick Craig-Wood bff702a6f1 docs: group the global flags and make them appear on command and flags pages
This adds an additional parameter to the creation of each flag. This
specifies one or more flag groups. This **must** be set for global
flags and **must not** be set for local flags.

This causes flags.md to be built with sections to aid comprehension
and it causes the documentation pages for each command (and the
`--help`) to be built showing the flags groups as specified in the
`groups` annotation on the command.

See: https://forum.rclone.org/t/make-docs-for-mortals-not-only-rclone-gurus/39476/
2023-08-02 12:53:09 +01:00

116 lines
3.2 KiB
Go

package http
import (
"bytes"
"embed"
"html/template"
"log"
"os"
"time"
"github.com/spf13/pflag"
"github.com/rclone/rclone/fs/config/flags"
)
// TemplateHelp returns a string that describes how to use a custom template
func TemplateHelp(prefix string) string {
help := `
#### Template
` + "`--{{ .Prefix }}template`" + ` allows a user to specify a custom markup template for HTTP
and WebDAV serve functions. The server exports the following markup
to be used within the template to server pages:
| Parameter | Description |
| :---------- | :---------- |
| .Name | The full path of a file/directory. |
| .Title | Directory listing of .Name |
| .Sort | The current sort used. This is changeable via ?sort= parameter |
| | Sort Options: namedirfirst,name,size,time (default namedirfirst) |
| .Order | The current ordering used. This is changeable via ?order= parameter |
| | Order Options: asc,desc (default asc) |
| .Query | Currently unused. |
| .Breadcrumb | Allows for creating a relative navigation |
|-- .Link | The relative to the root link of the Text. |
|-- .Text | The Name of the directory. |
| .Entries | Information about a specific file/directory. |
|-- .URL | The 'url' of an entry. |
|-- .Leaf | Currently same as 'URL' but intended to be 'just' the name. |
|-- .IsDir | Boolean for if an entry is a directory or not. |
|-- .Size | Size in Bytes of the entry. |
|-- .ModTime | The UTC timestamp of an entry. |
`
tmpl, err := template.New("template help").Parse(help)
if err != nil {
log.Fatal("Fatal error parsing template", err)
}
data := struct {
Prefix string
}{
Prefix: prefix,
}
buf := &bytes.Buffer{}
err = tmpl.Execute(buf, data)
if err != nil {
log.Fatal("Fatal error executing template", err)
}
return buf.String()
}
// TemplateConfig for the templating functionality
type TemplateConfig struct {
Path string
}
// AddFlagsPrefix for the templating functionality
func (cfg *TemplateConfig) AddFlagsPrefix(flagSet *pflag.FlagSet, prefix string) {
flags.StringVarP(flagSet, &cfg.Path, prefix+"template", "", cfg.Path, "User-specified template", prefix)
}
// AddTemplateFlagsPrefix for the templating functionality
func AddTemplateFlagsPrefix(flagSet *pflag.FlagSet, prefix string, cfg *TemplateConfig) {
cfg.AddFlagsPrefix(flagSet, prefix)
}
// DefaultTemplateCfg returns a new config which can be customized by command line flags
func DefaultTemplateCfg() TemplateConfig {
return TemplateConfig{}
}
// AfterEpoch returns the time since the epoch for the given time
func AfterEpoch(t time.Time) bool {
return t.After(time.Time{})
}
// Assets holds the embedded filesystem for the default template
//
//go:embed templates
var Assets embed.FS
// GetTemplate returns the HTML template for serving directories via HTTP/WebDAV
func GetTemplate(tmpl string) (*template.Template, error) {
var readFile = os.ReadFile
if tmpl == "" {
tmpl = "templates/index.html"
readFile = Assets.ReadFile
}
data, err := readFile(tmpl)
if err != nil {
return nil, err
}
funcMap := template.FuncMap{
"afterEpoch": AfterEpoch,
}
tpl, err := template.New("index").Funcs(funcMap).Parse(string(data))
if err != nil {
return nil, err
}
return tpl, nil
}