Closed vcraescu closed 5 years ago
You can do this with template functions: https://docs.aahframework.org/v0.11/template-funcs.html#adding-your-custom-funcs-or-third-party-funcs
A simple example by only adding a way to include html files:
./app/init.go
import(
"bytes"
"html/template"
"path/filepath"
)
aah.AddTemplateFunc(template.FuncMap{
"Partials": func(filename string) template.HTML {
t := template.New(filename)
templatepath, err := filepath.Abs(filename)
if err != nil {
// error handling
return template.HTML("Error")
}
t, err = t.ParseFiles(templatepath)
if err != nil {
// error handling
return template.HTML("Error")
}
var tbuffer bytes.Buffer
t.Execute(&tbuffer, nil)
return template.HTML(tbuffer.String())
},
})
To use this, add to your template: {{ Partials "./views/users/form.html" }}
Instead of writing an anonymous function in init.go like in this simple example, you can add a component function to better organize your code. I'm using this in an extended way thru defining some kind of page components, which I place in a app/components folder. These template functions allow to add parameters of any kind (like struct), which I can add to the "partial" template thru the controller with aah.Data.
@AugustHell I know I can add a function to include partials, but this is a feature request because I believe it's an important feature for a web framework.
@vcraescu Thanks for bringing up use case, which would be beneficial to aah users.
@AugustHell Thanks for your inputs and helping aah community. I will take your inputs, generalize and add it aah view template functions in next release.
@vcraescu @AugustHell I was implementing partials template func then I thought following idea. Have a look and please let me know your thoughts.
Existing feature:
include
supports a tmpl include from common
directory. sample
. E.g. {{ include "sample/filename.html" . }}
.Currently supported syntax of include
:
Both syntax yield same results
---------------------------------
{{ include "sample/filename.html" . }}
{{ include "common/sample/filename.html" . }}
Both syntax yield same results
---------------------------------
{{ include "filename.html" . }}
{{ include "common/filename.html" . }}
So, add partials capability into func include
retaining existing syntax support and new one.
E.g.: adding new syntax instead new tmpl func
Both syntax yield same results
---------------------------------
{{ include "/views/users/form.html" . }}
{{ include "/users/form.html" . }}
I very much like this:
{{ include "/views/users/form.html" . }} if the . dot is for passing by a data struct, its perfect. Then I can use it for a hmvc like structure with components à la "/components/form/newuser.html"
@jeevatkm I don't think it's a good idea to support both absolute and relative paths because it's confusing. Only relative paths to project root should be allowed.
{{ include "relative/path/to/file.html" }}
So only
{{ include "views/users/form.html" . }}
should be valid. This allows the flexibility to include any file from any folder.
@AugustHell Yes, .
dot (second param) is for passing data to template. Also I'm thinking of making second param optional too.
@vcraescu Yeah idea is to have ability to include
template from anywhere under view/**
directory.
However I would like to mention why I thought of having root /
approach - Directory views
is the root directory for all view templates, typically it would make sense to call it as /views/**
.
For e.g:
<!-- absolute path syntax -->
{{ include "/views/users/form.html" . }}
{{ include "/users/form.html" . }}
<!-- relative path syntax -->
{{ include "users/form.html" . }}
Also order of resolving relative path has crux in it. Example-
<!-- Load from respect to parent template (currently this principle is not fully exists
because include only loads the template within directory-tree of common).
I would like to bring this capability into aah view engine -->
{{ include "users/form.html" . }}
<!-- Load from respect to view root directory. -->
{{ include "/views/users/form.html" . }}
{{ include "/users/form.html" . }}
We can advocate bring the same order of path resolve principle without beginning slash /
. Check template exists in respect to parent template if yes use it otherwise fallback to view root template. (currently I'm discussing my thoughts. I'm not sure which is feasible or not, I will have to try the implementation. I'm fine with relative path reference everywhere and view engine figures out internally)
I hope I have explained it in detail about my thoughts.
@jeevatkm Makes sense what you're saying if BC is your concern. It might be a good idea to have the imports relative to views folder and not to project dir. I have in mind some cases where this might be handy.
But
{{ include "/views/users/form.html" . }}
{{ include "/users/form.html" . }}
these 2 are a big NO-NO from my point of view. 2 different paths that does same thing. Too much "magic" which is error prone and hard to maintain in long term.
So, if you want to keep existing functionality (importing from "common" directory) then I suggest just 2 cases:
<!-- include from views dir -->
{{ include "/users/form.html" . }}
<!-- include from common dir -->
{{ include "users/form.html" . }}
Although, I would drop the include from common folder cause because it's so uncommon and I don't see any advantages having such a feature.
@vcraescu Yes, I agree. Since new feature would satisfy including a files from common directory too.
I think, I will deprecated the existing behavior of include
in v0.12.0 (if I'm able to add auto migrate for view files, then safely I can remove the existing behavior too. Let's what I can do) and introduce new include
behavior.
Done 😄
It will be good to have support for partial templates. As far as I can, at this moment, you can only include templates from "common" folder which is good but It's not enough in a large web application.
Need to be able to do something like this:
{{ partial("users/form.html") }}
Right now I'm just duplicating code because I don't want to put all the partials inside common folder since those templates only makes sense in user context and I will not use them anywhere else.
Thanks!