子文件夹中的深度匹配模板文件

时间:2017-05-20 10:22:47

标签: go

我有这个结构:

./src/main.go

package main

import (
  "log"
  "net/http"

  "github.com/djviolin/lanti-mvc-gtpl/src/controllers"
)

func main() {
  http.HandleFunc("/", controllers.Index)

  err := http.ListenAndServe(":8080", nil)
  if err != nil {
    log.Fatal("ListenAndServe: ", err)
  }
}

./src/controllers/index.go

package controllers

import (
  "html/template"
  "log"
  "net/http"
)

// Index : frontpage handler
func Index(w http.ResponseWriter, r *http.Request) {
  t := template.New("index")
  render, err := t.ParseGlob("./views/*.html")
  if err != nil {
    log.Fatal("Parse: ", err)
    return
  }
  render.Execute(w, map[string]string{"Title": "My title", "Body": "This is the body"})
}

我有以下模板文件的结构:

│   index.html
└───partials
        footer.html
        header.html

如何深度匹配子文件夹中的部分?据我所知,ParseGlob不支持**运营商。有没有办法通过标准库模板实现这一目标?

更新

我尝试使用github.com/mattn/go-zglob(在this github问题下推荐)以递归方式列出views文件夹中的所有模板文件:

matches, err := zglob.Glob(`./views/**/*.html`)
if err != nil {
    log.Fatal("Parse: ", err)
    return
}
fmt.Println(matches)
// RETURNS: [views/index.html views/partials/footer.html views/partials/header.html]

返回一个字符串数组,但是ParseFiles函数需要用string逗号分隔的,输入,因此,以下代码抛出此错误:

message: 'cannot use matches (type []string) as type string in argument to t.ParseFiles'

1 个答案:

答案 0 :(得分:0)

我找到了解决方案here。如果有人比这更好,我非常欢迎!

package controllers

// github.com/djviolin/lanti-mvc-gtpl/src/controllers/index.go

import (
    "fmt"
    "html/template"
    "log"
    "net/http"
    "os"
    "path/filepath"
)

// GetAllFilePathsInDirectory : Recursively get all file paths in directory, including sub-directories.
func GetAllFilePathsInDirectory(dirpath string) ([]string, error) {
    var paths []string
    err := filepath.Walk(dirpath, func(path string, info os.FileInfo, err error) error {
        if err != nil {
            return err
        }
        if !info.IsDir() {
            paths = append(paths, path)
        }
        return nil
    })
    if err != nil {
        return nil, err
    }
    return paths, nil
}

// ParseDirectory : Recursively parse all files in directory, including sub-directories.
func ParseDirectory(dirpath string, filename string) (*template.Template, error) {
    paths, err := GetAllFilePathsInDirectory(dirpath)
    if err != nil {
        return nil, err
    }
    fmt.Println(paths) // logging
    t := template.New(filename)
    return t.ParseFiles(paths...)
}

// Index : is the index handler
func Index(w http.ResponseWriter, r *http.Request) {
    render, err := ParseDirectory("./views", "index")
    if err != nil {
        log.Fatal("Parse: ", err)
        return
    }
    render.Execute(w, map[string]string{"Title": "My title", "Body": "This is the body"})
}