hoisie/mustache

Custom path of partials

tosh-iba opened this issue · 4 comments

ParseString used the current working directory for handling of partials.
Would be interesting to define custom path of partials.
Has sometimes may need to set different paths depending on various situations

Thank you very much.
Tosh.

Would specifying an absolute path work for you?

Yes.
Would be wonderful.

Thanks
Tosh.

Just pushed a change that should fix it. Can you test?

The problem remains the same.
ParseString used the current working directory for handling of partials.
Public access would suffice or a function to change template.dir or a public NewTemplate(data, baseDir)
func NewTemplate(s string, baseDir) *Template {
return &Template{string(s), "{{", "}}", 0, 1, baseDir, new(vector.Vector)}
}

It would be interesting to define other ways of searching.
For example:

import ( "path" )

type Template struct {
    ...
    search_path vector.StringVector
    ...
}

func NewTemplate(s string, baseDir) *Template {
    search_path := new(StringVector).Resize(1, 0)
    search_path.Set(0, baseDir)
    return &Template{string(s), "{{", "}}", 0, 1, search_path, new(vector.Vector)}
}

func (tmpl *Template) setTemplateBaseDirectory(dir string) {
    tmpl.search_path.Resize(1, 0)
    tmpl.search_path.Set(0, path.Clean(dir))
}

func (tmpl *Template) addAlternateTemplateBaseDirectory(dir string) {
    tmpl.searh_path.Push(path.Clean(dir))
}

func (tmpl *Template) parsePartial(name string) (*Template, os.Error) {
    If the filename is an absolute filename, starting with /, the search path is ignored.

    for _, base := range tmpl.search_path
        filename := path.Join(base, name)
        ...
        since they have the file open it could use something like: (for example)

        defer f.close()
        s, err := ioutil.ReadAll(f)
        if err != nil {
            return nil, err
        }

        dirname, _ := path.Split(filename)
        partial := NewTemplate(s, dirname)

        err = partial.parse()
        if err != nil {
            return nil, err
        }

        return partial, nil
        ...

    return nil, os.NewError(fmt.Sprintf("Could not find partial %q", name))
}

func Parse(s string) (*Template, os.Error) {
    tmpl := NewTemplate(s, "")
    ...
}

func ParseFile(filename string) (*Template, os.Error) {
    ...
    dirname, _ := path.Split(filename)
    tmpl := NewTemplate(s, dirname)
    ...
}

But not if it is too expensive in execution time...
Probably only need to add the function:
func (tmpl *Template) setBaseDirectory(dir string) {
tmpl.dir := dir
}

Other issues:
1- If you need "cwd := os.Getenv("CWD")" consider putting in the init function?

2- Need to search for the two extensions?

3- In the documentation
"If you're planning to render the same template multiple times, you do it efficiently by compiling the template first:

-tmpl,_ := mustache.Parse("hello {{c}}")
+tmpl,_ := mustache.ParseString("hello {{c}}")
var buf bytes.Buffer;"

or change the function name to Parse for consistency.

Are just some ideas.
I do not give much work, but it is the only way to learn.

I have not thought too much. I have not much time now.

Sincerely.
Tosh.

PD. Sorry for my English. Use google translator