summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortjpcc <tjp@ctrl-c.club>2023-09-16 21:04:50 -0600
committertjpcc <tjp@ctrl-c.club>2023-09-16 21:04:50 -0600
commitf2b044364129ee9e4f66348e747bd53b4d7e55ac (patch)
tree30dd86661efa3ed179d99b95c2ba663dbe367cc2
parenta38d04936cd859711dfb0938d5cb998ffc9ce247 (diff)
support template overrides
-rw-r--r--gemini.go71
-rw-r--r--templates.go18
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
+}