mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 02:31:04 +01:00
add a ParseTemplate to the HTML view engine.
relative to: #1617 Wait for an answer from the issuer and if that's the expected behavior, do the same for the rest of the view engines
This commit is contained in:
parent
dac834cf11
commit
64038b09e3
|
@ -110,6 +110,7 @@
|
|||
* [Inject Engine Between Handlers](view/context-view-engine/main.go)
|
||||
* [Embedding Templates Into App Executable File](view/embedding-templates-into-app/main.go)
|
||||
* [Write to a custom `io.Writer`](view/write-to)
|
||||
* [Parse a Template manually](view/parse-template/main.go)
|
||||
* [Blocks](view/template_blocks_0)
|
||||
* [Blocks Embedded](view/template_blocks_1_embedded)
|
||||
* [Pug: `Actions`](view/template_pug_0)
|
||||
|
|
35
_examples/view/parse-template/main.go
Normal file
35
_examples/view/parse-template/main.go
Normal file
|
@ -0,0 +1,35 @@
|
|||
// Package main shows how to parse a template through custom byte slice content.
|
||||
package main
|
||||
|
||||
import "github.com/kataras/iris/v12"
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
// To not load any templates from files or embedded data,
|
||||
// pass nil or empty string on the first argument:
|
||||
// view := iris.HTML(nil, ".html")
|
||||
|
||||
view := iris.HTML("./views", ".html")
|
||||
view.ParseTemplate("program.html", []byte(`<h1>{{greet .Name}}</h1>`), iris.Map{
|
||||
"greet": func(name string) string {
|
||||
return "Hello, " + name + "!"
|
||||
},
|
||||
})
|
||||
|
||||
app.RegisterView(view)
|
||||
app.Get("/", index)
|
||||
app.Get("/layout", layout)
|
||||
|
||||
app.Listen(":8080")
|
||||
}
|
||||
|
||||
func index(ctx iris.Context) {
|
||||
ctx.View("program.html", iris.Map{
|
||||
"Name": "Gerasimos",
|
||||
})
|
||||
}
|
||||
|
||||
func layout(ctx iris.Context) {
|
||||
ctx.ViewLayout("layouts/main.html")
|
||||
index(ctx)
|
||||
}
|
11
_examples/view/parse-template/views/layouts/main.html
Normal file
11
_examples/view/parse-template/views/layouts/main.html
Normal file
|
@ -0,0 +1,11 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>My Layout</title>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<h1>[layout] Body content is below...</h1>
|
||||
<!-- Render the current template here -->
|
||||
{{ yield }}
|
||||
</body>
|
||||
</html>
|
22
view/fs.go
22
view/fs.go
|
@ -49,6 +49,10 @@ func assetNames(fs http.FileSystem, name string) ([]string, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if f == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
infos, err := f.Readdir(-1)
|
||||
f.Close()
|
||||
if err != nil {
|
||||
|
@ -82,9 +86,17 @@ func asset(fs http.FileSystem, name string) ([]byte, error) {
|
|||
}
|
||||
|
||||
func getFS(fsOrDir interface{}) (fs http.FileSystem) {
|
||||
if fsOrDir == nil {
|
||||
return noOpFS{}
|
||||
}
|
||||
|
||||
switch v := fsOrDir.(type) {
|
||||
case string:
|
||||
fs = httpDirWrapper{http.Dir(v)}
|
||||
if v == "" {
|
||||
fs = noOpFS{}
|
||||
} else {
|
||||
fs = httpDirWrapper{http.Dir(v)}
|
||||
}
|
||||
case http.FileSystem:
|
||||
fs = v
|
||||
default:
|
||||
|
@ -94,6 +106,10 @@ func getFS(fsOrDir interface{}) (fs http.FileSystem) {
|
|||
return
|
||||
}
|
||||
|
||||
type noOpFS struct{}
|
||||
|
||||
func (fs noOpFS) Open(name string) (http.File, error) { return nil, nil }
|
||||
|
||||
// fixes: "invalid character in file path"
|
||||
// on amber engine (it uses the virtual fs directly
|
||||
// and it uses filepath instead of the path package...).
|
||||
|
@ -101,6 +117,6 @@ type httpDirWrapper struct {
|
|||
http.Dir
|
||||
}
|
||||
|
||||
func (d httpDirWrapper) Open(name string) (http.File, error) {
|
||||
return d.Dir.Open(filepath.ToSlash(name))
|
||||
func (fs httpDirWrapper) Open(name string) (http.File, error) {
|
||||
return fs.Dir.Open(filepath.ToSlash(name))
|
||||
}
|
||||
|
|
67
view/html.go
67
view/html.go
|
@ -215,12 +215,6 @@ func (s *HTMLEngine) Funcs(funcMap template.FuncMap) *HTMLEngine {
|
|||
//
|
||||
// Returns an error if something bad happens, caller is responsible to handle that.
|
||||
func (s *HTMLEngine) Load() error {
|
||||
s.rmu.Lock()
|
||||
defer s.rmu.Unlock()
|
||||
|
||||
s.Templates = template.New(s.rootDir)
|
||||
s.Templates.Delims(s.left, s.right)
|
||||
|
||||
return walk(s.fs, s.rootDir, func(path string, info os.FileInfo, err error) error {
|
||||
if info == nil || info.IsDir() {
|
||||
return nil
|
||||
|
@ -236,30 +230,51 @@ func (s *HTMLEngine) Load() error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("%s: %w", path, err)
|
||||
}
|
||||
contents := string(buf)
|
||||
|
||||
name := strings.TrimPrefix(path, "/")
|
||||
tmpl := s.Templates.New(name)
|
||||
tmpl.Option(s.options...)
|
||||
|
||||
if s.middleware != nil {
|
||||
contents, err = s.middleware(name, buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Add our funcmaps.
|
||||
_, err = tmpl.
|
||||
Funcs(emptyFuncs).
|
||||
// Funcs(s.makeDefaultLayoutFuncs(name)).
|
||||
// Funcs(s.layoutFuncs).
|
||||
Funcs(s.funcs).
|
||||
Parse(contents)
|
||||
return err
|
||||
return s.ParseTemplate(path, buf, nil)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HTMLEngine) initRootTmpl() { // protected by the caller.
|
||||
if s.Templates == nil {
|
||||
// the root template should be the same,
|
||||
// no matter how many reloads as the
|
||||
// following unexported fields cannot be modified.
|
||||
s.Templates = template.New(s.rootDir)
|
||||
s.Templates.Delims(s.left, s.right)
|
||||
}
|
||||
}
|
||||
|
||||
// ParseTemplate adds a custom template to the root template.
|
||||
func (s *HTMLEngine) ParseTemplate(name string, contents []byte, funcMap template.FuncMap) (err error) {
|
||||
s.rmu.Lock()
|
||||
defer s.rmu.Unlock()
|
||||
|
||||
s.initRootTmpl()
|
||||
|
||||
name = strings.TrimPrefix(name, "/")
|
||||
tmpl := s.Templates.New(name)
|
||||
tmpl.Option(s.options...)
|
||||
|
||||
var text string
|
||||
|
||||
if s.middleware != nil {
|
||||
text, err = s.middleware(name, contents)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
text = string(contents)
|
||||
}
|
||||
|
||||
tmpl.Funcs(emptyFuncs).Funcs(s.funcs)
|
||||
if len(funcMap) > 0 {
|
||||
tmpl.Funcs(funcMap) // custom for this template.
|
||||
}
|
||||
_, err = tmpl.Parse(text)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *HTMLEngine) executeTemplateBuf(name string, binding interface{}) (*bytes.Buffer, error) {
|
||||
buf := new(bytes.Buffer)
|
||||
err := s.Templates.ExecuteTemplate(buf, name, binding)
|
||||
|
|
Loading…
Reference in New Issue
Block a user