Compare commits

..

2 Commits

Author SHA1 Message Date
87f639da58 示例 2023-05-06 23:00:43 +08:00
ec211e8970 路由 2023-05-06 22:57:34 +08:00
6 changed files with 224 additions and 13 deletions

View File

@ -17,6 +17,13 @@ import (
"net/http" "net/http"
) )
var hooker []func(r *gin.Engine)
// Hook 方便插件在init时使用
func Hook(fn ...func(r *gin.Engine)) {
hooker = append(hooker, fn...)
}
func SetupRouter() *gin.Engine { func SetupRouter() *gin.Engine {
// Disable Console Color // Disable Console Color
// gin.DisableConsoleColor() // gin.DisableConsoleColor()
@ -83,6 +90,10 @@ func SetupRouter() *gin.Engine {
if c.Pprof != "" { if c.Pprof != "" {
pprof.Register(r, c.Pprof) pprof.Register(r, c.Pprof)
} }
for _, fn := range hooker {
fn(r)
}
reload.Push(func() { reload.Push(func() {
c := config.GetConfig() c := config.GetConfig()
siteFlow(c.MaxRequestSleepNum, c.MaxRequestNum, c.CacheTime.SleepTime) siteFlow(c.MaxRequestSleepNum, c.MaxRequestNum, c.CacheTime.SleepTime)

View File

@ -0,0 +1,9 @@
<div>
{{.aa}}
</div>
<div>
{{ range $k,$v := .posts}}
<h2>{{$v.PostTitle}} </h2>
{{end}}
</div>

View File

@ -1,24 +1,82 @@
package main package main
import ( import (
"embed"
"github.com/fthvgb1/wp-go/app/cmd/route"
"github.com/fthvgb1/wp-go/app/pkg/constraints" "github.com/fthvgb1/wp-go/app/pkg/constraints"
"github.com/fthvgb1/wp-go/app/pkg/logs"
"github.com/fthvgb1/wp-go/app/plugins/wphandle"
"github.com/fthvgb1/wp-go/app/theme" "github.com/fthvgb1/wp-go/app/theme"
"github.com/fthvgb1/wp-go/app/theme/wp" "github.com/fthvgb1/wp-go/app/theme/wp"
"github.com/fthvgb1/wp-go/app/theme/wp/components"
"github.com/fthvgb1/wp-go/app/theme/wp/components/widget"
route2 "github.com/fthvgb1/wp-go/app/theme/wp/route"
"github.com/gin-gonic/gin"
"html/template"
"net/http"
"plugintt/xx" "plugintt/xx"
) )
func init() { //go:embed a.gohtml
// here can register theme var em embed.FS
theme.AddThemeHookFunc("xxx", Xo) var tt *template.Template
}
func Xo(h *wp.Handle) { func init() {
// action or hook or config theme // register as theme
h.PushHandler(constraints.PipeRender, constraints.Home, wp.HandleCall{ theme.AddThemeHookFunc("themename", hook)
Fn: func(handle *wp.Handle) {
xx.Xo() //use the local template
}, //note: must use embed.FS
Order: 100, t, err := template.ParseFS(em, "a.gohtml")
Name: "xxxx", if err != nil {
logs.Error(err, "")
}
tt = t
// register gin route. it will be effecting when server restart.
route.Hook(func(r *gin.Engine) {
r.GET("xx", func(c *gin.Context) {
c.String(http.StatusOK, "xxoo")
})
})
}
func hook(h *wp.Handle) {
wp.Run(h, config)
}
func config(h *wp.Handle) {
// same theme config
wphandle.UsePlugins(h)
wp.InitPipe(h)
h.PushHandler(constraints.PipeMiddleware, constraints.Home,
wp.NewHandleFn(widget.IsCategory, 100, "widget.IsCategory"))
components.WidgetArea(h)
h.PushHandler(constraints.PipeRender, constraints.Home, wp.NewHandleFn(func(h *wp.Handle) {
h.SetData("aa", "xyxxxx")
h.RenderHtml(tt, http.StatusOK, "a.gohtml")
h.Abort()
h.StopPipe()
}, 10, "renderHome"))
// use simple reg route
route2.PushRoute(`(?P<control>\w+)/(?P<method>\w+)`, route2.Route{
Path: `(?P<control>\w+)/(?P<method>\w+)`,
Scene: constraints.Home,
Method: []string{"GET"},
Type: "reg",
ConfigHandle: wp.Index,
})
//...
}
// Xo to be a func when theme init
func Xo(h *wp.Handle) {
xx.Xo()
route2.Delete(`(?P<control>\w+)/(?P<method>\w+)`)
h.ReplaceHandle(constraints.PipeRender, "wp.RenderTemplate", func(h *wp.Handle) {
h.SetData("aa", "xyxxxx")
h.RenderHtml(tt, http.StatusOK, "a.gohtml")
h.StopPipe()
}) })
} }

View File

@ -2,5 +2,6 @@
# copy plugintt to other dir and remove .dev suffix # copy plugintt to other dir and remove .dev suffix
# note the go version and build tool flag must same to server build # note the go version and build tool flag must same to server build
# eg: -gcflags all="-N -l" may used in ide debug # eg: -gcflags all="-N -l" --race may used in ide debug
go mod tidy
go build -buildmode=plugin -o xx.so main.go go build -buildmode=plugin -o xx.so main.go

131
app/theme/wp/route/route.go Normal file
View File

@ -0,0 +1,131 @@
package route
import (
"github.com/fthvgb1/wp-go/app/cmd/reload"
"github.com/fthvgb1/wp-go/app/theme/wp"
"github.com/fthvgb1/wp-go/helper/slice"
"github.com/fthvgb1/wp-go/safety"
"regexp"
)
type Route struct {
Path string
Scene string
Method []string
Type string //const|reg
ConfigHandle func(*wp.Handle)
}
var routeHook []func(Route) (Route, bool)
var regRoutes *safety.Map[string, *regexp.Regexp]
var routes = func() *safety.Map[string, Route] {
r := safety.NewMap[string, Route]()
reload.Push(func() {
r.Flush()
regRoutes.Flush()
})
regRoutes = safety.NewMap[string, *regexp.Regexp]()
return r
}()
// PushRoute path can be const or regex string
//
// eg: `(?P<control>\w+)/(?P<method>\w+)`, route.Route{
// Path: `(?P<control>\w+)/(?P<method>\w+)`,
// Scene: constraints.Home,
// Method: []string{"GET"},
// Type: "reg",
// ConfigHandle: $theme.Hook or nil,
// }
func PushRoute(path string, route Route) error {
if route.Type == "const" {
routes.Store(path, route)
return nil
}
re, err := regexp.Compile(route.Path)
if err != nil {
return err
}
regRoutes.Store(path, re)
routes.Store(path, route)
return err
}
func Delete(path string) {
routeHook = append(routeHook, func(route Route) (Route, bool) {
return route, route.Path != path
})
}
func Replace(path string, route Route) {
routeHook = append(routeHook, func(r Route) (Route, bool) {
return route, path == route.Path
})
}
func Hook(path string, fn func(Route) Route) {
routeHook = append(routeHook, func(r Route) (Route, bool) {
if path == r.Path {
r = fn(r)
}
return r, path == r.Path
})
}
func ResolveRoute(h *wp.Handle) {
requestURI := h.C.Request.RequestURI
rs, rrs := reload.GetAnyValBys("route",
struct{}{},
func(_ struct{}) func() (map[string]Route, map[string]*regexp.Regexp) {
m := map[string]Route{}
rrs := map[string]*regexp.Regexp{}
routes.Range(func(key string, value Route) bool {
vv, _ := regRoutes.Load(key)
if len(routeHook) > 0 {
for _, fn := range routeHook {
v, ok := fn(value)
if ok {
m[v.Path] = v
if v.Type == "reg" {
if v.Path != key {
vvv, err := regexp.Compile(v.Path)
if err != nil {
panic(err)
}
vv = vvv
}
rrs[v.Path] = vv
}
}
}
} else {
m[key] = value
rrs[key] = vv
}
return true
})
return func() (map[string]Route, map[string]*regexp.Regexp) {
return m, rrs
}
})()
v, ok := rs[requestURI]
if ok && slice.IsContained(v.Method, h.C.Request.Method) {
h.SetScene(v.Scene)
wp.Run(h, v.ConfigHandle)
return
}
for path, reg := range rrs {
r := reg.FindAllStringSubmatch(requestURI, -1)
if len(r) < 1 {
return
}
rr := rs[path]
if slice.IsContained(rr.Method, h.C.Request.Method) {
h.SetScene(rr.Scene)
h.C.Set("route", r)
wp.Run(h, rr.ConfigHandle)
return
}
}
}

View File

@ -234,6 +234,7 @@ func (h *Handle) CommonComponents() {
func PreRenderTemplate(h *Handle) { func PreRenderTemplate(h *Handle) {
h.C.HTML(h.Code, h.templ, h.ginH) h.C.HTML(h.Code, h.templ, h.ginH)
h.Abort()
h.StopPipe() h.StopPipe()
} }