From f2b044364129ee9e4f66348e747bd53b4d7e55ac Mon Sep 17 00:00:00 2001 From: tjpcc Date: Sat, 16 Sep 2023 21:04:50 -0600 Subject: support template overrides --- gemini.go | 71 +++++++++++++++++++++++++++++++++--------------------------- templates.go | 18 +++++++++++++++ 2 files changed, 57 insertions(+), 32 deletions(-) diff --git a/gemini.go b/gemini.go index 6222684..e6e936f 100644 --- a/gemini.go +++ b/gemini.go @@ -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 +} -- cgit v1.2.3