Question: This is my directory structure:

```
app/
  template/
    layout/
      base.tmpl
    index.tmpl

```

`template.ParseGlob("*/*.tmpl")` parses `index.tmpl` but not `base.tmpl` in the `layout` subdirectory. Is there a way to parse all templates recursively?

Answer: 
Datsik's answer has the drawback that there are name collision issues when several directories contain many templates. If two templates in different directories have the same filename it won't work properly: only the second of them will be usable.

This is caused by the implementation of template.ParseFiles, so we can solve it by avoiding template.ParseFiles. Here's a modified walk algorithm that does this by using template.Parse directly instead.

```
func findAndParseTemplates(rootDir string, funcMap template.FuncMap) (*template.Template, error) {
    cleanRoot := filepath.Clean(rootDir)
    pfx := len(cleanRoot)+1
    root := template.New("")

    err := filepath.Walk(cleanRoot, func(path string, info os.FileInfo, e1 error) error {
        if !info.IsDir() && strings.HasSuffix(path, ".html") {
            if e1 != nil {
                return e1
            }

            b, e2 := ioutil.ReadFile(path)
            if e2 != nil {
                return e2
            }

            name := path[pfx:]
            t := root.New(name).Funcs(funcMap)
            _, e2 = t.Parse(string(b))
            if e2 != nil {
                return e2
            }
        }

        return nil
    })

    return root, err
}

```

This will parse all your templates then you can render them by calling their names e.g.

```
template.ExecuteTemplate(w, "a/home.html", nil)

```
With the answer of pete911 I could create this function to parse all the html templates on multiple subdirectories.

```golang
// parse.go
func ParseHtmlTemplates() *template.Template {
    var directories []string
    var filenames []string

    // Root directory of template files
    root := "./templates"

    // Get all directories on /templates and check if there's repeated files
    err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
        if !info.IsDir() {
            // Is file
            filename := info.Name()

            hasRepeatedFiles := contains(filenames, filename)
            if hasRepeatedFiles {
                return fmt.Errorf("You can't have repeated template files: %s", filename)
            }

            filenames = append(filenames, filename)
        } else {
            // Is directory
            directories = append(directories, path)
        }

        return nil
    })
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }

    // Create a template for parsing all directories
    tmpl := template.Must(template.ParseGlob(root + "/*.html"))

    // Parse all directories (minus the root directory)
    for _, path := range directories[1:] {
        pattern := path + "/*.html"
        template.Must(tmpl.ParseGlob(pattern))
    }

    return tmpl
}

// contains private method
func contains(filenames []string, filename string) bool {
    for _, f := range filenames {
        if f == filename {
            return true
        }
    }
    return false
}

// main.go
func main() {
    tmpl = ParseHtmlTemplates()
    if err := tmpl.Execute(os.Stdout, ""); err != nil {
        panic(err)
    }
}

```