diff options
author | tjpcc <tjp@ctrl-c.club> | 2023-09-16 21:04:50 -0600 |
---|---|---|
committer | tjpcc <tjp@ctrl-c.club> | 2023-09-16 21:04:50 -0600 |
commit | f2b044364129ee9e4f66348e747bd53b4d7e55ac (patch) | |
tree | 30dd86661efa3ed179d99b95c2ba663dbe367cc2 | |
parent | a38d04936cd859711dfb0938d5cb998ffc9ce247 (diff) |
support template overrides
-rw-r--r-- | gemini.go | 71 | ||||
-rw-r--r-- | templates.go | 18 |
2 files changed, 57 insertions, 32 deletions
@@ -19,19 +19,24 @@ const ( reponamekey = "syw_reponame" ) -func GeminiRouter(repodir string) *sliderule.Router { +func GeminiRouter(repodir string, overrides *template.Template) *sliderule.Router { + tmpl, err := addTemplates(geminiTemplate, overrides) + if err != nil { + panic(err) + } + repoRouter := &sliderule.Router{} repoRouter.Use(assignRepo(repodir)) - repoRouter.Route("/", gmiTemplate(geminiTemplate, "repo_home.gmi")) - repoRouter.Route("/branches", gmiTemplate(geminiTemplate, "branch_list.gmi")) - repoRouter.Route("/tags", gmiTemplate(geminiTemplate, "tag_list.gmi")) - repoRouter.Route("/refs/:ref/", gmiTemplate(geminiTemplate, "ref.gmi")) - repoRouter.Route("/refs/:ref/tree/*path", sliderule.HandlerFunc(geminiTreePath)) - repoRouter.Route("/diffstat/:fromref/:toref", runTemplate(geminiTemplate, "diffstat.gmi", "text/plain")) - repoRouter.Route("/diff/:fromref/:toref", runTemplate(geminiTemplate, "diff.gmi", "text/x-diff")) + repoRouter.Route("/", gmiTemplate(tmpl, "repo_home.gmi")) + repoRouter.Route("/branches", gmiTemplate(tmpl, "branch_list.gmi")) + repoRouter.Route("/tags", gmiTemplate(tmpl, "tag_list.gmi")) + repoRouter.Route("/refs/:ref/", gmiTemplate(tmpl, "ref.gmi")) + repoRouter.Route("/refs/:ref/tree/*path", geminiTreePath(tmpl)) + repoRouter.Route("/diffstat/:fromref/:toref", runTemplate(tmpl, "diffstat.gmi", "text/plain")) + repoRouter.Route("/diff/:fromref/:toref", runTemplate(tmpl, "diff.gmi", "text/x-diff")) router := &sliderule.Router{} - router.Route("/", geminiRoot(repodir)) + router.Route("/", geminiRoot(repodir, tmpl)) router.Mount("/:"+reponamekey, repoRouter) return router @@ -46,7 +51,7 @@ func assignRepo(repodir string) sliderule.Middleware { } } -func geminiRoot(repodir string) sliderule.Handler { +func geminiRoot(repodir string, tmpl *template.Template) sliderule.Handler { return sliderule.HandlerFunc(func(ctx context.Context, request *sliderule.Request) *sliderule.Response { entries, err := os.ReadDir(repodir) if err != nil { @@ -61,7 +66,7 @@ func geminiRoot(repodir string) sliderule.Handler { } buf := &bytes.Buffer{} - if err := geminiTemplate.ExecuteTemplate(buf, "repo_root.gmi", names); err != nil { + if err := tmpl.ExecuteTemplate(buf, "repo_root.gmi", names); err != nil { return gemini.Failure(err) } @@ -69,31 +74,33 @@ func geminiRoot(repodir string) sliderule.Handler { }) } -func geminiTreePath(ctx context.Context, request *sliderule.Request) *sliderule.Response { - params := sliderule.RouteParams(ctx) - if params["path"] == "" || strings.HasSuffix(params["path"], "/") { - return gmiTemplate(geminiTemplate, "tree.gmi").Handle(ctx, request) - } +func geminiTreePath(tmpl *template.Template) sliderule.Handler { + return sliderule.HandlerFunc(func(ctx context.Context, request *sliderule.Request) *sliderule.Response { + params := sliderule.RouteParams(ctx) + if params["path"] == "" || strings.HasSuffix(params["path"], "/") { + return gmiTemplate(tmpl, "tree.gmi").Handle(ctx, request) + } - repo := ctx.Value(repokey).(*Repository) + repo := ctx.Value(repokey).(*Repository) - body, err := repo.Blob(ctx, params["ref"], params["path"]) - if err != nil { - return gemini.Failure(err) - } + body, err := repo.Blob(ctx, params["ref"], params["path"]) + if err != nil { + return gemini.Failure(err) + } - mediaType := "" - ext := path.Ext(params["path"]) - if ext == ".gmi" { - mediaType = "text/gemini; charset=utf-8" - } else { - mediaType = mime.TypeByExtension(ext) - } - if mediaType == "" { - mediaType = "application/octet-stream" - } + mediaType := "" + ext := path.Ext(params["path"]) + if ext == ".gmi" { + mediaType = "text/gemini; charset=utf-8" + } else { + mediaType = mime.TypeByExtension(ext) + } + if mediaType == "" { + mediaType = "application/octet-stream" + } - return gemini.Success(mediaType, bytes.NewBuffer(body)) + return gemini.Success(mediaType, bytes.NewBuffer(body)) + }) } func gmiTemplate(tmpl *template.Template, name string) sliderule.Handler { diff --git a/templates.go b/templates.go index ddce7ea..e31f06f 100644 --- a/templates.go +++ b/templates.go @@ -8,3 +8,21 @@ import ( //go:embed templates/*.gmi var geminiTemplateFS embed.FS var geminiTemplate = template.Must(template.ParseFS(geminiTemplateFS, "templates/*.gmi")) + +func addTemplates(base *template.Template, additions *template.Template) (*template.Template, error) { + base, err := base.Clone() + if err != nil { + return nil, err + } + if additions == nil { + return base, nil + } + + for _, addition := range additions.Templates() { + if _, err := base.AddParseTree(addition.Name(), addition.Tree); err != nil { + return nil, err + } + } + + return base, nil +} |