1 Star 0 Fork 1

maxiao / goview

forked from mirrors_foolin / goview 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

goview

GoDoc Widget Travis Widget GoReportCard Widget

Goview is a lightweight, minimalist and idiomatic template library based on golang html/template for building Go web application.

Contents

Install

go get github.com/foolin/goview

Features

  • Lightweight - use golang html/template syntax.
  • Easy - easy use for your web application.
  • Fast - Support configure cache template.
  • Include syntax - Support include file.
  • Master layout - Support configure master layout file.
  • Extension - Support configure template file extension.
  • Easy - Support configure templates directory.
  • Auto reload - Support dynamic reload template(disable cache mode).
  • Multiple Engine - Support multiple templates for frontend and backend.
  • No external dependencies - plain ol' Go html/template.
  • Gorice - Support gorice for package resources.
  • Gin/Iris/Echo/Chi - Support gin framework, Iris framework, echo framework, go-chi framework.

Docs

See https://www.godoc.org/github.com/foolin/goview

Supports

Usage

Overview

Project structure:

|-- app/views/
    |--- index.html          
    |--- page.html
    |-- layouts/
        |--- footer.html
        |--- master.html
   

Use default instance:

    //write http.ResponseWriter
    //"index" -> index.html
    goview.Render(writer, http.StatusOK, "index", goview.M{})

Use new instance with config:


    gv := goview.New(goview.Config{
        Root:      "views",
        Extension: ".tpl",
        Master:    "layouts/master",
        Partials:  []string{"partials/ad"},
        Funcs: template.FuncMap{
            "sub": func(a, b int) int {
                return a - b
            },
            "copy": func() string {
                return time.Now().Format("2006")
            },
        },
        DisableCache: true,
	Delims:    Delims{Left: "{{", Right: "}}"},
    })
    
    //Set new instance
    goview.Use(gv)
    
    //write http.ResponseWriter
    goview.Render(writer, http.StatusOK, "index", goview.M{})

Use multiple instance with config:

    //============== Frontend ============== //
    gvFrontend := goview.New(goview.Config{
        Root:      "views/frontend",
        Extension: ".tpl",
        Master:    "layouts/master",
        Partials:  []string{"partials/ad"},
        Funcs: template.FuncMap{
            "sub": func(a, b int) int {
                return a - b
            },
            "copy": func() string {
                return time.Now().Format("2006")
            },
        },
        DisableCache: true,
	Delims:       Delims{Left: "{{", Right: "}}"},
    })
    
    //write http.ResponseWriter
    gvFrontend.Render(writer, http.StatusOK, "index", goview.M{})
    
    //============== Backend ============== //
    gvBackend := goview.New(goview.Config{
        Root:      "views/backend",
        Extension: ".tpl",
        Master:    "layouts/master",
        Partials:  []string{"partials/ad"},
        Funcs: template.FuncMap{
            "sub": func(a, b int) int {
                return a - b
            },
            "copy": func() string {
                return time.Now().Format("2006")
            },
        },
        DisableCache: true,
	Delims:       Delims{Left: "{{", Right: "}}"},
    })
    
    //write http.ResponseWriter
    gvBackend.Render(writer, http.StatusOK, "index", goview.M{})

Config

goview.Config{
    Root:      "views", //template root path
    Extension: ".tpl", //file extension
    Master:    "layouts/master", //master layout file
    Partials:  []string{"partials/head"}, //partial files
    Funcs: template.FuncMap{
        "sub": func(a, b int) int {
            return a - b
        },
        // more funcs
    },
    DisableCache: false, //if disable cache, auto reload template file for debug.
    Delims:       Delims{Left: "{{", Right: "}}"},
}

Include syntax

//template file
{{include "layouts/footer"}}

Render name:

Render name use index without .html extension, that will render with master layout.

  • "index" - Render with master layout.
  • "index.html" - Not render with master layout.
Notice: `.html` is default template extension, you can change with config

Render with master

//use name without extension `.html`
goview.Render(w, http.StatusOK, "index", goview.M{})

The w is instance of http.ResponseWriter

Render only file(not use master layout)

//use full name with extension `.html`
goview.Render(w, http.StatusOK, "page.html", goview.M{})

Custom template functions

We have two type of functions global functions, and temporary functions.

Global functions are set within the config.

goview.Config{
	Funcs: template.FuncMap{
		"reverse": e.Reverse,
	},
}
//template file
{{ reverse "route-name" }}

Temporary functions are set inside the handler.

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
	err := goview.Render(w, http.StatusOK, "index", goview.M{
		"reverse": e.Reverse,
	})
	if err != nil {
		fmt.Fprintf(w, "Render index error: %v!", err)
	}
})
//template file
{{ call $.reverse "route-name" }}

Examples

See _examples/ for a variety of examples.

Basic example


package main

import (
	"fmt"
	"github.com/foolin/goview"
	"net/http"
)

func main() {

	//render index use `index` without `.html` extension, that will render with master layout.
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		err := goview.Render(w, http.StatusOK, "index", goview.M{
			"title": "Index title!",
			"add": func(a int, b int) int {
				return a + b
			},
		})
		if err != nil {
			fmt.Fprintf(w, "Render index error: %v!", err)
		}

	})

	//render page use `page.tpl` with '.html' will only file template without master layout.
	http.HandleFunc("/page", func(w http.ResponseWriter, r *http.Request) {
		err := goview.Render(w, http.StatusOK, "page.html", goview.M{"title": "Page file title!!"})
		if err != nil {
			fmt.Fprintf(w, "Render page.html error: %v!", err)
		}
	})

	fmt.Println("Listening and serving HTTP on :9090")
	http.ListenAndServe(":9090", nil)

}

Project structure:

|-- app/views/
    |--- index.html          
    |--- page.html
    |-- layouts/
        |--- footer.html
        |--- master.html
    

See in "examples/basic" folder

Basic example

Gin example

go get github.com/foolin/goview/supports/ginview

package main

import (
	"github.com/foolin/goview/supports/ginview"
	"github.com/gin-gonic/gin"
	"net/http"
)

func main() {
	router := gin.Default()

	//new template engine
	router.HTMLRender = ginview.Default()

	router.GET("/", func(ctx *gin.Context) {
		//render with master
		ctx.HTML(http.StatusOK, "index", gin.H{
			"title": "Index title!",
			"add": func(a int, b int) int {
				return a + b
			},
		})
	})

	router.GET("/page", func(ctx *gin.Context) {
		//render only file, must full name with extension
		ctx.HTML(http.StatusOK, "page.html", gin.H{"title": "Page file title!!"})
	})

	router.Run(":9090")
}

Project structure:

|-- app/views/
    |--- index.html          
    |--- page.html
    |-- layouts/
        |--- footer.html
        |--- master.html
    

See in "examples/basic" folder

Gin example

Iris example

$ go get github.com/foolin/goview/supports/irisview
package main

import (
	"github.com/foolin/goview/supports/irisview"
	"github.com/kataras/iris/v12"
)

func main() {
	app := iris.New()

	// Register the goview template engine.
	app.RegisterView(irisview.Default())

	app.Get("/", func(ctx iris.Context) {
		// Render with master.
		ctx.View("index", iris.Map{
			"title": "Index title!",
			"add": func(a int, b int) int {
				return a + b
			},
		})
	})

	app.Get("/page", func(ctx iris.Context) {
		// Render only file, must full name with extension.
		ctx.View("page.html", iris.Map{"title": "Page file title!!"})
	})

	app.Listen(":9090")
}

Project structure:

|-- app/views/
    |--- index.html          
    |--- page.html
    |-- layouts/
        |--- footer.html
        |--- master.html
    

See in "examples/iris" folder

Iris example

Iris multiple example

package main

import (
	"html/template"
	"time"

	"github.com/foolin/goview"
	"github.com/foolin/goview/supports/irisview"
	"github.com/kataras/iris/v12"
)

func main() {
	app := iris.New()

	// Register a new template engine.
	app.RegisterView(irisview.New(goview.Config{
		Root:      "views/frontend",
		Extension: ".html",
		Master:    "layouts/master",
		Partials:  []string{"partials/ad"},
		Funcs: template.FuncMap{
			"copy": func() string {
				return time.Now().Format("2006")
			},
		},
		DisableCache: true,
	}))

	app.Get("/", func(ctx iris.Context) {
		ctx.View("index", iris.Map{
			"title": "Frontend title!",
		})
	})

	//=========== Backend ===========//

	// Assign a new template middleware.
	mw := irisview.NewMiddleware(goview.Config{
		Root:      "views/backend",
		Extension: ".html",
		Master:    "layouts/master",
		Partials:  []string{},
		Funcs: template.FuncMap{
			"copy": func() string {
				return time.Now().Format("2006")
			},
		},
		DisableCache: true,
	})

	backendGroup := app.Party("/admin", mw)

	backendGroup.Get("/", func(ctx iris.Context) {
		// Use the ctx.View as you used to. Zero changes to your codebase,
		// even if you use multiple templates.
		ctx.View("index", iris.Map{
			"title": "Backend title!",
		})
	})

	app.Listen(":9090")
}

Project structure:

|-- app/views/
    |-- fontend/
        |--- index.html
        |-- layouts/
            |--- footer.html
            |--- head.html
            |--- master.html
        |-- partials/
     	   |--- ad.html
    |-- backend/
        |--- index.html
        |-- layouts/
            |--- footer.html
            |--- head.html
            |--- master.html
        
See in "examples/iris-multiple" folder

Iris multiple example

Echo example

Echo <=v3 version:

go get github.com/foolin/goview/supports/echoview

Echo v4 version:

go get github.com/foolin/goview/supports/echoview-v4

package main

import (
	"github.com/foolin/goview/supports/echoview"
	"github.com/labstack/echo"
	"github.com/labstack/echo/middleware"
	"net/http"
)

func main() {

	// Echo instance
	e := echo.New()

	// Middleware
	e.Use(middleware.Logger())
	e.Use(middleware.Recover())

	//Set Renderer
	e.Renderer = echoview.Default()

	// Routes
	e.GET("/", func(c echo.Context) error {
		//render with master
		return c.Render(http.StatusOK, "index", echo.Map{
			"title": "Index title!",
			"add": func(a int, b int) int {
				return a + b
			},
		})
	})

	e.GET("/page", func(c echo.Context) error {
		//render only file, must full name with extension
		return c.Render(http.StatusOK, "page.html", echo.Map{"title": "Page file title!!"})
	})

	// Start server
	e.Logger.Fatal(e.Start(":9090"))
}

Project structure:

|-- app/views/
    |--- index.html          
    |--- page.html
    |-- layouts/
        |--- footer.html
        |--- master.html
    

See in "examples/basic" folder

Echo example Echo v4 example

Go-chi example


package main

import (
	"fmt"
	"github.com/foolin/goview"
	"github.com/go-chi/chi"
	"net/http"
)

func main() {

	r := chi.NewRouter()

	//render index use `index` without `.html` extension, that will render with master layout.
	r.Get("/", func(w http.ResponseWriter, r *http.Request) {
		err := goview.Render(w, http.StatusOK, "index", goview.M{
			"title": "Index title!",
			"add": func(a int, b int) int {
				return a + b
			},
		})
		if err != nil {
			fmt.Fprintf(w, "Render index error: %v!", err)
		}
	})

	//render page use `page.tpl` with '.html' will only file template without master layout.
	r.Get("/page", func(w http.ResponseWriter, r *http.Request) {
		err := goview.Render(w, http.StatusOK, "page.html", goview.M{"title": "Page file title!!"})
		if err != nil {
			fmt.Fprintf(w, "Render page.html error: %v!", err)
		}
	})

	fmt.Println("Listening and serving HTTP on :9090")
	http.ListenAndServe(":9090", r)

}

Project structure:

|-- app/views/
    |--- index.html          
    |--- page.html
    |-- layouts/
        |--- footer.html
        |--- master.html
    

See in "examples/basic" folder

Chi example

Advance example


package main

import (
	"fmt"
	"github.com/foolin/goview"
	"html/template"
	"net/http"
	"time"
)

func main() {

	gv := goview.New(goview.Config{
		Root:      "views",
		Extension: ".tpl",
		Master:    "layouts/master",
		Partials:  []string{"partials/ad"},
		Funcs: template.FuncMap{
			"sub": func(a, b int) int {
				return a - b
			},
			"copy": func() string {
				return time.Now().Format("2006")
			},
		},
		DisableCache: true,
	})

	//Set new instance
	goview.Use(gv)

	//render index use `index` without `.html` extension, that will render with master layout.
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		err := goview.Render(w, http.StatusOK, "index", goview.M{
			"title": "Index title!",
			"add": func(a int, b int) int {
				return a + b
			},
		})
		if err != nil {
			fmt.Fprintf(w, "Render index error: %v!", err)
		}

	})

	//render page use `page.tpl` with '.html' will only file template without master layout.
	http.HandleFunc("/page", func(w http.ResponseWriter, r *http.Request) {
		err := goview.Render(w, http.StatusOK, "page.tpl", goview.M{"title": "Page file title!!"})
		if err != nil {
			fmt.Fprintf(w, "Render page.html error: %v!", err)
		}
	})

	fmt.Println("Listening and serving HTTP on :9090")
	http.ListenAndServe(":9090", nil)
}

Project structure:

|-- app/views/
    |--- index.tpl          
    |--- page.tpl
    |-- layouts/
        |--- footer.tpl
        |--- head.tpl
        |--- master.tpl
    |-- partials/
        |--- ad.tpl
    

See in "examples/advance" folder

Advance example

Multiple example


package main

import (
	"html/template"
	"net/http"
	"time"

	"github.com/foolin/goview"
	"github.com/gin-gonic/gin"
)

func main() {
	router := gin.Default()

	//new template engine
	router.HTMLRender = gintemplate.New(gintemplate.TemplateConfig{
		Root:      "views/fontend",
		Extension: ".html",
		Master:    "layouts/master",
		Partials:  []string{"partials/ad"},
		Funcs: template.FuncMap{
			"copy": func() string {
				return time.Now().Format("2006")
			},
		},
		DisableCache: true,
	})

	router.GET("/", func(ctx *gin.Context) {
		// `HTML()` is a helper func to deal with multiple TemplateEngine's.
		// It detects the suitable TemplateEngine for each path automatically.
		gintemplate.HTML(ctx, http.StatusOK, "index", gin.H{
			"title": "Fontend title!",
		})
	})

	//=========== Backend ===========//

	//new middleware
	mw := gintemplate.NewMiddleware(gintemplate.TemplateConfig{
		Root:      "views/backend",
		Extension: ".html",
		Master:    "layouts/master",
		Partials:  []string{},
		Funcs: template.FuncMap{
			"copy": func() string {
				return time.Now().Format("2006")
			},
		},
		DisableCache: true,
	})

	// You should use helper func `Middleware()` to set the supplied
	// TemplateEngine and make `HTML()` work validly.
	backendGroup := router.Group("/admin", mw)

	backendGroup.GET("/", func(ctx *gin.Context) {
		// With the middleware, `HTML()` can detect the valid TemplateEngine.
		gintemplate.HTML(ctx, http.StatusOK, "index", gin.H{
			"title": "Backend title!",
		})
	})

	router.Run(":9090")
}

Project structure:

|-- app/views/
    |-- fontend/
        |--- index.html
        |-- layouts/
            |--- footer.html
            |--- head.html
            |--- master.html
        |-- partials/
     	   |--- ad.html
    |-- backend/
        |--- index.html
        |-- layouts/
            |--- footer.html
            |--- head.html
            |--- master.html
        
See in "examples/multiple" folder

Multiple example

go.rice example

go get github.com/foolin/goview/supports/gorice

package main

import (
	"fmt"
	"github.com/GeertJohan/go.rice"
	"github.com/foolin/goview"
	"github.com/foolin/goview/supports/gorice"
	"net/http"
)

func main() {

	//static
	staticBox := rice.MustFindBox("static")
	staticFileServer := http.StripPrefix("/static/", http.FileServer(staticBox.HTTPBox()))
	http.Handle("/static/", staticFileServer)

	//new view engine
	gv := gorice.New(rice.MustFindBox("views"))
	//set engine for default instance
	goview.Use(gv)

	//render index use `index` without `.html` extension, that will render with master layout.
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		err := goview.Render(w, http.StatusOK, "index", goview.M{
			"title": "Index title!",
			"add": func(a int, b int) int {
				return a + b
			},
		})
		if err != nil {
			fmt.Fprintf(w, "Render index error: %v!", err)
		}

	})

	//render page use `page.tpl` with '.html' will only file template without master layout.
	http.HandleFunc("/page", func(w http.ResponseWriter, r *http.Request) {
		err := goview.Render(w, http.StatusOK, "page.html", goview.M{"title": "Page file title!!"})
		if err != nil {
			fmt.Fprintf(w, "Render page.html error: %v!", err)
		}
	})

	fmt.Println("Listening and serving HTTP on :9090")
	http.ListenAndServe(":9090", nil)
}

Project structure:

|-- app/views/
    |--- index.html          
    |--- page.html
    |-- layouts/
        |--- footer.html
        |--- master.html
|-- app/static/  
    |-- css/
        |--- bootstrap.css   	
    |-- img/
        |--- gopher.png

See in "examples/gorice" folder

gorice example

More examples

See _examples/ for a variety of examples.

Todo

[ ] Add Partials support directory or glob [ ] Add functions support.

The MIT License (MIT) Copyright (c) 2018 Foolin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

暂无描述 展开 收起
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
1
https://gitee.com/mx_space/goview.git
git@gitee.com:mx_space/goview.git
mx_space
goview
goview
master

搜索帮助

53164aa7 5694891 3bd8fe86 5694891