Skip to content

Commit

Permalink
Added static template loading
Browse files Browse the repository at this point in the history
  • Loading branch information
diamondap committed Mar 26, 2024
1 parent 58bcae5 commit 4bc668a
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 51 deletions.
61 changes: 61 additions & 0 deletions server/dev_loader.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//go:build xxx

package server

import (
"html/template"

"github.com/APTrust/dart-runner/constants"
"github.com/APTrust/dart-runner/core"
"github.com/APTrust/dart-runner/util"
"github.com/gin-gonic/gin"
)

// initTemplates loads templates and sets up template helper functions.
func initTemplates(router *gin.Engine) {

// Note: We can't put workflowList in util with the
// other template helpers because it creates a cyclical
// import cycle between core and util. So we define the
// body of that helper here inline.

router.SetFuncMap(template.FuncMap{
"add": util.Add,
"dateISO": util.DateISO,
"dateTimeISO": util.DateTimeISO,
"dateTimeUS": util.DateTimeUS,
"dateUS": util.DateUS,
"dict": util.Dict,
"dirStats": util.DirStats,
"displayDate": util.DisplayDate,
"escapeAttr": util.EscapeAttr,
"escapeHTML": util.EscapeHTML,
"fileIconFor": util.FileIconFor,
"humanSize": util.HumanSize,
"mod": util.Mod,
"strEq": util.StrEq,
"strStartsWith": util.StrStartsWith,
"truncate": util.Truncate,
"truncateMiddle": util.TruncateMiddle,
"truncateStart": util.TruncateStart,
"unixToISO": util.UnixToISO,
"workflowList": func() []core.NameIDPair { return core.ObjNameIdList(constants.TypeWorkflow) },
"yesNo": util.YesNo,
})

// Load the view templates
// If we're running from main, templates will come
// from ./views. When running tests, templates come
// from ../../views because http tests run from web
// from ../../../views for member api and admin api
// sub directory.
if util.FileExists("./views") {
router.LoadHTMLGlob("./views/**/*.html")
} else if util.FileExists("./server/views") {
router.LoadHTMLGlob("./server/views/**/*.html")
} else if util.FileExists("../server/views") {
router.LoadHTMLGlob("../server/views/**/*.html")
} else {
router.LoadHTMLGlob("../../server/views/**/*.html")
}
}
90 changes: 90 additions & 0 deletions server/release_loader.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package server

import (
"embed"
"fmt"
"html/template"
"io/fs"
"regexp"
"strings"

"github.com/APTrust/dart-runner/constants"
"github.com/APTrust/dart-runner/core"
"github.com/APTrust/dart-runner/util"
"github.com/gin-gonic/gin"
)

//go:embed views
var views embed.FS

//go:embed assets
var assets embed.FS

// initTemplates loads templates and sets up template helper functions.
func initTemplates(router *gin.Engine) {

// Note: We can't put workflowList in util with the
// other template helpers because it creates a cyclical
// import cycle between core and util. So we define the
// body of that helper here inline.

router.SetFuncMap(template.FuncMap{
"add": util.Add,
"dateISO": util.DateISO,
"dateTimeISO": util.DateTimeISO,
"dateTimeUS": util.DateTimeUS,
"dateUS": util.DateUS,
"dict": util.Dict,
"dirStats": util.DirStats,
"displayDate": util.DisplayDate,
"escapeAttr": util.EscapeAttr,
"escapeHTML": util.EscapeHTML,
"fileIconFor": util.FileIconFor,
"humanSize": util.HumanSize,
"mod": util.Mod,
"strEq": util.StrEq,
"strStartsWith": util.StrStartsWith,
"truncate": util.Truncate,
"truncateMiddle": util.TruncateMiddle,
"truncateStart": util.TruncateStart,
"unixToISO": util.UnixToISO,
"workflowList": func() []core.NameIDPair { return core.ObjNameIdList(constants.TypeWorkflow) },
"yesNo": util.YesNo,
})

loadHTMLFromEmbedFS(router, views, "*.html")
}

// Next two functions courtest of https://github.com/gin-gonic/gin/issues/2795

// loadHTMLFromEmbedFS loads HTML templates from an embedded file system
func loadHTMLFromEmbedFS(engine *gin.Engine, embedFS embed.FS, pattern string) {
root := template.New("")
tmpl := template.Must(root, loadAndAddToRoot(engine.FuncMap, root, embedFS, pattern))
engine.SetHTMLTemplate(tmpl)
}

// loadAndAddToRoot recursively loads and parses template files from embedded FS
func loadAndAddToRoot(funcMap template.FuncMap, rootTemplate *template.Template, embedFS embed.FS, pattern string) error {
pattern = strings.ReplaceAll(pattern, ".", "\\.")
pattern = strings.ReplaceAll(pattern, "*", ".*")

err := fs.WalkDir(embedFS, ".", func(path string, d fs.DirEntry, walkErr error) error {
if walkErr != nil {
return walkErr
}
if matched, _ := regexp.MatchString(pattern, path); !d.IsDir() && matched {
data, readErr := embedFS.ReadFile(path)
if readErr != nil {
return readErr
}
t := rootTemplate.New(path).Funcs(funcMap)
if _, parseErr := t.Parse(string(data)); parseErr != nil {
return parseErr
}
fmt.Println(" template", path)
}
return nil
})
return err
}
51 changes: 0 additions & 51 deletions server/server.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package server

import (
"html/template"
"io"

"github.com/APTrust/dart-runner/constants"
"github.com/APTrust/dart-runner/core"
"github.com/APTrust/dart-runner/server/controllers"
"github.com/APTrust/dart-runner/util"
"github.com/gin-gonic/gin"
)

Expand Down Expand Up @@ -40,55 +38,6 @@ func InitAppEngine(discardStdOut bool) *gin.Engine {
return r
}

// initTemplates loads templates and sets up template helper functions.
func initTemplates(router *gin.Engine) {

// Note: We can't put workflowList in util with the
// other template helpers because it creates a cyclical
// import cycle between core and util. So we define the
// body of that helper here inline.

router.SetFuncMap(template.FuncMap{
"add": util.Add,
"dateISO": util.DateISO,
"dateTimeISO": util.DateTimeISO,
"dateTimeUS": util.DateTimeUS,
"dateUS": util.DateUS,
"dict": util.Dict,
"dirStats": util.DirStats,
"displayDate": util.DisplayDate,
"escapeAttr": util.EscapeAttr,
"escapeHTML": util.EscapeHTML,
"fileIconFor": util.FileIconFor,
"humanSize": util.HumanSize,
"mod": util.Mod,
"strEq": util.StrEq,
"strStartsWith": util.StrStartsWith,
"truncate": util.Truncate,
"truncateMiddle": util.TruncateMiddle,
"truncateStart": util.TruncateStart,
"unixToISO": util.UnixToISO,
"workflowList": func() []core.NameIDPair { return core.ObjNameIdList(constants.TypeWorkflow) },
"yesNo": util.YesNo,
})

// Load the view templates
// If we're running from main, templates will come
// from ./views. When running tests, templates come
// from ../../views because http tests run from web
// from ../../../views for member api and admin api
// sub directory.
if util.FileExists("./views") {
router.LoadHTMLGlob("./views/**/*.html")
} else if util.FileExists("./server/views") {
router.LoadHTMLGlob("./server/views/**/*.html")
} else if util.FileExists("../server/views") {
router.LoadHTMLGlob("../server/views/**/*.html")
} else {
router.LoadHTMLGlob("../../server/views/**/*.html")
}
}

func initRoutes(router *gin.Engine) {

// This ensures that routes match even when they contain
Expand Down

0 comments on commit 4bc668a

Please sign in to comment.