mirror of
https://github.com/kataras/iris.git
synced 2025-12-18 18:37:05 +00:00
Add notes for the new lead maintainer of the open-source iris project and align with @get-ion/ion by @hiveminded
Former-commit-id: da4f38eb9034daa49446df3ee529423b98f9b331
This commit is contained in:
79
_examples/routing/custom-context/method-overriding/main.go
Normal file
79
_examples/routing/custom-context/method-overriding/main.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package main
|
||||
|
||||
// In this package I'll show you how to override the existing Context's functions and methods.
|
||||
// You can easly navigate to the custom-context example to see how you can add new functions
|
||||
// to your own context (need a custom handler).
|
||||
//
|
||||
// This way is far easier to understand and it's faster when you want to override existing methods:
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/kataras/iris"
|
||||
"github.com/kataras/iris/context"
|
||||
)
|
||||
|
||||
// Create your own custom Context, put any fields you wanna need.
|
||||
type MyContext struct {
|
||||
// Optional Part 1: embed (optional but required if you don't want to override all context's methods)
|
||||
context.Context // it's the context/context.go#context struct but you don't need to know it.
|
||||
}
|
||||
|
||||
var _ context.Context = &MyContext{} // optionally: validate on compile-time if MyContext implements context.Context.
|
||||
|
||||
// Optional Part 2:
|
||||
// The only one important if you will override the Context with an embedded context.Context inside it.
|
||||
func (ctx *MyContext) Next() {
|
||||
context.Next(ctx)
|
||||
}
|
||||
|
||||
// Override any context's method you want...
|
||||
// [...]
|
||||
|
||||
func (ctx *MyContext) HTML(htmlContents string) (int, error) {
|
||||
ctx.Application().Logger().Infof("Executing .HTML function from MyContext")
|
||||
|
||||
ctx.ContentType("text/html")
|
||||
return ctx.WriteString(htmlContents)
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
// Register a view engine on .html files inside the ./view/** directory.
|
||||
app.RegisterView(iris.HTML("./view", ".html"))
|
||||
|
||||
// The only one Required:
|
||||
// here is how you define how your own context will be created and acquired from the iris' generic context pool.
|
||||
app.ContextPool.Attach(func() context.Context {
|
||||
return &MyContext{
|
||||
// Optional Part 3:
|
||||
Context: context.NewContext(app),
|
||||
}
|
||||
})
|
||||
|
||||
// register your route, as you normally do
|
||||
app.Handle("GET", "/", recordWhichContextJustForProofOfConcept, func(ctx context.Context) {
|
||||
// use the context's overridden HTML method.
|
||||
ctx.HTML("<h1> Hello from my custom context's HTML! </h1>")
|
||||
})
|
||||
|
||||
// this will be executed by the MyContext.Context
|
||||
// if MyContext is not directly define the View function by itself.
|
||||
app.Handle("GET", "/hi/{firstname:alphabetical}", recordWhichContextJustForProofOfConcept, func(ctx context.Context) {
|
||||
firstname := ctx.Values().GetString("firstname")
|
||||
|
||||
ctx.ViewData("firstname", firstname)
|
||||
ctx.Gzip(true)
|
||||
|
||||
ctx.View("hi.html")
|
||||
})
|
||||
|
||||
app.Run(iris.Addr(":8080"))
|
||||
}
|
||||
|
||||
// should always print "($PATH) Handler is executing from 'MyContext'"
|
||||
func recordWhichContextJustForProofOfConcept(ctx context.Context) {
|
||||
ctx.Application().Logger().Infof("(%s) Handler is executing from: '%s'", ctx.Path(), reflect.TypeOf(ctx).Elem().Name())
|
||||
ctx.Next()
|
||||
}
|
||||
|
||||
// Look "new-implementation" to see how you can create an entirely new Context with new functions.
|
||||
@@ -0,0 +1 @@
|
||||
<h1> Hi {{.firstname}} </h1>
|
||||
104
_examples/routing/custom-context/new-implementation/main.go
Normal file
104
_examples/routing/custom-context/new-implementation/main.go
Normal file
@@ -0,0 +1,104 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/kataras/iris"
|
||||
"github.com/kataras/iris/context"
|
||||
"github.com/kataras/iris/sessions"
|
||||
)
|
||||
|
||||
// Owner is our application structure, it contains the methods or fields we need,
|
||||
// think it as the owner of our *Context.
|
||||
type Owner struct {
|
||||
// define here the fields that are global
|
||||
// and shared to all clients.
|
||||
sessionsManager *sessions.Sessions
|
||||
}
|
||||
|
||||
// this package-level variable "application" will be used inside context to communicate with our global Application.
|
||||
var owner = &Owner{
|
||||
sessionsManager: sessions.New(sessions.Config{Cookie: "mysessioncookie"}),
|
||||
}
|
||||
|
||||
// Context is our custom context.
|
||||
// Let's implement a context which will give us access
|
||||
// to the client's Session with a trivial `ctx.Session()` call.
|
||||
type Context struct {
|
||||
context.Context
|
||||
session *sessions.Session
|
||||
}
|
||||
|
||||
// Session returns the current client's session.
|
||||
func (ctx *Context) Session() *sessions.Session {
|
||||
// this help us if we call `Session()` multiple times in the same handler
|
||||
if ctx.session == nil {
|
||||
// start a new session if not created before.
|
||||
ctx.session = owner.sessionsManager.Start(ctx.Context)
|
||||
}
|
||||
|
||||
return ctx.session
|
||||
}
|
||||
|
||||
// Bold will send a bold text to the client.
|
||||
func (ctx *Context) Bold(text string) {
|
||||
ctx.HTML("<b>" + text + "</b>")
|
||||
}
|
||||
|
||||
var contextPool = sync.Pool{New: func() interface{} {
|
||||
return &Context{}
|
||||
}}
|
||||
|
||||
func acquire(original context.Context) *Context {
|
||||
ctx := contextPool.Get().(*Context)
|
||||
ctx.Context = original // set the context to the original one in order to have access to iris's implementation.
|
||||
ctx.session = nil // reset the session
|
||||
return ctx
|
||||
}
|
||||
|
||||
func release(ctx *Context) {
|
||||
contextPool.Put(ctx)
|
||||
}
|
||||
|
||||
// Handler will convert our handler of func(*Context) to an iris Handler,
|
||||
// in order to be compatible with the HTTP API.
|
||||
func Handler(h func(*Context)) context.Handler {
|
||||
return func(original context.Context) {
|
||||
ctx := acquire(original)
|
||||
h(ctx)
|
||||
release(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
func newApp() *iris.Application {
|
||||
app := iris.New()
|
||||
|
||||
// Work as you did before, the only difference
|
||||
// is that the original context.Handler should be wrapped with our custom
|
||||
// `Handler` function.
|
||||
app.Get("/", Handler(func(ctx *Context) {
|
||||
ctx.Bold("Hello from our *Context")
|
||||
}))
|
||||
|
||||
app.Post("/set", Handler(func(ctx *Context) {
|
||||
nameFieldValue := ctx.FormValue("name")
|
||||
ctx.Session().Set("name", nameFieldValue)
|
||||
ctx.Writef("set session = " + nameFieldValue)
|
||||
}))
|
||||
|
||||
app.Get("/get", Handler(func(ctx *Context) {
|
||||
name := ctx.Session().GetString("name")
|
||||
ctx.Writef(name)
|
||||
}))
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := newApp()
|
||||
|
||||
// GET: http://localhost:8080
|
||||
// POST: http://localhost:8080/set
|
||||
// GET: http://localhost:8080/get
|
||||
app.Run(iris.Addr(":8080"))
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/kataras/iris/httptest"
|
||||
)
|
||||
|
||||
func TestCustomContextNewImpl(t *testing.T) {
|
||||
app := newApp()
|
||||
e := httptest.New(t, app, httptest.URL("http://localhost:8080"))
|
||||
|
||||
e.GET("/").Expect().
|
||||
Status(httptest.StatusOK).
|
||||
ContentType("text/html").
|
||||
Body().Equal("<b>Hello from our *Context</b>")
|
||||
|
||||
expectedName := "iris"
|
||||
e.POST("/set").WithFormField("name", expectedName).Expect().
|
||||
Status(httptest.StatusOK).
|
||||
Body().Equal("set session = " + expectedName)
|
||||
|
||||
e.GET("/get").Expect().
|
||||
Status(httptest.StatusOK).
|
||||
Body().Equal(expectedName)
|
||||
}
|
||||
Reference in New Issue
Block a user