Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for partials #217

Closed
2 tasks done
vcraescu opened this issue Oct 4, 2018 · 10 comments
Closed
2 tasks done

Support for partials #217

vcraescu opened this issue Oct 4, 2018 · 10 comments
Assignees
Labels

Comments

@vcraescu
Copy link

vcraescu commented Oct 4, 2018

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!


  • Implementation
  • Documentation
@AugustHell
Copy link

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.

@vcraescu
Copy link
Author

vcraescu commented Oct 4, 2018

@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.

@jeevatkm
Copy link
Member

jeevatkm commented Oct 4, 2018

@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.

@jeevatkm jeevatkm added feature lib-view View Engine labels Oct 4, 2018
@jeevatkm jeevatkm added this to the v0.12.0 Milestone milestone Oct 4, 2018
@jeevatkm jeevatkm self-assigned this Oct 23, 2018
@jeevatkm
Copy link
Member

@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:

  • func include supports a tmpl include from common directory.
  • Also it supports sub-tree within common directory too. Let's common directory has sub directory as 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" . }}

@AugustHell
Copy link

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"

@vcraescu
Copy link
Author

@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.

@jeevatkm
Copy link
Member

jeevatkm commented Oct 24, 2018

@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.

@vcraescu
Copy link
Author

vcraescu commented Oct 25, 2018

@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.

@jeevatkm
Copy link
Member

@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.

jeevatkm added a commit to go-aah/docs that referenced this issue Oct 25, 2018
@jeevatkm
Copy link
Member

Done 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants