[feature] allow absolute path to templates (#507)

Only attempt to join the `WebTemplateBaseDir` with the current working
directory if the user has not configured an absolute path to the
template directory.

This changeset also makes a similar change to the testrig, allowing
tests to configure an alternative location for the templates directory.

Fixes #411

Signed-off-by: Terin Stock <terinjokes@gmail.com>
This commit is contained in:
Terin Stock 2022-04-29 02:00:25 -07:00 committed by GitHub
parent c36fbab86f
commit f9b351438b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 28 deletions

View File

@ -28,14 +28,16 @@ import (
) )
func loadTemplates(templateBaseDir string) (*template.Template, error) { func loadTemplates(templateBaseDir string) (*template.Template, error) {
cwd, err := os.Getwd() if !filepath.IsAbs(templateBaseDir) {
if err != nil { cwd, err := os.Getwd()
return nil, fmt.Errorf("error getting current working directory: %s", err) if err != nil {
return nil, fmt.Errorf("error getting current working directory: %s", err)
}
templateBaseDir = filepath.Join(cwd, templateBaseDir)
} }
// look for all templates that start with 'email_' // look for all templates that start with 'email_'
tmPath := filepath.Join(cwd, fmt.Sprintf("%semail_*", templateBaseDir)) return template.ParseGlob(filepath.Join(templateBaseDir, "email_*"))
return template.ParseGlob(tmPath)
} }
// https://datatracker.ietf.org/doc/html/rfc2822 // https://datatracker.ietf.org/doc/html/rfc2822

View File

@ -33,20 +33,22 @@ import (
// LoadTemplates loads html templates for use by the given engine // LoadTemplates loads html templates for use by the given engine
func loadTemplates(engine *gin.Engine) error { func loadTemplates(engine *gin.Engine) error {
cwd, err := os.Getwd()
if err != nil {
return fmt.Errorf("error getting current working directory: %s", err)
}
templateBaseDir := viper.GetString(config.Keys.WebTemplateBaseDir) templateBaseDir := viper.GetString(config.Keys.WebTemplateBaseDir)
_, err = os.Stat(filepath.Join(cwd, templateBaseDir, "index.tmpl")) if !filepath.IsAbs(templateBaseDir) {
if err != nil { cwd, err := os.Getwd()
return fmt.Errorf("%s doesn't seem to contain the templates; index.tmpl is missing: %s", filepath.Join(cwd, templateBaseDir), err) if err != nil {
return fmt.Errorf("error getting current working directory: %w", err)
}
templateBaseDir = filepath.Join(cwd, viper.GetString(config.Keys.WebTemplateBaseDir))
} }
tmPath := filepath.Join(cwd, fmt.Sprintf("%s*", templateBaseDir)) if _, err := os.Stat(filepath.Join(templateBaseDir, "index.tmpl")); err != nil {
engine.LoadHTMLGlob(tmPath) return fmt.Errorf("%s doesn't seem to contain the templates; index.tmpl is missing: %w", templateBaseDir, err)
}
engine.LoadHTMLGlob(fmt.Sprintf("%s*", templateBaseDir))
return nil return nil
} }

View File

@ -33,7 +33,14 @@ import (
) )
// NewTestRouter returns a Router suitable for testing // NewTestRouter returns a Router suitable for testing
//
// If the environment variable GTS_WEB_TEMPLATE_BASE_DIR set, it will take that
// value as the template base directory instead.
func NewTestRouter(db db.DB) router.Router { func NewTestRouter(db db.DB) router.Router {
if alternativeTemplateBaseDir := os.Getenv("GTS_WEB_TEMPLATE_BASE_DIR"); alternativeTemplateBaseDir != "" {
viper.Set(config.Keys.WebTemplateBaseDir, alternativeTemplateBaseDir)
}
r, err := router.New(context.Background(), db) r, err := router.New(context.Background(), db)
if err != nil { if err != nil {
panic(err) panic(err)
@ -43,23 +50,24 @@ func NewTestRouter(db db.DB) router.Router {
// ConfigureTemplatesWithGin will panic on any errors related to template loading during tests // ConfigureTemplatesWithGin will panic on any errors related to template loading during tests
func ConfigureTemplatesWithGin(engine *gin.Engine) { func ConfigureTemplatesWithGin(engine *gin.Engine) {
router.LoadTemplateFunctions(engine) router.LoadTemplateFunctions(engine)
// https://stackoverflow.com/questions/31873396/is-it-possible-to-get-the-current-root-of-package-structure-as-a-string-in-golan
_, runtimeCallerLocation, _, _ := runtime.Caller(0)
projectRoot, err := filepath.Abs(filepath.Join(filepath.Dir(runtimeCallerLocation), "../"))
if err != nil {
panic(err)
}
templateBaseDir := viper.GetString(config.Keys.WebTemplateBaseDir) templateBaseDir := viper.GetString(config.Keys.WebTemplateBaseDir)
_, err = os.Stat(filepath.Join(projectRoot, templateBaseDir, "index.tmpl")) if !filepath.IsAbs(templateBaseDir) {
if err != nil { // https://stackoverflow.com/questions/31873396/is-it-possible-to-get-the-current-root-of-package-structure-as-a-string-in-golan
panic(fmt.Errorf("%s doesn't seem to contain the templates; index.tmpl is missing: %s", filepath.Join(projectRoot, templateBaseDir), err)) _, runtimeCallerLocation, _, _ := runtime.Caller(0)
projectRoot, err := filepath.Abs(filepath.Join(filepath.Dir(runtimeCallerLocation), "../"))
if err != nil {
panic(err)
}
templateBaseDir = filepath.Join(projectRoot, templateBaseDir)
} }
tmPath := filepath.Join(projectRoot, fmt.Sprintf("%s*", templateBaseDir)) if _, err := os.Stat(filepath.Join(templateBaseDir, "index.tmpl")); err != nil {
engine.LoadHTMLGlob(tmPath) panic(fmt.Errorf("%s doesn't seem to contain the templates; index.tmpl is missing: %w", templateBaseDir, err))
}
engine.LoadHTMLGlob(filepath.Join(templateBaseDir, "*"))
} }