mirror of
https://github.com/kataras/iris.git
synced 2026-01-02 09:47:17 +00:00
20 days of unstoppable work. Waiting fo go 1.8, I didn't finish yet, some touches remains.
Former-commit-id: ed84f99c89f43fe5e980a8e6d0ee22c186f0e1b9
This commit is contained in:
93
adaptors/view/_examples/overview/main.go
Normal file
93
adaptors/view/_examples/overview/main.go
Normal file
@@ -0,0 +1,93 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
|
||||
"gopkg.in/kataras/iris.v6"
|
||||
"gopkg.in/kataras/iris.v6/adaptors/gorillamux"
|
||||
"gopkg.in/kataras/iris.v6/adaptors/view"
|
||||
)
|
||||
|
||||
// ExampleXML just a test struct to view represents xml content-type
|
||||
type ExampleXML struct {
|
||||
XMLName xml.Name `xml:"example"`
|
||||
One string `xml:"one,attr"`
|
||||
Two string `xml:"two,attr"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
app.Adapt(iris.DevLogger())
|
||||
app.Adapt(gorillamux.New())
|
||||
|
||||
app.Get("/data", func(ctx *iris.Context) {
|
||||
ctx.Data(iris.StatusOK, []byte("Some binary data here."))
|
||||
})
|
||||
|
||||
app.Get("/text", func(ctx *iris.Context) {
|
||||
ctx.Text(iris.StatusOK, "Plain text here")
|
||||
})
|
||||
|
||||
app.Get("/json", func(ctx *iris.Context) {
|
||||
ctx.JSON(iris.StatusOK, map[string]string{"hello": "json"}) // or myjsonStruct{hello:"json}
|
||||
})
|
||||
|
||||
app.Get("/jsonp", func(ctx *iris.Context) {
|
||||
ctx.JSONP(iris.StatusOK, "callbackName", map[string]string{"hello": "jsonp"})
|
||||
})
|
||||
|
||||
app.Get("/xml", func(ctx *iris.Context) {
|
||||
ctx.XML(iris.StatusOK, ExampleXML{One: "hello", Two: "xml"}) // or iris.Map{"One":"hello"...}
|
||||
})
|
||||
|
||||
app.Get("/markdown", func(ctx *iris.Context) {
|
||||
ctx.Markdown(iris.StatusOK, "# Hello Dynamic Markdown Iris")
|
||||
})
|
||||
|
||||
app.Adapt(view.HTML("./templates", ".html"))
|
||||
app.Get("/template", func(ctx *iris.Context) {
|
||||
|
||||
ctx.MustRender(
|
||||
"hi.html", // the file name of the template relative to the './templates'
|
||||
iris.Map{"Name": "Iris"}, // the .Name inside the ./templates/hi.html
|
||||
iris.Map{"gzip": false}, // enable gzip for big files
|
||||
)
|
||||
|
||||
})
|
||||
|
||||
// ------ first customization without even the need of *Context or a Handler--------
|
||||
//
|
||||
// Custom new content-/type:
|
||||
// app.Adapt(iris.RenderPolicy(func(out io.Writer, name string, binding interface{}, options ...map[string]interface{}) (error, bool) {
|
||||
// if name == "customcontent-type" {
|
||||
//
|
||||
// // some very advanced things here:
|
||||
// out.Write([]byte(binding.(string)))
|
||||
// return nil, true
|
||||
// }
|
||||
// return nil, false
|
||||
// }))
|
||||
//
|
||||
// app.Get("/custom", func(ctx *iris.Context) {
|
||||
// ctx.RenderWithStatus(iris.StatusOK, // or MustRender
|
||||
// "customcontent-type",
|
||||
// "my custom content here!",
|
||||
// )
|
||||
// })
|
||||
//
|
||||
// ---- second -----------------------------------------------------------------------
|
||||
//
|
||||
// Override the defaults (the json,xml,jsonp,text,data and so on), an existing content-type:
|
||||
// app.Adapt(iris.RenderPolicy(func(out io.Writer, name string, binding interface{}, options ...map[string]interface{}) (error, bool) {
|
||||
// if name == "text/plain" {
|
||||
// out.Write([]byte("From the custom text/plain renderer: " + binding.(string)))
|
||||
// return nil, true
|
||||
// }
|
||||
//
|
||||
// return nil, false
|
||||
// }))
|
||||
// // the context.Text's behaviors was changed now by your custom renderer.
|
||||
//
|
||||
|
||||
app.Listen(":8080")
|
||||
}
|
||||
8
adaptors/view/_examples/overview/templates/hi.html
Normal file
8
adaptors/view/_examples/overview/templates/hi.html
Normal file
@@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Hi Iris</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hi {{.Name}} </h1>
|
||||
</body>
|
||||
</html>
|
||||
237
adaptors/view/_examples/template_binary/bindata.go
Normal file
237
adaptors/view/_examples/template_binary/bindata.go
Normal file
@@ -0,0 +1,237 @@
|
||||
// Code generated by go-bindata.
|
||||
// sources:
|
||||
// templates/hi.html
|
||||
// DO NOT EDIT!
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func bindataRead(data []byte, name string) ([]byte, error) {
|
||||
gz, err := gzip.NewReader(bytes.NewBuffer(data))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Read %q: %v", name, err)
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
_, err = io.Copy(&buf, gz)
|
||||
clErr := gz.Close()
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Read %q: %v", name, err)
|
||||
}
|
||||
if clErr != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
type asset struct {
|
||||
bytes []byte
|
||||
info os.FileInfo
|
||||
}
|
||||
|
||||
type bindataFileInfo struct {
|
||||
name string
|
||||
size int64
|
||||
mode os.FileMode
|
||||
modTime time.Time
|
||||
}
|
||||
|
||||
func (fi bindataFileInfo) Name() string {
|
||||
return fi.name
|
||||
}
|
||||
func (fi bindataFileInfo) Size() int64 {
|
||||
return fi.size
|
||||
}
|
||||
func (fi bindataFileInfo) Mode() os.FileMode {
|
||||
return fi.mode
|
||||
}
|
||||
func (fi bindataFileInfo) ModTime() time.Time {
|
||||
return fi.modTime
|
||||
}
|
||||
func (fi bindataFileInfo) IsDir() bool {
|
||||
return false
|
||||
}
|
||||
func (fi bindataFileInfo) Sys() interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
var _templatesHiHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xb2\xc9\x28\xc9\xcd\xb1\xe3\xe5\xb2\xc9\x48\x4d\x4c\x01\xd1\x25\x99\x25\x39\xa9\x76\x1e\x99\x0a\x9e\x45\x99\xc5\x0a\xd1\x21\x1e\xae\x0a\x21\x9e\x21\x3e\xae\xb1\x36\xfa\x10\x29\xa0\x1a\x7d\x98\xe2\xa4\xfc\x94\x4a\x20\xcd\x69\x93\x61\x08\xd2\x52\x5d\xad\xe7\x97\x98\x9b\x5a\x5b\x0b\x52\x03\x95\x03\x2a\x86\xd8\x00\x08\x00\x00\xff\xff\xed\x0e\xad\x42\x6a\x00\x00\x00")
|
||||
|
||||
func templatesHiHtmlBytes() ([]byte, error) {
|
||||
return bindataRead(
|
||||
_templatesHiHtml,
|
||||
"templates/hi.html",
|
||||
)
|
||||
}
|
||||
|
||||
func templatesHiHtml() (*asset, error) {
|
||||
bytes, err := templatesHiHtmlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "templates/hi.html", size: 106, mode: os.FileMode(438), modTime: time.Unix(1468907204, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
// Asset loads and returns the asset for the given name.
|
||||
// It returns an error if the asset could not be found or
|
||||
// could not be loaded.
|
||||
func Asset(name string) ([]byte, error) {
|
||||
cannonicalName := strings.Replace(name, "\\", "/", -1)
|
||||
if f, ok := _bindata[cannonicalName]; ok {
|
||||
a, err := f()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
|
||||
}
|
||||
return a.bytes, nil
|
||||
}
|
||||
return nil, fmt.Errorf("Asset %s not found", name)
|
||||
}
|
||||
|
||||
// MustAsset is like Asset but panics when Asset would return an error.
|
||||
// It simplifies safe initialization of global variables.
|
||||
func MustAsset(name string) []byte {
|
||||
a, err := Asset(name)
|
||||
if err != nil {
|
||||
panic("asset: Asset(" + name + "): " + err.Error())
|
||||
}
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
// AssetInfo loads and returns the asset info for the given name.
|
||||
// It returns an error if the asset could not be found or
|
||||
// could not be loaded.
|
||||
func AssetInfo(name string) (os.FileInfo, error) {
|
||||
cannonicalName := strings.Replace(name, "\\", "/", -1)
|
||||
if f, ok := _bindata[cannonicalName]; ok {
|
||||
a, err := f()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
|
||||
}
|
||||
return a.info, nil
|
||||
}
|
||||
return nil, fmt.Errorf("AssetInfo %s not found", name)
|
||||
}
|
||||
|
||||
// AssetNames returns the names of the assets.
|
||||
func AssetNames() []string {
|
||||
names := make([]string, 0, len(_bindata))
|
||||
for name := range _bindata {
|
||||
names = append(names, name)
|
||||
}
|
||||
return names
|
||||
}
|
||||
|
||||
// _bindata is a table, holding each asset generator, mapped to its name.
|
||||
var _bindata = map[string]func() (*asset, error){
|
||||
"templates/hi.html": templatesHiHtml,
|
||||
}
|
||||
|
||||
// AssetDir returns the file names below a certain
|
||||
// directory embedded in the file by go-bindata.
|
||||
// For example if you run go-bindata on data/... and data contains the
|
||||
// following hierarchy:
|
||||
// data/
|
||||
// foo.txt
|
||||
// img/
|
||||
// a.png
|
||||
// b.png
|
||||
// then AssetDir("data") would return []string{"foo.txt", "img"}
|
||||
// AssetDir("data/img") would return []string{"a.png", "b.png"}
|
||||
// AssetDir("foo.txt") and AssetDir("notexist") would return an error
|
||||
// AssetDir("") will return []string{"data"}.
|
||||
func AssetDir(name string) ([]string, error) {
|
||||
node := _bintree
|
||||
if len(name) != 0 {
|
||||
cannonicalName := strings.Replace(name, "\\", "/", -1)
|
||||
pathList := strings.Split(cannonicalName, "/")
|
||||
for _, p := range pathList {
|
||||
node = node.Children[p]
|
||||
if node == nil {
|
||||
return nil, fmt.Errorf("Asset %s not found", name)
|
||||
}
|
||||
}
|
||||
}
|
||||
if node.Func != nil {
|
||||
return nil, fmt.Errorf("Asset %s not found", name)
|
||||
}
|
||||
rv := make([]string, 0, len(node.Children))
|
||||
for childName := range node.Children {
|
||||
rv = append(rv, childName)
|
||||
}
|
||||
return rv, nil
|
||||
}
|
||||
|
||||
type bintree struct {
|
||||
Func func() (*asset, error)
|
||||
Children map[string]*bintree
|
||||
}
|
||||
|
||||
var _bintree = &bintree{nil, map[string]*bintree{
|
||||
"templates": {nil, map[string]*bintree{
|
||||
"hi.html": {templatesHiHtml, map[string]*bintree{}},
|
||||
}},
|
||||
}}
|
||||
|
||||
// RestoreAsset restores an asset under the given directory
|
||||
func RestoreAsset(dir, name string) error {
|
||||
data, err := Asset(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
info, err := AssetInfo(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RestoreAssets restores an asset under the given directory recursively
|
||||
func RestoreAssets(dir, name string) error {
|
||||
children, err := AssetDir(name)
|
||||
// File
|
||||
if err != nil {
|
||||
return RestoreAsset(dir, name)
|
||||
}
|
||||
// Dir
|
||||
for _, child := range children {
|
||||
err = RestoreAssets(dir, filepath.Join(name, child))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func _filePath(dir, name string) string {
|
||||
cannonicalName := strings.Replace(name, "\\", "/", -1)
|
||||
return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
|
||||
}
|
||||
24
adaptors/view/_examples/template_binary/main.go
Normal file
24
adaptors/view/_examples/template_binary/main.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"gopkg.in/kataras/iris.v6"
|
||||
"gopkg.in/kataras/iris.v6/adaptors/httprouter"
|
||||
"gopkg.in/kataras/iris.v6/adaptors/view"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
app.Adapt(iris.DevLogger())
|
||||
app.Adapt(httprouter.New())
|
||||
|
||||
//$ go-bindata ./templates/...
|
||||
// templates are not used, you can delete the folder and run the example
|
||||
app.Adapt(view.HTML("./templates", ".html").Binary(Asset, AssetNames))
|
||||
|
||||
app.Get("/hi", hi)
|
||||
app.Listen(":8080")
|
||||
}
|
||||
|
||||
func hi(ctx *iris.Context) {
|
||||
ctx.MustRender("hi.html", struct{ Name string }{Name: "iris"})
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Hi Iris [THE TITLE]</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hi {{.Name}}
|
||||
</body>
|
||||
</html>
|
||||
23
adaptors/view/_examples/template_html_0/main.go
Normal file
23
adaptors/view/_examples/template_html_0/main.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"gopkg.in/kataras/iris.v6"
|
||||
"gopkg.in/kataras/iris.v6/adaptors/httprouter"
|
||||
"gopkg.in/kataras/iris.v6/adaptors/view"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := iris.New(iris.Configuration{Gzip: false, Charset: "UTF-8"}) // defaults to these
|
||||
|
||||
app.Adapt(iris.DevLogger())
|
||||
app.Adapt(httprouter.New())
|
||||
|
||||
app.Adapt(view.HTML("./templates", ".html"))
|
||||
|
||||
app.Get("/hi", hi)
|
||||
app.Listen(":8080")
|
||||
}
|
||||
|
||||
func hi(ctx *iris.Context) {
|
||||
ctx.MustRender("hi.html", struct{ Name string }{Name: "iris"})
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Hi Iris</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hi {{.Name}} </h1>
|
||||
</body>
|
||||
</html>
|
||||
32
adaptors/view/_examples/template_html_1/main.go
Normal file
32
adaptors/view/_examples/template_html_1/main.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"gopkg.in/kataras/iris.v6"
|
||||
"gopkg.in/kataras/iris.v6/adaptors/httprouter"
|
||||
"gopkg.in/kataras/iris.v6/adaptors/view"
|
||||
)
|
||||
|
||||
type mypage struct {
|
||||
Title string
|
||||
Message string
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
app.Adapt(iris.DevLogger())
|
||||
app.Adapt(httprouter.New())
|
||||
|
||||
tmpl := view.HTML("./templates", ".html")
|
||||
tmpl.Layout("layout.html")
|
||||
|
||||
app.Adapt(tmpl)
|
||||
|
||||
app.Get("/", func(ctx *iris.Context) {
|
||||
ctx.Render("mypage.html", mypage{"My Page title", "Hello world!"}, iris.Map{"gzip": true})
|
||||
// Note that: you can pass "layout" : "otherLayout.html" to bypass the config's Layout property
|
||||
// or iris.NoLayout to disable layout on this render action.
|
||||
// third is an optional parameter
|
||||
})
|
||||
|
||||
app.Listen(":8080")
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>My Layout</title>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<h1>Body is:</h1>
|
||||
<!-- Render the current template here -->
|
||||
{{ yield }}
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,4 @@
|
||||
<h1>
|
||||
Title: {{.Title}}
|
||||
</h1>
|
||||
<h3>Message: {{.Message}} </h3>
|
||||
3
adaptors/view/_examples/template_html_2/README.md
Normal file
3
adaptors/view/_examples/template_html_2/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## Info
|
||||
|
||||
This folder examines the {{render "dir/templatefilename"}} functionality to manually render any template inside any template
|
||||
49
adaptors/view/_examples/template_html_2/main.go
Normal file
49
adaptors/view/_examples/template_html_2/main.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"gopkg.in/kataras/iris.v6"
|
||||
"gopkg.in/kataras/iris.v6/adaptors/httprouter"
|
||||
"gopkg.in/kataras/iris.v6/adaptors/view"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
app.Adapt(iris.DevLogger())
|
||||
app.Adapt(httprouter.New())
|
||||
|
||||
tmpl := view.HTML("./templates", ".html")
|
||||
tmpl.Layout("layouts/layout.html")
|
||||
tmpl.Funcs(map[string]interface{}{
|
||||
"greet": func(s string) string {
|
||||
return "Greetings " + s + "!"
|
||||
},
|
||||
})
|
||||
|
||||
app.Adapt(tmpl)
|
||||
|
||||
app.Get("/", func(ctx *iris.Context) {
|
||||
if err := ctx.Render("page1.html", nil); err != nil {
|
||||
println(err.Error())
|
||||
}
|
||||
})
|
||||
|
||||
// remove the layout for a specific route
|
||||
app.Get("/nolayout", func(ctx *iris.Context) {
|
||||
if err := ctx.Render("page1.html", nil, iris.RenderOptions{"layout": iris.NoLayout}); err != nil {
|
||||
println(err.Error())
|
||||
}
|
||||
})
|
||||
|
||||
// set a layout for a party, .Layout should be BEFORE any Get or other Handle party's method
|
||||
my := app.Party("/my").Layout("layouts/mylayout.html")
|
||||
{
|
||||
my.Get("/", func(ctx *iris.Context) {
|
||||
ctx.MustRender("page1.html", nil)
|
||||
})
|
||||
my.Get("/other", func(ctx *iris.Context) {
|
||||
ctx.MustRender("page1.html", nil)
|
||||
})
|
||||
}
|
||||
|
||||
app.Listen(":8080")
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Layout</title>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<h1>This is the global layout</h1>
|
||||
<br />
|
||||
<!-- Render the current template here -->
|
||||
{{ yield }}
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,12 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>my Layout</title>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<h1>This is the layout for the /my/ and /my/other routes only</h1>
|
||||
<br />
|
||||
<!-- Render the current template here -->
|
||||
{{ yield }}
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,7 @@
|
||||
<div style="background-color: black; color: blue">
|
||||
|
||||
<h1>Page 1 {{ greet "iris developer"}}</h1>
|
||||
|
||||
{{ render "partials/page1_partial1.html"}}
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
<div style="background-color: white; color: red">
|
||||
<h1>Page 1's Partial 1</h1>
|
||||
</div>
|
||||
53
adaptors/view/_examples/template_html_3/main.go
Normal file
53
adaptors/view/_examples/template_html_3/main.go
Normal file
@@ -0,0 +1,53 @@
|
||||
// Package main an example on how to naming your routes & use the custom 'url' HTML Template Engine, same for other template engines.
|
||||
package main
|
||||
|
||||
import (
|
||||
"gopkg.in/kataras/iris.v6"
|
||||
"gopkg.in/kataras/iris.v6/adaptors/gorillamux"
|
||||
"gopkg.in/kataras/iris.v6/adaptors/view"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
app.Adapt(iris.DevLogger())
|
||||
app.Adapt(gorillamux.New())
|
||||
|
||||
app.Adapt(view.HTML("./templates", ".html"))
|
||||
|
||||
app.Get("/mypath", emptyHandler).ChangeName("my-page1")
|
||||
app.Get("/mypath2/{param1}/{param2}", emptyHandler).ChangeName("my-page2")
|
||||
app.Get("/mypath3/{param1}/statichere/{param2}", emptyHandler).ChangeName("my-page3")
|
||||
app.Get("/mypath4/{param1}/statichere/{param2}/{otherparam}/{something:.*}", emptyHandler).ChangeName("my-page4")
|
||||
|
||||
// same with Handle/Func
|
||||
app.HandleFunc("GET", "/mypath5/{param1}/statichere/{param2}/{otherparam}/anything/{something:.*}", emptyHandler).ChangeName("my-page5")
|
||||
|
||||
app.Get("/mypath6/{param1}/{param2}/staticParam/{param3AfterStatic}", emptyHandler).ChangeName("my-page6")
|
||||
|
||||
app.Get("/", func(ctx *iris.Context) {
|
||||
// for /mypath6...
|
||||
paramsAsArray := []string{"param1", "theParam1",
|
||||
"param2", "theParam2",
|
||||
"param3AfterStatic", "theParam3"}
|
||||
|
||||
if err := ctx.Render("page.html", iris.Map{"ParamsAsArray": paramsAsArray}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
})
|
||||
|
||||
app.Get("/redirect/{namedRoute}", func(ctx *iris.Context) {
|
||||
routeName := ctx.Param("namedRoute")
|
||||
|
||||
println("The full uri of " + routeName + "is: " + app.URL(routeName))
|
||||
// if routeName == "my-page1"
|
||||
// prints: The full uri of my-page1 is: http://127.0.0.1:8080/mypath
|
||||
ctx.RedirectTo(routeName)
|
||||
// http://127.0.0.1:8080/redirect/my-page1 will redirect to -> http://127.0.0.1:8080/mypath
|
||||
})
|
||||
|
||||
app.Listen("localhost:8080")
|
||||
}
|
||||
|
||||
func emptyHandler(ctx *iris.Context) {
|
||||
ctx.Writef("Hello from %s.", ctx.Path())
|
||||
}
|
||||
27
adaptors/view/_examples/template_html_3/templates/page.html
Normal file
27
adaptors/view/_examples/template_html_3/templates/page.html
Normal file
@@ -0,0 +1,27 @@
|
||||
<a href="{{url "my-page1"}}">http://127.0.0.1:8080/mypath</a>
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<a href="{{url "my-page2" "param1" "theParam1" "param2" "theParam2"}}">http://localhost:8080/mypath2/:param1/:param2</a>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<a href="{{url "my-page3" "param1" "theParam1" "param2" "theParam2AfterStatic"}}">
|
||||
http://localhost:8080/mypath3/:param1/statichere/:param2</a>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<a href="{{url "my-page4" "param1" "theParam1" "param2" "theparam2AfterStatic" "otherparam" "otherParam" "something" "matchAnything"}}">http://localhost/mypath4/:param1/statichere/:param2/:otherparam/*something</a>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<a href="{{url "my-page5" "param1" "theParam1" "param2" "theParam2AfterStatic" "otherparam" "otherParam" "something" "matchAnythingAfterStatic"}}">
|
||||
http://localhost:8080/mypath5/:param1/statichere/:param2/:otherparam/anything/*anything</a>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<a href={{url "my-page6" .ParamsAsArray }}>http://localhost:8080/mypath6/{param1}/{param2}/staticParam/{param3AfterStatic}</a>
|
||||
32
adaptors/view/_examples/template_html_4/hosts
Normal file
32
adaptors/view/_examples/template_html_4/hosts
Normal file
@@ -0,0 +1,32 @@
|
||||
# Copyright (c) 1993-2009 Microsoft Corp.
|
||||
#
|
||||
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
|
||||
#
|
||||
# This file contains the mappings of IP addresses to host names. Each
|
||||
# entry should be kept on an individual line. The IP address should
|
||||
# be placed in the first column followed by the corresponding host name.
|
||||
# The IP address and the host name should be separated by at least one
|
||||
# space.
|
||||
#
|
||||
# Additionally, comments (such as these) may be inserted on individual
|
||||
# lines or following the machine name denoted by a '#' symbol.
|
||||
#
|
||||
# For example:
|
||||
#
|
||||
# 102.54.94.97 rhino.acme.com # source server
|
||||
# 38.25.63.10 x.acme.com # x client host
|
||||
|
||||
# localhost name resolution is handled within DNS itself.
|
||||
127.0.0.1 localhost
|
||||
::1 localhost
|
||||
#-IRIS-For development machine, you have to configure your dns also for online, search google how to do it if you don't know
|
||||
|
||||
127.0.0.1 username1.127.0.0.1
|
||||
127.0.0.1 username2.127.0.0.1
|
||||
127.0.0.1 username3.127.0.0.1
|
||||
127.0.0.1 username4.127.0.0.1
|
||||
127.0.0.1 username5.127.0.0.1
|
||||
# note that you can always use custom subdomains
|
||||
#-END IRIS-
|
||||
|
||||
# Windows: Drive:/Windows/system32/drivers/etc/hosts, on Linux: /etc/hosts
|
||||
53
adaptors/view/_examples/template_html_4/main.go
Normal file
53
adaptors/view/_examples/template_html_4/main.go
Normal file
@@ -0,0 +1,53 @@
|
||||
// Package main an example on how to naming your routes & use the custom 'url' HTML Template Engine, same for other template engines.
|
||||
package main
|
||||
|
||||
import (
|
||||
"gopkg.in/kataras/iris.v6"
|
||||
"gopkg.in/kataras/iris.v6/adaptors/gorillamux"
|
||||
"gopkg.in/kataras/iris.v6/adaptors/view"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
app.Adapt(iris.DevLogger())
|
||||
app.Adapt(gorillamux.New())
|
||||
|
||||
app.Adapt(view.HTML("./templates", ".html"))
|
||||
|
||||
app.Get("/mypath", emptyHandler).ChangeName("my-page1")
|
||||
app.Get("/mypath2/{param1}/{param2}", emptyHandler).ChangeName("my-page2")
|
||||
app.Get("/mypath3/{param1}/statichere/{param2}", emptyHandler).ChangeName("my-page3")
|
||||
app.Get("/mypath4/{param1}/statichere/{param2}/{otherparam}/{something:.*}", emptyHandler).ChangeName("my-page4")
|
||||
|
||||
// same with Handle/Func
|
||||
app.HandleFunc("GET", "/mypath5/{param1}/statichere/{param2}/{otherparam}/anything/{something:.*}", emptyHandler).ChangeName("my-page5")
|
||||
|
||||
app.Get("/mypath6/{param1}/{param2}/staticParam/{param3AfterStatic}", emptyHandler).ChangeName("my-page6")
|
||||
|
||||
app.Get("/", func(ctx *iris.Context) {
|
||||
// for /mypath6...
|
||||
paramsAsArray := []string{"param1", "theParam1",
|
||||
"param2", "theParam2",
|
||||
"param3AfterStatic", "theParam3"}
|
||||
|
||||
if err := ctx.Render("page.html", iris.Map{"ParamsAsArray": paramsAsArray}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
})
|
||||
|
||||
app.Get("/redirect/{namedRoute}", func(ctx *iris.Context) {
|
||||
routeName := ctx.Param("namedRoute")
|
||||
|
||||
println("The full uri of " + routeName + "is: " + app.URL(routeName))
|
||||
// if routeName == "my-page1"
|
||||
// prints: The full uri of my-page1 is: http://127.0.0.1:8080/mypath
|
||||
ctx.RedirectTo(routeName)
|
||||
// http://127.0.0.1:8080/redirect/my-page1 will redirect to -> http://127.0.0.1:8080/mypath
|
||||
})
|
||||
|
||||
app.Listen("localhost:8080")
|
||||
}
|
||||
|
||||
func emptyHandler(ctx *iris.Context) {
|
||||
ctx.Writef("Hello from %s.", ctx.Path())
|
||||
}
|
||||
16
adaptors/view/_examples/template_html_4/templates/page.html
Normal file
16
adaptors/view/_examples/template_html_4/templates/page.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!-- the only difference between normal named routes and dynamic subdomains named routes is that the first argument of url
|
||||
is the subdomain part instead of named parameter-->
|
||||
|
||||
<a href="{{url "dynamic-subdomain1" "username1"}}">username1.127.0.0.1:8080/mypath</a>
|
||||
<br />
|
||||
<br />
|
||||
<a href="{{url "dynamic-subdomain2" "username2" "theParam1" "theParam2"}}">username2.127.0.0.1:8080/mypath2/:param1/:param2</a>
|
||||
<br />
|
||||
<br />
|
||||
<a href="{{url "dynamic-subdomain3" "username3" "theParam1" "theParam2AfterStatic"}}">username3.127.0.0.1:8080/mypath3/:param1/statichere/:param2</a>
|
||||
<br />
|
||||
<br />
|
||||
<a href="{{url "dynamic-subdomain4" "username4" "theParam1" "theparam2AfterStatic" "otherParam" "matchAnything"}}">username4.127.0.0.1:8080/mypath4/:param1/statichere/:param2/:otherparam/*something</a>
|
||||
<br />
|
||||
<br />
|
||||
<a href="{{url "dynamic-subdomain5" .ParamsAsArray }}" >username5.127.0.0.1:8080/mypath6/:param1/:param2/staticParam/:param3AfterStatic</a>
|
||||
136
adaptors/view/adaptor.go
Normal file
136
adaptors/view/adaptor.go
Normal file
@@ -0,0 +1,136 @@
|
||||
package view
|
||||
|
||||
import (
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/kataras/go-template"
|
||||
"gopkg.in/kataras/iris.v6"
|
||||
)
|
||||
|
||||
// Adaptor contains the common actions
|
||||
// that all template engines share.
|
||||
//
|
||||
// We need to export that as it is without an interface
|
||||
// because it may be used as a wrapper for a template engine
|
||||
// that is not exists yet but community can create.
|
||||
type Adaptor struct {
|
||||
dir string
|
||||
extension string
|
||||
// for a .go template file lives inside the executable
|
||||
assetFn func(name string) ([]byte, error)
|
||||
namesFn func() []string
|
||||
|
||||
reload bool
|
||||
|
||||
engine template.Engine // used only on Adapt, we could make
|
||||
//it as adaptEngine and pass a second parameter there but this would break the pattern.
|
||||
}
|
||||
|
||||
// NewAdaptor returns a new general template engine policy adaptor.
|
||||
func NewAdaptor(directory string, extension string, e template.Engine) *Adaptor {
|
||||
return &Adaptor{
|
||||
dir: directory,
|
||||
extension: extension,
|
||||
engine: e,
|
||||
}
|
||||
}
|
||||
|
||||
// Binary optionally, use it when template files are distributed
|
||||
// inside the app executable (.go generated files).
|
||||
func (h *Adaptor) Binary(assetFn func(name string) ([]byte, error), namesFn func() []string) *Adaptor {
|
||||
h.assetFn = assetFn
|
||||
h.namesFn = namesFn
|
||||
return h
|
||||
}
|
||||
|
||||
// Reload if setted to true the templates are reloading on each call,
|
||||
// use it when you're in development and you're boring of restarting
|
||||
// the whole app when you edit a template file
|
||||
func (h *Adaptor) Reload(developmentMode bool) *Adaptor {
|
||||
h.reload = developmentMode
|
||||
return h
|
||||
}
|
||||
|
||||
// Adapt adapts a template engine to the main Iris' policies.
|
||||
// this specific Adapt is a multi-policies adaptors
|
||||
// we use that instead of just return New() iris.RenderPolicy
|
||||
// for two reasons:
|
||||
// - the user may need to edit the adaptor's fields
|
||||
// like Directory, Binary
|
||||
// - we need to adapt an event policy to add the engine to the external mux
|
||||
// and load it.
|
||||
func (h *Adaptor) Adapt(frame *iris.Policies) {
|
||||
mux := template.DefaultMux
|
||||
// on the build state in order to have the shared funcs also
|
||||
evt := iris.EventPolicy{
|
||||
Build: func(s *iris.Framework) {
|
||||
// mux has default to ./templates and .html ext
|
||||
// no need for any checks here.
|
||||
// the RenderPolicy will give a "no templates found on 'directory'"
|
||||
// if user tries to use the context.Render without having the template files
|
||||
// no need to panic here because we will use the html as the default template engine
|
||||
// even if the user doesn't asks for
|
||||
// or no? we had the defaults before... maybe better to give the user
|
||||
// the oportunity to learn about the template's configuration
|
||||
// (now 6.1.4 ) they are defaulted and users may don't know how and if they can change the configuration
|
||||
// even if the book and examples covers these things, many times they're asking me on chat.............
|
||||
// so no defaults? ok no defaults. This file then will be saved to /adaptors as with other template engines.
|
||||
// simple.
|
||||
mux.AddEngine(h.engine).
|
||||
Directory(h.dir, h.extension).
|
||||
Binary(h.assetFn, h.namesFn)
|
||||
|
||||
mux.Reload = h.reload
|
||||
|
||||
// notes for me: per-template engine funcs are setted by each template engine adaptor itself,
|
||||
// here we will set the template funcs policy'.
|
||||
// as I explain on the TemplateFuncsPolicy it exists in order to allow community to create plugins
|
||||
// even by adding custom template funcs to their behaviors.
|
||||
|
||||
// We know that iris.TemplateFuncsPolicy is useless without this specific
|
||||
// adaptor. We also know that it is not a good idea to have two
|
||||
// policies with the same function or we can? wait. No we can't.
|
||||
// We can't because:
|
||||
// - the RenderPolicy should accept any type of render process, not only tempaltes.
|
||||
// - I didn't design iris/policy.go to keep logic about implementation, this would make that very limited
|
||||
// and I don't want to break that just for the templates.
|
||||
// - We want community to be able to create packages which can adapt template functions but
|
||||
// not to worry about the rest of the template engine adaptor policy.
|
||||
// And even don't worry if the user has registered or use a template engine at all.
|
||||
// So we should keep separate the TemplateFuncsPolicy(just map[string]interface{})
|
||||
// from the rest of the implementation.
|
||||
//
|
||||
// So when the community wants to create a template adaptor has two options:
|
||||
// - Use the RenderPolicy which is just a func
|
||||
// - Use the kataras/iris/adaptors/view.Adaptor adaptor wrapper for RenderPolicy with a compination of kataras/go-template/.Engine
|
||||
//
|
||||
//
|
||||
// So here is the only place we adapt the iris.TemplateFuncsPolicy to the tempaltes, if and only if templates are used,
|
||||
// otherwise they are just ignored without any creepy things.
|
||||
//
|
||||
// The TemplateFuncsPolicy will work in compination with the specific template adaptor's functions(see html.go and the rest)
|
||||
|
||||
if len(frame.TemplateFuncsPolicy) > 0 {
|
||||
mux.SetFuncMapToEngine(frame.TemplateFuncsPolicy, h.engine)
|
||||
}
|
||||
|
||||
if err := mux.Load(); err != nil {
|
||||
s.Log(iris.ProdMode, err.Error())
|
||||
}
|
||||
},
|
||||
}
|
||||
// adapt the build event to the main policies
|
||||
evt.Adapt(frame)
|
||||
|
||||
r := iris.RenderPolicy(func(out io.Writer, file string, tmplContext interface{}, options ...map[string]interface{}) (error, bool) {
|
||||
// template mux covers that but maybe we have more than one RenderPolicy
|
||||
// and each of them carries a different mux on the new design.
|
||||
if strings.Contains(file, h.extension) {
|
||||
return mux.ExecuteWriter(out, file, tmplContext, options...), true
|
||||
}
|
||||
return nil, false
|
||||
})
|
||||
|
||||
r.Adapt(frame)
|
||||
}
|
||||
48
adaptors/view/amber.go
Normal file
48
adaptors/view/amber.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package view
|
||||
|
||||
import (
|
||||
"github.com/kataras/go-template/amber"
|
||||
)
|
||||
|
||||
// AmberAdaptor is the adaptor for the Amber, simple, engine.
|
||||
// Read more about the Amber Go Template at:
|
||||
// https://github.com/eknkc/amber
|
||||
// and https://github.com/kataras/go-template/tree/master/amber
|
||||
type AmberAdaptor struct {
|
||||
*Adaptor
|
||||
engine *amber.Engine
|
||||
}
|
||||
|
||||
// Amber returns a new kataras/go-template/amber template engine
|
||||
// with the same features as all iris' view engines have:
|
||||
// Binary assets load (templates inside your executable with .go extension)
|
||||
// Layout, Funcs, {{ url }} {{ urlpath}} for reverse routing and much more.
|
||||
//
|
||||
// Read more: https://github.com/eknkc/amber
|
||||
func Amber(directory string, extension string) *AmberAdaptor {
|
||||
e := amber.New()
|
||||
return &AmberAdaptor{
|
||||
Adaptor: NewAdaptor(directory, extension, e),
|
||||
engine: e,
|
||||
}
|
||||
}
|
||||
|
||||
// Funcs adds the elements of the argument map to the template's function map.
|
||||
// It is legal to overwrite elements of the default actions:
|
||||
// - url func(routeName string, args ...string) string
|
||||
// - urlpath func(routeName string, args ...string) string
|
||||
// - render func(fullPartialName string) (template.HTML, error).
|
||||
func (a *AmberAdaptor) Funcs(funcMap map[string]interface{}) *AmberAdaptor {
|
||||
if len(funcMap) == 0 {
|
||||
return a
|
||||
}
|
||||
|
||||
// configuration maps are never nil, because
|
||||
// they are initialized at each of the engine's New func
|
||||
// so we're just passing them inside it.
|
||||
for k, v := range funcMap {
|
||||
a.engine.Config.Funcs[k] = v
|
||||
}
|
||||
|
||||
return a
|
||||
}
|
||||
93
adaptors/view/django.go
Normal file
93
adaptors/view/django.go
Normal file
@@ -0,0 +1,93 @@
|
||||
package view
|
||||
|
||||
import (
|
||||
"github.com/kataras/go-template/django"
|
||||
)
|
||||
|
||||
type (
|
||||
// Value conversion for django.Value
|
||||
Value django.Value
|
||||
// Error conversion for django.Error
|
||||
Error django.Error
|
||||
// FilterFunction conversion for django.FilterFunction
|
||||
FilterFunction func(in *Value, param *Value) (out *Value, err *Error)
|
||||
)
|
||||
|
||||
// this exists because of moving the pongo2 to the vendors without conflictitions if users
|
||||
// wants to register pongo2 filters they can use this django.FilterFunc to do so.
|
||||
func convertFilters(djangoFilters map[string]FilterFunction) map[string]django.FilterFunction {
|
||||
filters := make(map[string]django.FilterFunction, len(djangoFilters))
|
||||
for k, v := range djangoFilters {
|
||||
func(filterName string, filterFunc FilterFunction) {
|
||||
fn := django.FilterFunction(func(in *django.Value, param *django.Value) (*django.Value, *django.Error) {
|
||||
theOut, theErr := filterFunc((*Value)(in), (*Value)(param))
|
||||
return (*django.Value)(theOut), (*django.Error)(theErr)
|
||||
})
|
||||
filters[filterName] = fn
|
||||
}(k, v)
|
||||
}
|
||||
return filters
|
||||
}
|
||||
|
||||
// DjangoAdaptor is the adaptor for the Django engine.
|
||||
// Read more about the Django Go Template at:
|
||||
// https://github.com/flosch/pongo2
|
||||
// and https://github.com/kataras/go-template/tree/master/django
|
||||
type DjangoAdaptor struct {
|
||||
*Adaptor
|
||||
engine *django.Engine
|
||||
filters map[string]FilterFunction
|
||||
}
|
||||
|
||||
// Django returns a new kataras/go-template/django template engine
|
||||
// with the same features as all iris' view engines have:
|
||||
// Binary assets load (templates inside your executable with .go extension)
|
||||
// Layout, Funcs, {{ url }} {{ urlpath}} for reverse routing and much more.
|
||||
//
|
||||
// Read more: https://github.com/flosch/pongo2
|
||||
func Django(directory string, extension string) *DjangoAdaptor {
|
||||
e := django.New()
|
||||
return &DjangoAdaptor{
|
||||
Adaptor: NewAdaptor(directory, extension, e),
|
||||
engine: e,
|
||||
filters: make(map[string]FilterFunction, 0),
|
||||
}
|
||||
}
|
||||
|
||||
// Filters for pongo2, map[name of the filter] the filter function .
|
||||
//
|
||||
// Note, these Filters function overrides ALL the previous filters
|
||||
// It SETS a new filter map based on the given 'filtersMap' parameter.
|
||||
func (d *DjangoAdaptor) Filters(filtersMap map[string]FilterFunction) *DjangoAdaptor {
|
||||
|
||||
if len(filtersMap) == 0 {
|
||||
return d
|
||||
}
|
||||
// configuration maps are never nil, because
|
||||
// they are initialized at each of the engine's New func
|
||||
// so we're just passing them inside it.
|
||||
|
||||
filters := convertFilters(filtersMap)
|
||||
d.engine.Config.Filters = filters
|
||||
return d
|
||||
}
|
||||
|
||||
// Globals share context fields between templates. https://github.com/flosch/pongo2/issues/35
|
||||
func (d *DjangoAdaptor) Globals(globalsMap map[string]interface{}) *DjangoAdaptor {
|
||||
if len(globalsMap) == 0 {
|
||||
return d
|
||||
}
|
||||
|
||||
for k, v := range globalsMap {
|
||||
d.engine.Config.Globals[k] = v
|
||||
}
|
||||
|
||||
return d
|
||||
}
|
||||
|
||||
// DebugTemplates enables template debugging.
|
||||
// The verbose error messages will appear in browser instead of quiet passes with error code.
|
||||
func (d *DjangoAdaptor) DebugTemplates(debug bool) *DjangoAdaptor {
|
||||
d.engine.Config.DebugTemplates = debug
|
||||
return d
|
||||
}
|
||||
62
adaptors/view/handlebars.go
Normal file
62
adaptors/view/handlebars.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package view
|
||||
|
||||
import (
|
||||
"github.com/kataras/go-template/handlebars"
|
||||
)
|
||||
|
||||
// HandlebarsAdaptor is the adaptor for the Handlebars engine.
|
||||
// Read more about the Handlebars Go Template at:
|
||||
// https://github.com/aymerick/raymond
|
||||
// and https://github.com/kataras/go-template/tree/master/handlebars
|
||||
type HandlebarsAdaptor struct {
|
||||
*Adaptor
|
||||
engine *handlebars.Engine
|
||||
}
|
||||
|
||||
// Handlebars returns a new kataras/go-template/handlebars template engine
|
||||
// with the same features as all iris' view engines have:
|
||||
// Binary assets load (templates inside your executable with .go extension)
|
||||
// Layout, Funcs, {{ url }} {{ urlpath}} for reverse routing and much more.
|
||||
//
|
||||
// Read more: https://github.com/aymerick/raymond
|
||||
func Handlebars(directory string, extension string) *HandlebarsAdaptor {
|
||||
e := handlebars.New()
|
||||
return &HandlebarsAdaptor{
|
||||
Adaptor: NewAdaptor(directory, extension, e),
|
||||
engine: e,
|
||||
}
|
||||
}
|
||||
|
||||
// Layout sets the layout template file which inside should use
|
||||
// the {{ yield }} func to yield the main template file
|
||||
// and optionally {{partial/partial_r/render}} to render other template files like headers and footers
|
||||
//
|
||||
// The 'tmplLayoutFile' is a relative path of the templates base directory,
|
||||
// for the template file whith its extension.
|
||||
//
|
||||
// Example: Handlebars("./templates", ".html").Layout("layouts/mainLayout.html")
|
||||
// // mainLayout.html is inside: "./templates/layouts/".
|
||||
//
|
||||
// Note: Layout can be changed for a specific call
|
||||
// action with the option: "layout" on the Iris' context.Render function.
|
||||
func (h *HandlebarsAdaptor) Layout(tmplLayoutFile string) *HandlebarsAdaptor {
|
||||
h.engine.Config.Layout = tmplLayoutFile
|
||||
return h
|
||||
}
|
||||
|
||||
// Funcs adds the elements of the argument map to the template's function map.
|
||||
// It is legal to overwrite elements of the default actions:
|
||||
// - url func(routeName string, args ...string) string
|
||||
// - urlpath func(routeName string, args ...string) string
|
||||
// - and handlebars specific, read more: https://github.com/aymerick/raymond.
|
||||
func (h *HandlebarsAdaptor) Funcs(funcMap map[string]interface{}) *HandlebarsAdaptor {
|
||||
if funcMap == nil {
|
||||
return h
|
||||
}
|
||||
|
||||
for k, v := range funcMap {
|
||||
h.engine.Config.Helpers[k] = v
|
||||
}
|
||||
|
||||
return h
|
||||
}
|
||||
92
adaptors/view/html.go
Normal file
92
adaptors/view/html.go
Normal file
@@ -0,0 +1,92 @@
|
||||
package view
|
||||
|
||||
import (
|
||||
"github.com/kataras/go-template/html"
|
||||
)
|
||||
|
||||
// HTMLAdaptor is the html engine policy adaptor
|
||||
// used like the "html/template" standard go package
|
||||
// but with a lot of extra features by.
|
||||
//
|
||||
// This is just a wrapper of kataras/go-template/html.
|
||||
type HTMLAdaptor struct {
|
||||
*Adaptor
|
||||
engine *html.Engine
|
||||
}
|
||||
|
||||
// HTML creates and returns a new kataras/go-template/html engine.
|
||||
// The html engine used like the "html/template" standard go package
|
||||
// but with a lot of extra features.
|
||||
func HTML(directory string, extension string) *HTMLAdaptor {
|
||||
engine := html.New()
|
||||
return &HTMLAdaptor{
|
||||
Adaptor: NewAdaptor(directory, extension, engine),
|
||||
// create the underline engine with the default configuration,
|
||||
// which can be changed by this type.
|
||||
//The whole funcs should called only before Iris' build & listen state.
|
||||
engine: engine, // we need that for the configuration only.
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Delims sets the action delimiters to the specified strings, to be used in
|
||||
// subsequent calls to Parse, ParseFiles, or ParseGlob. Nested template
|
||||
// definitions will inherit the settings. An empty delimiter stands for the
|
||||
// corresponding default: {{ or }}.
|
||||
func (h *HTMLAdaptor) Delims(left string, right string) *HTMLAdaptor {
|
||||
if left != "" && right != "" {
|
||||
h.engine.Config.Left = left
|
||||
h.engine.Config.Right = right
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
// Layout sets the layout template file which inside should use
|
||||
// the {{ yield }} func to yield the main template file
|
||||
// and optionally {{partial/partial_r/render}} to render other template files like headers and footers
|
||||
//
|
||||
// The 'tmplLayoutFile' is a relative path of the templates base directory,
|
||||
// for the template file whith its extension.
|
||||
//
|
||||
// Example: HTML("./templates", ".html").Layout("layouts/mainLayout.html")
|
||||
// // mainLayout.html is inside: "./templates/layouts/".
|
||||
//
|
||||
// Note: Layout can be changed for a specific call
|
||||
// action with the option: "layout" on the Iris' context.Render function.
|
||||
func (h *HTMLAdaptor) Layout(tmplLayoutFile string) *HTMLAdaptor {
|
||||
h.engine.Config.Layout = tmplLayoutFile
|
||||
return h
|
||||
}
|
||||
|
||||
// LayoutFuncs adds the elements of the argument map to the template's layout-only function map.
|
||||
// It is legal to overwrite elements of the default layout actions:
|
||||
// - yield func() (template.HTML, error)
|
||||
// - current func() (string, error)
|
||||
// - partial func(partialName string) (template.HTML, error)
|
||||
// - partial_r func(partialName string) (template.HTML, error)
|
||||
// - render func(fullPartialName string) (template.HTML, error).
|
||||
func (h *HTMLAdaptor) LayoutFuncs(funcMap map[string]interface{}) *HTMLAdaptor {
|
||||
if funcMap != nil {
|
||||
h.engine.Config.LayoutFuncs = funcMap
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
// Funcs adds the elements of the argument map to the template's function map.
|
||||
// It is legal to overwrite elements of the default actions:
|
||||
// - url func(routeName string, args ...string) string
|
||||
// - urlpath func(routeName string, args ...string) string
|
||||
// - render func(fullPartialName string) (template.HTML, error).
|
||||
func (h *HTMLAdaptor) Funcs(funcMap map[string]interface{}) *HTMLAdaptor {
|
||||
if len(funcMap) == 0 {
|
||||
return h
|
||||
}
|
||||
// configuration maps are never nil, because
|
||||
// they are initialized at each of the engine's New func
|
||||
// so we're just passing them inside it.
|
||||
for k, v := range funcMap {
|
||||
h.engine.Config.Funcs[k] = v
|
||||
}
|
||||
|
||||
return h
|
||||
}
|
||||
21
adaptors/view/pug.go
Normal file
21
adaptors/view/pug.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package view
|
||||
|
||||
import (
|
||||
"github.com/Joker/jade"
|
||||
)
|
||||
|
||||
// Pug (or Jade) returns a new kataras/go-template/pug engine.
|
||||
// It shares the same exactly logic with the
|
||||
// HTMLAdaptor, it uses the same exactly configuration.
|
||||
// It has got some features and a lot of functions
|
||||
// which will make your life easier.
|
||||
// Read more about the Jade Go Template: https://github.com/Joker/jade
|
||||
func Pug(directory string, extension string) *HTMLAdaptor {
|
||||
h := HTML(directory, extension)
|
||||
// because I has designed the kataras/go-template
|
||||
// so powerful, we can just pass a parser middleware
|
||||
// into the standard html template engine
|
||||
// and we're ready to go.
|
||||
h.engine.Middleware = jade.Parse
|
||||
return h
|
||||
}
|
||||
Reference in New Issue
Block a user