mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 02:31:04 +01:00
update Blocks module
This commit is contained in:
parent
e0ac28c1bb
commit
e7b40398aa
|
@ -8,6 +8,7 @@ func main() {
|
|||
// Note, in Blocks engine, layouts
|
||||
// are used by their base names, the
|
||||
// blocks.LayoutDir(layoutDir) defaults to "./layouts".
|
||||
// .Blocks(...).Layout("main") for default layout for all views, it can be modified through ctx.ViewLayout though.
|
||||
|
||||
app.Get("/", index)
|
||||
|
||||
|
|
|
@ -1,8 +1,3 @@
|
|||
<!-- You can define more than one block.
|
||||
The default one is "content" which should be the main template's body.
|
||||
So, even if it's missing (see index.html), it's added automatically by the view engine.
|
||||
When you need to define more than one block, you have to be more specific:
|
||||
-->
|
||||
{{ define "content" }}
|
||||
<h1>Internal Server Error</h1>
|
||||
{{ end }}
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
<title>{{.Code}}</title>
|
||||
</head>
|
||||
<body>
|
||||
{{ template "content" .}}
|
||||
{{ template "content" . }}
|
||||
|
||||
{{block "message" .}}{{end}}
|
||||
{{ block "message" . }}Default Error Message{{ end }}
|
||||
</body>
|
||||
</html>
|
38
_examples/view/template_blocks_2/main.go
Normal file
38
_examples/view/template_blocks_2/main.go
Normal file
|
@ -0,0 +1,38 @@
|
|||
package main
|
||||
|
||||
import "github.com/kataras/iris/v12"
|
||||
|
||||
// Based on https://github.com/kataras/iris/issues/2214.
|
||||
func main() {
|
||||
app := initApp()
|
||||
app.Listen(":8080")
|
||||
}
|
||||
|
||||
func initApp() *iris.Application {
|
||||
app := iris.New()
|
||||
app.Logger().SetLevel("debug")
|
||||
|
||||
tmpl := iris.Blocks("./src/public/html", ".html")
|
||||
tmpl.Layout("main")
|
||||
app.RegisterView(tmpl)
|
||||
|
||||
app.Get("/list", func(ctx iris.Context) {
|
||||
ctx.View("files/list")
|
||||
})
|
||||
|
||||
app.Get("/menu", func(ctx iris.Context) {
|
||||
ctx.View("menu/menu")
|
||||
})
|
||||
|
||||
app.Get("/list2", func(ctx iris.Context) {
|
||||
ctx.ViewLayout("secondary")
|
||||
ctx.View("files/list")
|
||||
})
|
||||
|
||||
app.Get("/menu2", func(ctx iris.Context) {
|
||||
ctx.ViewLayout("secondary")
|
||||
ctx.View("menu/menu")
|
||||
})
|
||||
|
||||
return app
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{{ define "title"}}
|
||||
<title>222</title>
|
||||
{{ end }}
|
||||
|
||||
{{ define "content" }}
|
||||
<h1>List Content</h1>
|
||||
{{ end }}
|
|
@ -0,0 +1,8 @@
|
|||
<html>
|
||||
<head>
|
||||
{{ block "title" .}}<title>Main Default Title</title>{{end}}
|
||||
</head>
|
||||
<body>
|
||||
{{ block "content" .}}<h1>Main Default Content</h1>{{end}}
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,9 @@
|
|||
<html>
|
||||
<head>
|
||||
{{ block "title" .}}<title>Secondary Default Title</title>{{end}}
|
||||
</head>
|
||||
<body>
|
||||
<h1>Secondary Layout</h1>
|
||||
{{ block "content" .}}<h1>Secondary Default Content</h1>{{end}}
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,3 @@
|
|||
{{ define "title" }} <title>111</title>{{ end }}
|
||||
|
||||
{{ define "content" }}<h1>Menu Content</h1>{{ end }}
|
16
aliases.go
16
aliases.go
|
@ -336,18 +336,18 @@ func ConfigureMiddleware(handlers ...Handler) router.PartyConfigurator {
|
|||
return &partyConfiguratorMiddleware{handlers: handlers}
|
||||
}
|
||||
|
||||
var (
|
||||
// Compression is a middleware which enables
|
||||
// writing and reading using the best offered compression.
|
||||
// Usage:
|
||||
// app.Use (for matched routes)
|
||||
// app.UseRouter (for both matched and 404s or other HTTP errors).
|
||||
Compression = func(ctx Context) {
|
||||
// Compression is a middleware which enables
|
||||
// writing and reading using the best offered compression.
|
||||
// Usage:
|
||||
// app.Use (for matched routes)
|
||||
// app.UseRouter (for both matched and 404s or other HTTP errors).
|
||||
func Compression(ctx Context) {
|
||||
ctx.CompressWriter(true)
|
||||
ctx.CompressReader(true)
|
||||
ctx.Next()
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
// AllowQuerySemicolons returns a middleware that serves requests by converting any
|
||||
// unescaped semicolons(;) in the URL query to ampersands(&).
|
||||
//
|
||||
|
|
|
@ -754,6 +754,13 @@ func (api *APIBuilder) createRoutes(errorCode int, methods []string, relativePat
|
|||
|
||||
mainHandlerFileName, mainHandlerFileNumber := context.HandlerFileLineRel(handlers[mainHandlerIndex])
|
||||
|
||||
// TODO: think of it.
|
||||
if mainHandlerFileName == "<autogenerated>" {
|
||||
// At PartyConfigure, 2nd+ level of routes it will get <autogenerated> but in reallity will be the same as the caller.
|
||||
mainHandlerFileName = filename
|
||||
mainHandlerFileNumber = line
|
||||
}
|
||||
|
||||
// re-calculate mainHandlerIndex in favor of the middlewares.
|
||||
mainHandlerIndex = len(beginHandlers) + mainHandlerIndex
|
||||
|
||||
|
|
|
@ -2,13 +2,11 @@ package router
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/kataras/iris/v12/context"
|
||||
"github.com/kataras/iris/v12/core/errgroup"
|
||||
|
@ -16,7 +14,6 @@ import (
|
|||
macroHandler "github.com/kataras/iris/v12/macro/handler"
|
||||
|
||||
"github.com/kataras/golog"
|
||||
"github.com/kataras/pio"
|
||||
)
|
||||
|
||||
type (
|
||||
|
@ -371,87 +368,7 @@ func (h *routerHandler) Build(provider RoutesProvider) error {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: move this and make it easier to read when all cases are, visually, tested.
|
||||
if logger := h.logger; logger != nil && logger.Level == golog.DebugLevel && noLogCount < len(registeredRoutes) {
|
||||
// group routes by method and print them without the [DBUG] and time info,
|
||||
// the route logs are colorful.
|
||||
// Note: don't use map, we need to keep registered order, use
|
||||
// different slices for each method.
|
||||
|
||||
collect := func(method string) (methodRoutes []*Route) {
|
||||
for _, r := range registeredRoutes {
|
||||
if r.NoLog {
|
||||
continue
|
||||
}
|
||||
if r.Method == method {
|
||||
methodRoutes = append(methodRoutes, r)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
type MethodRoutes struct {
|
||||
method string
|
||||
routes []*Route
|
||||
}
|
||||
|
||||
allMethods := append(AllMethods, []string{MethodNone, ""}...)
|
||||
methodRoutes := make([]MethodRoutes, 0, len(allMethods))
|
||||
|
||||
for _, method := range allMethods {
|
||||
routes := collect(method)
|
||||
if len(routes) > 0 {
|
||||
methodRoutes = append(methodRoutes, MethodRoutes{method, routes})
|
||||
}
|
||||
}
|
||||
|
||||
if n := len(methodRoutes); n > 0 {
|
||||
tr := "routes"
|
||||
if len(registeredRoutes) == 1 {
|
||||
tr = tr[0 : len(tr)-1]
|
||||
}
|
||||
|
||||
bckpNewLine := logger.NewLine
|
||||
logger.NewLine = false
|
||||
debugLevel := golog.Levels[golog.DebugLevel]
|
||||
// Replace that in order to not transfer it to the log handler (e.g. json)
|
||||
// logger.Debugf("API: %d registered %s (", len(registeredRoutes), tr)
|
||||
// with:
|
||||
pio.WriteRich(logger.Printer, debugLevel.Title, debugLevel.ColorCode, debugLevel.Style...)
|
||||
fmt.Fprintf(logger.Printer, " %s %sAPI: %d registered %s (", time.Now().Format(logger.TimeFormat), logger.Prefix, len(registeredRoutes)-noLogCount, tr)
|
||||
//
|
||||
logger.NewLine = bckpNewLine
|
||||
|
||||
for i, m := range methodRoutes {
|
||||
// @method: @count
|
||||
if i > 0 {
|
||||
if i == n-1 {
|
||||
fmt.Fprint(logger.Printer, " and ")
|
||||
} else {
|
||||
fmt.Fprint(logger.Printer, ", ")
|
||||
}
|
||||
}
|
||||
if m.method == "" {
|
||||
m.method = "ERROR"
|
||||
}
|
||||
fmt.Fprintf(logger.Printer, "%d ", len(m.routes))
|
||||
pio.WriteRich(logger.Printer, m.method, TraceTitleColorCode(m.method))
|
||||
}
|
||||
|
||||
fmt.Fprint(logger.Printer, ")\n")
|
||||
}
|
||||
|
||||
for i, m := range methodRoutes {
|
||||
for _, r := range m.routes {
|
||||
r.Trace(logger.Printer, -1)
|
||||
}
|
||||
|
||||
if i != len(allMethods)-1 {
|
||||
logger.Printer.Write(pio.NewLine)
|
||||
}
|
||||
}
|
||||
}
|
||||
printRoutesInfo(h.logger, registeredRoutes, noLogCount)
|
||||
|
||||
return errgroup.Check(rp)
|
||||
}
|
||||
|
|
94
core/router/handler_debug.go
Normal file
94
core/router/handler_debug.go
Normal file
|
@ -0,0 +1,94 @@
|
|||
package router
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/kataras/golog"
|
||||
"github.com/kataras/pio"
|
||||
)
|
||||
|
||||
func printRoutesInfo(logger *golog.Logger, registeredRoutes []*Route, noLogCount int) {
|
||||
if !(logger != nil && logger.Level == golog.DebugLevel && noLogCount < len(registeredRoutes)) {
|
||||
return
|
||||
}
|
||||
|
||||
// group routes by method and print them without the [DBUG] and time info,
|
||||
// the route logs are colorful.
|
||||
// Note: don't use map, we need to keep registered order, use
|
||||
// different slices for each method.
|
||||
|
||||
collect := func(method string) (methodRoutes []*Route) {
|
||||
for _, r := range registeredRoutes {
|
||||
if r.NoLog {
|
||||
continue
|
||||
}
|
||||
if r.Method == method {
|
||||
methodRoutes = append(methodRoutes, r)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
type MethodRoutes struct {
|
||||
method string
|
||||
routes []*Route
|
||||
}
|
||||
|
||||
allMethods := append(AllMethods, []string{MethodNone, ""}...)
|
||||
methodRoutes := make([]MethodRoutes, 0, len(allMethods))
|
||||
|
||||
for _, method := range allMethods {
|
||||
routes := collect(method)
|
||||
if len(routes) > 0 {
|
||||
methodRoutes = append(methodRoutes, MethodRoutes{method, routes})
|
||||
}
|
||||
}
|
||||
|
||||
if n := len(methodRoutes); n > 0 {
|
||||
tr := "routes"
|
||||
if len(registeredRoutes) == 1 {
|
||||
tr = tr[0 : len(tr)-1]
|
||||
}
|
||||
|
||||
bckpNewLine := logger.NewLine
|
||||
logger.NewLine = false
|
||||
debugLevel := golog.Levels[golog.DebugLevel]
|
||||
// Replace that in order to not transfer it to the log handler (e.g. json)
|
||||
// logger.Debugf("API: %d registered %s (", len(registeredRoutes), tr)
|
||||
// with:
|
||||
pio.WriteRich(logger.Printer, debugLevel.Title, debugLevel.ColorCode, debugLevel.Style...)
|
||||
fmt.Fprintf(logger.Printer, " %s %sAPI: %d registered %s (", time.Now().Format(logger.TimeFormat), logger.Prefix, len(registeredRoutes)-noLogCount, tr)
|
||||
//
|
||||
logger.NewLine = bckpNewLine
|
||||
|
||||
for i, m := range methodRoutes {
|
||||
// @method: @count
|
||||
if i > 0 {
|
||||
if i == n-1 {
|
||||
fmt.Fprint(logger.Printer, " and ")
|
||||
} else {
|
||||
fmt.Fprint(logger.Printer, ", ")
|
||||
}
|
||||
}
|
||||
if m.method == "" {
|
||||
m.method = "ERROR"
|
||||
}
|
||||
fmt.Fprintf(logger.Printer, "%d ", len(m.routes))
|
||||
pio.WriteRich(logger.Printer, m.method, TraceTitleColorCode(m.method))
|
||||
}
|
||||
|
||||
fmt.Fprint(logger.Printer, ")\n")
|
||||
}
|
||||
|
||||
for i, m := range methodRoutes {
|
||||
for _, r := range m.routes {
|
||||
r.Trace(logger.Printer, -1)
|
||||
}
|
||||
|
||||
if i != len(allMethods)-1 {
|
||||
logger.Printer.Write(pio.NewLine)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -562,6 +562,14 @@ func (r *Route) Trace(w io.Writer, stoppedIndex int) {
|
|||
file, line = context.HandlerFileLineRel(h)
|
||||
// If a middleware, e.g (macro) which changes the main handler index,
|
||||
// skip it.
|
||||
|
||||
// TODO: think of it.
|
||||
if file == "<autogenerated>" {
|
||||
// At PartyConfigure, 2nd+ level of routes it will get <autogenerated> but in reallity will be the same as the caller.
|
||||
file = r.RegisterFileName
|
||||
line = r.RegisterLineNumber
|
||||
}
|
||||
|
||||
if file == r.SourceFileName && line == r.SourceLineNumber {
|
||||
continue
|
||||
}
|
||||
|
|
3
go.mod
3
go.mod
|
@ -21,7 +21,7 @@ require (
|
|||
github.com/iris-contrib/httpexpect/v2 v2.15.2
|
||||
github.com/iris-contrib/schema v0.0.6
|
||||
github.com/json-iterator/go v1.1.12
|
||||
github.com/kataras/blocks v0.0.7
|
||||
github.com/kataras/blocks v0.0.8
|
||||
github.com/kataras/golog v0.1.9
|
||||
github.com/kataras/jwt v0.1.10
|
||||
github.com/kataras/neffos v0.0.22
|
||||
|
@ -107,6 +107,7 @@ require (
|
|||
github.com/yudai/gojsondiff v1.0.0 // indirect
|
||||
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.3 // indirect
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
moul.io/http2curl/v2 v2.3.0 // indirect
|
||||
)
|
||||
|
|
6
go.sum
generated
6
go.sum
generated
|
@ -105,8 +105,8 @@ github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8Hm
|
|||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/kataras/blocks v0.0.7 h1:cF3RDY/vxnSRezc7vLFlQFTYXG/yAr1o7WImJuZbzC4=
|
||||
github.com/kataras/blocks v0.0.7/go.mod h1:UJIU97CluDo0f+zEjbnbkeMRlvYORtmc1304EeyXf4I=
|
||||
github.com/kataras/blocks v0.0.8 h1:MrpVhoFTCR2v1iOOfGng5VJSILKeZZI+7NGfxEh3SUM=
|
||||
github.com/kataras/blocks v0.0.8/go.mod h1:9Jm5zx6BB+06NwA+OhTbHW1xkMOYxahnqTN5DveZ2Yg=
|
||||
github.com/kataras/golog v0.1.9 h1:vLvSDpP7kihFGKFAvBSofYo7qZNULYSHOH2D7rPTKJk=
|
||||
github.com/kataras/golog v0.1.9/go.mod h1:jlpk/bOaYCyqDqH18pgDHdaJab72yBE6i0O3s30hpWY=
|
||||
github.com/kataras/jwt v0.1.10 h1:GBXOF9RVInDPhCFBiDumRG9Tt27l7ugLeLo8HL5SeKQ=
|
||||
|
@ -263,6 +263,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
|||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
|
|
|
@ -46,6 +46,9 @@ type (
|
|||
|
||||
// Expires the duration of which the cookie must expires (created_time.Add(Expires)).
|
||||
// If you want to delete the cookie when the browser closes, set it to -1.
|
||||
// However, if you use a database storage setting this value to -1 may
|
||||
// cause you problems because of the fact that the database
|
||||
// may has its own expiration mechanism and value will be expired and removed immediately.
|
||||
//
|
||||
// 0 means no expire, (24 years)
|
||||
// -1 means when browser closes
|
||||
|
|
Loading…
Reference in New Issue
Block a user