无法使用Gin加载HTML模板

I've been having some issues loading html templates using the Gin framework through the r.HTMLRender setting.

It would seem that the templates are not being found.

I have tried to use the following helpers:

Neither of these seem to be working when setting the default path for templates (in my case app/views); for the purposes of getting to this to work my html template file structure looks like this:

/workspace
|-app
  |-views
    |-layouts
      |-application.html
    |-test.html

Here is a sample of the Gin loading code:

import (
    "github.com/gin-contrib/location"
    "github.com/gin-gonic/gin"
    "fmt"
    "os"
    "github.com/gin-gonic/contrib/static"
    "github.com/michelloworld/ez-gin-template"
)

//CORSMiddleware ...
func CORSMiddleware() gin.HandlerFunc {
    /** CORS middleware **/
}

func Router() {

    if os.Getenv("ENVIRONMENT") == "production" {
        gin.SetMode(gin.ReleaseMode)
    }

    // Initialize Gin object
    r := gin.Default()

    // Cors Middleware
    r.Use(CORSMiddleware())

    // Rate limiting
    rl, err := helpers.RateLimiterMiddleware()
    if err != nil {
        panic("Rate Limiting Initialization error")
    }
    r.Use(rl)

    // Asset provision
    r.Use(static.ServeRoot("/public","app/assets"))

    // Get URL information
    r.Use(location.Default())

    // Attempt with EZ Template, fails
    // I ge this error: "runtime error: invalid memory address or nil pointer dereference" when calling c.HTML(...)
    render := eztemplate.New()
    render.TemplatesDir = "app/views/" // default
    render.Layout = "layouts/application"     // default
    render.Ext = ".html"               // default
    render.Debug = true               // default
    r.HTMLRender = render.Init()


    // Attempt with GinHTMLRender, fails
    // I get this error: https://gist.github.com/madhums/4340cbeb36871e227905#file-gin_html_render-go-L110
    /* 
    htmlRender := GinHTMLRender.New()
    htmlRender.TemplatesDir = "app/views/"
    htmlRender.Debug = gin.IsDebugging()
    htmlRender.Layout = "layouts/application"

    log.Println("Dir:"+htmlRender.TemplatesDir)

    r.HTMLRender = htmlRender.Create()*/

    /** Some Routes **/

    // Start web listener

    r.Run(":8009") // listen and serve on 0.0.0.0:8080
}

The corresponding render call is code is the following:

/* c is of type *gin.Context */
c.HTML(200, "test", "")

For some reason it seems like the r.HTMLRender function is not taking into account the template path; I have attempted doing this:

_, err := template.ParseFiles("app/views/test.html")
if err != nil {
    log.Println("Template Error")
} else {
    log.Println("No Template Error")
}

This code consistently displays "No Template Error", which leads me to believe that the HTMLRender assignment is not considering the TemplatesDir set variable.

I've been stuck with this issue for some time, and I am not entirely sure how to get it resolved.

Any help getting this to work would be greatly appreciated.

After doing some further research I found the source of my problem with EZ Gin Template.

I'm hoping this helps anyone experiencing the same issue.

After taking a deeper look at the helper code, I realized that the template matching pattern is strict and does not search for files recursively; ie. it expects a specific file structure to find template files:

In the default setting, EZ Gin Template requires the following file structure to work:

/workspace
- app
  - views
    - layouts
      - some_layout.html
    - some_dir
      - template_file.html
      - _partial_template.html
    - partials
      - _some_other_partial.html

In order to allow for other file patterns, the helper set of functions needs to be modified.

In my case, I forked the helper code locally to allow matching 1st level template files:

func (r Render) Init() Render {
    globalPartials := r.getGlobalPartials()

    layout := r.TemplatesDir + r.Layout + r.Ext

    // Match multiple levels of templates
    viewDirs, _ := filepath.Glob(r.TemplatesDir + "**" + string(os.PathSeparator) + "*" + r.Ext)
    // Added the following two lines to match for app/views/some_file.html as well as files on the **/*.html matching pattern
    tmp, _ := filepath.Glob(r.TemplatesDir + "*" + r.Ext)
    viewDirs = append(viewDirs, tmp...)
    // Can be extended by replicating those two lines above and adding search paths within the base template path.

    fullPartialDir := filepath.Join(r.TemplatesDir + r.PartialDir)
    for _, view := range viewDirs {
        templateFileName := filepath.Base(view)
        //skip partials
        if strings.Index(templateFileName, "_") != 0 && strings.Index(view, fullPartialDir) != 0 {
            localPartials := r.findPartials(filepath.Dir(view))

            renderName := r.getRenderName(view)
            if r.Debug {
                log.Printf("[GIN-debug] %-6s %-25s --> %s
", "LOAD", view, renderName)
            }
            allFiles := []string{layout, view}
            allFiles = append(allFiles, globalPartials...)
            allFiles = append(allFiles, localPartials...)
            r.AddFromFiles(renderName, allFiles...)
        }
    }

    return r
}

I have not tried a similar solution with GinHTMLRenderer, but I expect that the issue might likely be related to it in terms of the expected file structure.