Отображение html страницы
- Добавлен шаблонизатор jet - Сделан views для html страниц - Переработано отображение ошибок, теперь они корректно отображаются
This commit is contained in:
parent
ff614cea04
commit
f7a4ad6cdb
@ -3,6 +3,8 @@ module pink_fox
|
|||||||
go 1.24.1
|
go 1.24.1
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 // indirect
|
||||||
|
github.com/CloudyKit/jet/v6 v6.3.1 // indirect
|
||||||
github.com/bytedance/sonic v1.13.1 // indirect
|
github.com/bytedance/sonic v1.13.1 // indirect
|
||||||
github.com/bytedance/sonic/loader v0.2.4 // indirect
|
github.com/bytedance/sonic/loader v0.2.4 // indirect
|
||||||
github.com/cloudwego/base64x v0.1.5 // indirect
|
github.com/cloudwego/base64x v0.1.5 // indirect
|
||||||
|
|||||||
@ -1,3 +1,7 @@
|
|||||||
|
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 h1:sR+/8Yb4slttB4vD+b9btVEnWgL3Q00OBTzVT8B9C0c=
|
||||||
|
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno=
|
||||||
|
github.com/CloudyKit/jet/v6 v6.3.1 h1:6IAo5Cx21xrHVaR8zzXN5gJatKV/wO7Nf6bfCnCSbUw=
|
||||||
|
github.com/CloudyKit/jet/v6 v6.3.1/go.mod h1:lf8ksdNsxZt7/yH/3n4vJQWA9RUq4wpaHtArHhGVMOw=
|
||||||
github.com/bytedance/sonic v1.13.1 h1:Jyd5CIvdFnkOWuKXr+wm4Nyk2h0yAFsr8ucJgEasO3g=
|
github.com/bytedance/sonic v1.13.1 h1:Jyd5CIvdFnkOWuKXr+wm4Nyk2h0yAFsr8ucJgEasO3g=
|
||||||
github.com/bytedance/sonic v1.13.1/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4=
|
github.com/bytedance/sonic v1.13.1/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4=
|
||||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||||
|
|||||||
@ -1,16 +1,23 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/CloudyKit/jet/v6"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/gin-gonic/gin/render"
|
||||||
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"pink_fox/src/app"
|
"pink_fox/src/app"
|
||||||
c "pink_fox/src/app/config"
|
c "pink_fox/src/app/config"
|
||||||
"pink_fox/src/app/db"
|
"pink_fox/src/app/db"
|
||||||
l "pink_fox/src/app/logger"
|
l "pink_fox/src/app/logger"
|
||||||
"pink_fox/src/app/routes_manager"
|
"pink_fox/src/app/routes_manager"
|
||||||
|
"pink_fox/src/app/views_manager"
|
||||||
"pink_fox/src/routes"
|
"pink_fox/src/routes"
|
||||||
|
"pink_fox/src/views"
|
||||||
|
"runtime/debug"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
@ -52,13 +59,93 @@ func (it *Server) StartServer(application *app.Application) error {
|
|||||||
c.String(http.StatusOK, "ok")
|
c.String(http.StatusOK, "ok")
|
||||||
})
|
})
|
||||||
|
|
||||||
routes.RegistrationRoutes(routes_manager.NewManager(r, application))
|
r.Use(it.errorHandler(application.Logger))
|
||||||
|
|
||||||
|
err := it.loadTemplates(r)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tm := views_manager.NewManager()
|
||||||
|
views.RegistrationViews(tm)
|
||||||
|
|
||||||
|
routes.RegistrationRoutes(routes_manager.NewManager(r, application, tm))
|
||||||
|
|
||||||
fmt.Printf("Starting http_server at port %d...", application.Conf.Port)
|
fmt.Printf("Starting http_server at port %d...", application.Conf.Port)
|
||||||
err := r.Run(fmt.Sprintf(":%d", application.Conf.Port))
|
err = r.Run(fmt.Sprintf(":%d", application.Conf.Port))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (it *Server) loadTemplates(e *gin.Engine) error {
|
||||||
|
set := jet.NewSet(jet.NewOSFileSystemLoader("views"))
|
||||||
|
renderer := &JetRenderer{set: set}
|
||||||
|
e.HTMLRender = renderer
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (it *Server) errorHandler(logger *l.Logger) gin.HandlerFunc {
|
||||||
|
return func(ctx *gin.Context) {
|
||||||
|
it.errorHandlerSetRecovery(ctx)
|
||||||
|
if len(ctx.Errors) > 0 {
|
||||||
|
logger.Error(ctx.Errors[0].Error())
|
||||||
|
ctx.JSON(http.StatusInternalServerError, gin.H{
|
||||||
|
"errors": "Internal Server Error",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (it *Server) errorHandlerSetRecovery(ctx *gin.Context) {
|
||||||
|
defer func() {
|
||||||
|
if err := recover(); err != nil {
|
||||||
|
_ = ctx.Error(fmt.Errorf("panic: %v\n%s", err, debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
ctx.Next()
|
||||||
|
}
|
||||||
|
|
||||||
|
type JetRenderer struct {
|
||||||
|
set *jet.Set
|
||||||
|
template string
|
||||||
|
data any
|
||||||
|
}
|
||||||
|
|
||||||
|
func (it *JetRenderer) Instance(tpl string, data any) render.Render {
|
||||||
|
it.template = tpl
|
||||||
|
it.data = data
|
||||||
|
return it
|
||||||
|
}
|
||||||
|
|
||||||
|
func (it *JetRenderer) Render(w http.ResponseWriter) error {
|
||||||
|
tpl, err := it.set.GetTemplate(it.template)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
vars := make(jet.VarMap)
|
||||||
|
if it.data != nil {
|
||||||
|
if v, ok := it.data.(jet.VarMap); ok {
|
||||||
|
vars = v
|
||||||
|
} else {
|
||||||
|
vars.Set("data", it.data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
err = tpl.Execute(&buf, vars, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = io.Copy(w, &buf)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (it *JetRenderer) WriteContentType(http.ResponseWriter) {
|
||||||
|
// не знаю в каких случаях будет вызван этот метод
|
||||||
|
panic("implement me") // TODO
|
||||||
|
}
|
||||||
|
|||||||
@ -2,14 +2,19 @@ package http_server
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"pink_fox/src/app/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ResponseFactory struct {
|
type ResponseFactory struct {
|
||||||
ctx *gin.Context
|
ctx *gin.Context
|
||||||
|
makeViewObject types.MakeViewObject
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewResponseFactory(ctx *gin.Context) *ResponseFactory {
|
func NewResponseFactory(ctx *gin.Context, makeViewObject types.MakeViewObject) *ResponseFactory {
|
||||||
return &ResponseFactory{ctx: ctx}
|
return &ResponseFactory{
|
||||||
|
ctx: ctx,
|
||||||
|
makeViewObject: makeViewObject,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (it *ResponseFactory) String(s string) *StringResponse {
|
func (it *ResponseFactory) String(s string) *StringResponse {
|
||||||
@ -23,3 +28,7 @@ func (it *ResponseFactory) HtmlError(code int) *HtmlErrorResponse {
|
|||||||
func (it *ResponseFactory) Redirect(url string) *RedirectResponse {
|
func (it *ResponseFactory) Redirect(url string) *RedirectResponse {
|
||||||
return NewRedirectResponse(url, it.ctx)
|
return NewRedirectResponse(url, it.ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (it *ResponseFactory) View(id int16, file string, data any) *ViewResponse {
|
||||||
|
return NewViewResponse(it.ctx, it.makeViewObject, id, file, data)
|
||||||
|
}
|
||||||
|
|||||||
@ -2,8 +2,10 @@ package http_server
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/CloudyKit/jet/v6"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"pink_fox/src/app/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Response interface {
|
type Response interface {
|
||||||
@ -65,3 +67,29 @@ func (it *RedirectResponse) SetCode(code int) *RedirectResponse {
|
|||||||
func (it *RedirectResponse) Render() {
|
func (it *RedirectResponse) Render() {
|
||||||
it.ctx.Redirect(it.code, it.to)
|
it.ctx.Redirect(it.code, it.to)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ViewResponse struct {
|
||||||
|
ctx *gin.Context
|
||||||
|
makeViewObject types.MakeViewObject
|
||||||
|
id int16
|
||||||
|
file string
|
||||||
|
data any
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewViewResponse(ctx *gin.Context, makeViewObject types.MakeViewObject, id int16, file string, data any) *ViewResponse {
|
||||||
|
return &ViewResponse{
|
||||||
|
ctx: ctx,
|
||||||
|
makeViewObject: makeViewObject,
|
||||||
|
id: id,
|
||||||
|
file: file,
|
||||||
|
data: data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (it *ViewResponse) Render() {
|
||||||
|
data := make(jet.VarMap)
|
||||||
|
data.Set("vi", it.makeViewObject(it.id))
|
||||||
|
data.Set("it", it.data)
|
||||||
|
|
||||||
|
it.ctx.HTML(http.StatusOK, it.file, data)
|
||||||
|
}
|
||||||
|
|||||||
@ -5,8 +5,10 @@ import (
|
|||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"net/http"
|
"net/http"
|
||||||
"pink_fox/src/app"
|
"pink_fox/src/app"
|
||||||
"pink_fox/src/app/http_server"
|
hs "pink_fox/src/app/http_server"
|
||||||
le "pink_fox/src/app/lerror"
|
le "pink_fox/src/app/lerror"
|
||||||
|
"pink_fox/src/app/types"
|
||||||
|
vm2 "pink_fox/src/app/views_manager"
|
||||||
"pink_fox/src/dependence"
|
"pink_fox/src/dependence"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"strings"
|
"strings"
|
||||||
@ -16,21 +18,23 @@ type RoutesManager struct {
|
|||||||
engine *gin.Engine
|
engine *gin.Engine
|
||||||
application *app.Application
|
application *app.Application
|
||||||
middlewares []MiddlewareFunc
|
middlewares []MiddlewareFunc
|
||||||
|
vm *vm2.ViewsManager
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewManager(e *gin.Engine, application *app.Application) *RoutesManager {
|
func NewManager(e *gin.Engine, application *app.Application, vm *vm2.ViewsManager) *RoutesManager {
|
||||||
return &RoutesManager{
|
return &RoutesManager{
|
||||||
engine: e,
|
engine: e,
|
||||||
application: application,
|
application: application,
|
||||||
middlewares: make([]MiddlewareFunc, 0),
|
middlewares: make([]MiddlewareFunc, 0),
|
||||||
|
vm: vm,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type MiddlewareFunc func(*dependence.Container, ActionFunc) (http_server.Response, *le.Error)
|
type MiddlewareFunc func(*dependence.Container, ActionFunc) (hs.Response, *le.Error)
|
||||||
|
|
||||||
type HandlerFunc func(container *dependence.Container) (http_server.Response, *le.Error)
|
type HandlerFunc func(container *dependence.Container) (hs.Response, *le.Error)
|
||||||
|
|
||||||
type ActionFunc func() (http_server.Response, *le.Error)
|
type ActionFunc func() (hs.Response, *le.Error)
|
||||||
|
|
||||||
func (it *RoutesManager) Group(relativePath string, middlewares ...MiddlewareFunc) *Group {
|
func (it *RoutesManager) Group(relativePath string, middlewares ...MiddlewareFunc) *Group {
|
||||||
return NewGroup(it, relativePath, middlewares...)
|
return NewGroup(it, relativePath, middlewares...)
|
||||||
@ -41,18 +45,18 @@ func (it *RoutesManager) Use(middlewares ...MiddlewareFunc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (it *RoutesManager) ANY(relativePath string, handler HandlerFunc, middlewares ...MiddlewareFunc) {
|
func (it *RoutesManager) ANY(relativePath string, handler HandlerFunc, middlewares ...MiddlewareFunc) {
|
||||||
handlerForGin := makeHandlerGin(handler, append(it.middlewares, middlewares...), it.application)
|
handlerForGin := makeHandlerGin(handler, append(it.middlewares, middlewares...), it.application, it.vm)
|
||||||
it.engine.GET(relativePath, handlerForGin)
|
it.engine.GET(relativePath, handlerForGin)
|
||||||
it.engine.POST(relativePath, handlerForGin)
|
it.engine.POST(relativePath, handlerForGin)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (it *RoutesManager) GET(relativePath string, handler HandlerFunc, middlewares ...MiddlewareFunc) {
|
func (it *RoutesManager) GET(relativePath string, handler HandlerFunc, middlewares ...MiddlewareFunc) {
|
||||||
handlerForGin := makeHandlerGin(handler, append(it.middlewares, middlewares...), it.application)
|
handlerForGin := makeHandlerGin(handler, append(it.middlewares, middlewares...), it.application, it.vm)
|
||||||
it.engine.GET(relativePath, handlerForGin)
|
it.engine.GET(relativePath, handlerForGin)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (it *RoutesManager) POST(relativePath string, handler HandlerFunc, middlewares ...MiddlewareFunc) {
|
func (it *RoutesManager) POST(relativePath string, handler HandlerFunc, middlewares ...MiddlewareFunc) {
|
||||||
handlerForGin := makeHandlerGin(handler, append(it.middlewares, middlewares...), it.application)
|
handlerForGin := makeHandlerGin(handler, append(it.middlewares, middlewares...), it.application, it.vm)
|
||||||
it.engine.POST(relativePath, handlerForGin)
|
it.engine.POST(relativePath, handlerForGin)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,36 +87,62 @@ func (it *Group) Use(middlewares ...MiddlewareFunc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (it *Group) ANY(relativePath string, handler HandlerFunc, middlewares ...MiddlewareFunc) {
|
func (it *Group) ANY(relativePath string, handler HandlerFunc, middlewares ...MiddlewareFunc) {
|
||||||
handlerForGin := makeHandlerGin(handler, append(it.middlewares, middlewares...), it.routesManager.application)
|
handlerForGin := makeHandlerGin(handler, append(it.middlewares, middlewares...), it.routesManager.application, it.routesManager.vm)
|
||||||
it.routesManager.engine.GET(it.relativePath+relativePath, handlerForGin)
|
it.routesManager.engine.GET(it.relativePath+relativePath, handlerForGin)
|
||||||
it.routesManager.engine.POST(it.relativePath+relativePath, handlerForGin)
|
it.routesManager.engine.POST(it.relativePath+relativePath, handlerForGin)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (it *Group) GET(relativePath string, handler HandlerFunc, middlewares ...MiddlewareFunc) {
|
func (it *Group) GET(relativePath string, handler HandlerFunc, middlewares ...MiddlewareFunc) {
|
||||||
handlerForGin := makeHandlerGin(handler, append(it.middlewares, middlewares...), it.routesManager.application)
|
handlerForGin := makeHandlerGin(handler, append(it.middlewares, middlewares...), it.routesManager.application, it.routesManager.vm)
|
||||||
it.routesManager.engine.GET(it.relativePath+relativePath, handlerForGin)
|
it.routesManager.engine.GET(it.relativePath+relativePath, handlerForGin)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (it *Group) POST(relativePath string, handler HandlerFunc, middlewares ...MiddlewareFunc) {
|
func (it *Group) POST(relativePath string, handler HandlerFunc, middlewares ...MiddlewareFunc) {
|
||||||
handlerForGin := makeHandlerGin(handler, append(it.middlewares, middlewares...), it.routesManager.application)
|
handlerForGin := makeHandlerGin(handler, append(it.middlewares, middlewares...), it.routesManager.application, it.routesManager.vm)
|
||||||
it.routesManager.engine.POST(it.relativePath+relativePath, handlerForGin)
|
it.routesManager.engine.POST(it.relativePath+relativePath, handlerForGin)
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeHandlerGin(handler HandlerFunc, middlewares []MiddlewareFunc, application *app.Application) gin.HandlerFunc {
|
func makeHandlerGin(handler HandlerFunc, middlewares []MiddlewareFunc, application *app.Application, vm *vm2.ViewsManager) gin.HandlerFunc {
|
||||||
return func(ctx *gin.Context) {
|
return func(ctx *gin.Context) {
|
||||||
dic := dependence.NewContainer(application, ctx)
|
dic := dependence.NewContainer(application, ctx)
|
||||||
|
dic.SetViewManager(castMakeViewObject(dic, vm))
|
||||||
defer dic.Close()
|
defer dic.Close()
|
||||||
res, err := pipeline(handler, middlewares, dic)
|
err := execHandlerGin(handler, middlewares, dic, ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeToLog(err, application)
|
writeToLog(err, application)
|
||||||
showHtmlError(err, application, ctx)
|
showHtmlError(err, application, ctx)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
res.Render()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func pipeline(endpoint HandlerFunc, middlewares []MiddlewareFunc, di *dependence.Container) (resp http_server.Response, lerr *le.Error) {
|
func castMakeViewObject(depend *dependence.Container, vm *vm2.ViewsManager) types.MakeViewObject {
|
||||||
|
return func(id int16) any {
|
||||||
|
obj, err := vm.GetViewObject(id, depend)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("шаблон с id=%d не найден", id))
|
||||||
|
}
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func execHandlerGin(handler HandlerFunc, middlewares []MiddlewareFunc, dic *dependence.Container, ctx *gin.Context) *le.Error {
|
||||||
|
res, err := pipeline(handler, middlewares, dic)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
res.Render()
|
||||||
|
if len(ctx.Errors) > 0 {
|
||||||
|
errorGin := ctx.Errors[0]
|
||||||
|
ctx.Errors = make([]*gin.Error, 0)
|
||||||
|
return le.New(errorGin)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func pipeline(endpoint HandlerFunc, middlewares []MiddlewareFunc, di *dependence.Container) (resp hs.Response, lerr *le.Error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := recover(); err != nil {
|
if err := recover(); err != nil {
|
||||||
resp = nil
|
resp = nil
|
||||||
@ -120,7 +150,7 @@ func pipeline(endpoint HandlerFunc, middlewares []MiddlewareFunc, di *dependence
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
handler := func() (http_server.Response, *le.Error) {
|
handler := func() (hs.Response, *le.Error) {
|
||||||
return endpoint(di)
|
return endpoint(di)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,7 +163,7 @@ func pipeline(endpoint HandlerFunc, middlewares []MiddlewareFunc, di *dependence
|
|||||||
}
|
}
|
||||||
|
|
||||||
func createMiddleware(next ActionFunc, middleware MiddlewareFunc, di *dependence.Container) ActionFunc {
|
func createMiddleware(next ActionFunc, middleware MiddlewareFunc, di *dependence.Container) ActionFunc {
|
||||||
return func() (http_server.Response, *le.Error) {
|
return func() (hs.Response, *le.Error) {
|
||||||
return middleware(di, next)
|
return middleware(di, next)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -158,5 +188,5 @@ func showHtmlError(err *le.Error, application *app.Application, ctx *gin.Context
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx.Header("Content-Type", "text/html; charset=utf-8")
|
ctx.Header("Content-Type", "text/html; charset=utf-8")
|
||||||
ctx.String(500, fmt.Sprintf("<h1>500 %s</h1>\n%s\n", http.StatusText(500), message))
|
ctx.String(http.StatusInternalServerError, fmt.Sprintf("<h1>%d %s</h1>\n%s\n", http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError), message))
|
||||||
}
|
}
|
||||||
|
|||||||
3
pink_fox_app/src/app/types/types.go
Normal file
3
pink_fox_app/src/app/types/types.go
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
type MakeViewObject func(int16) any
|
||||||
30
pink_fox_app/src/app/views_manager/views_manager.go
Normal file
30
pink_fox_app/src/app/views_manager/views_manager.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package views_manager
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"pink_fox/src/dependence"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ViewsManager struct {
|
||||||
|
list map[int16]ViewsFunc
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewManager() *ViewsManager {
|
||||||
|
return &ViewsManager{
|
||||||
|
list: make(map[int16]ViewsFunc),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (it *ViewsManager) Add(id int16, tplFunc ViewsFunc) {
|
||||||
|
it.list[id] = tplFunc
|
||||||
|
}
|
||||||
|
|
||||||
|
func (it *ViewsManager) GetViewObject(id int16, depend *dependence.Container) (any, error) {
|
||||||
|
tplFunc, ok := it.list[id]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("GetViewObject: template id %v not found", id)
|
||||||
|
}
|
||||||
|
return tplFunc(depend), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type ViewsFunc func(*dependence.Container) any
|
||||||
25
pink_fox_app/src/controllers/Html.go
Normal file
25
pink_fox_app/src/controllers/Html.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"pink_fox/src/app/http_server"
|
||||||
|
le "pink_fox/src/app/lerror"
|
||||||
|
"pink_fox/src/views"
|
||||||
|
)
|
||||||
|
|
||||||
|
type HtmlController struct {
|
||||||
|
responseFactory *http_server.ResponseFactory
|
||||||
|
}
|
||||||
|
|
||||||
|
type HtmlControllerDependence interface {
|
||||||
|
MakeResponseFactory() *http_server.ResponseFactory
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHtmlController(depend HtmlControllerDependence) *HtmlController {
|
||||||
|
return &HtmlController{
|
||||||
|
responseFactory: depend.MakeResponseFactory(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (it *HtmlController) IndexAction() (http_server.Response, *le.Error) {
|
||||||
|
return it.responseFactory.View(views.Base, "test.jet", "hello"), nil
|
||||||
|
}
|
||||||
@ -4,12 +4,14 @@ import (
|
|||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"pink_fox/src/app"
|
"pink_fox/src/app"
|
||||||
"pink_fox/src/app/http_server"
|
"pink_fox/src/app/http_server"
|
||||||
|
"pink_fox/src/app/types"
|
||||||
repo "pink_fox/src/repositories"
|
repo "pink_fox/src/repositories"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Container struct {
|
type Container struct {
|
||||||
application *app.Application
|
application *app.Application
|
||||||
context *gin.Context
|
context *gin.Context
|
||||||
|
makeViewObject types.MakeViewObject
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewContainer(application *app.Application, context *gin.Context) *Container {
|
func NewContainer(application *app.Application, context *gin.Context) *Container {
|
||||||
@ -19,6 +21,10 @@ func NewContainer(application *app.Application, context *gin.Context) *Container
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (it *Container) SetViewManager(makeViewObject types.MakeViewObject) {
|
||||||
|
it.makeViewObject = makeViewObject
|
||||||
|
}
|
||||||
|
|
||||||
func (it *Container) Close() {
|
func (it *Container) Close() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,7 +33,7 @@ func (it *Container) MakeRequest() *http_server.Request {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (it *Container) MakeResponseFactory() *http_server.ResponseFactory {
|
func (it *Container) MakeResponseFactory() *http_server.ResponseFactory {
|
||||||
return http_server.NewResponseFactory(it.context)
|
return http_server.NewResponseFactory(it.context, it.makeViewObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (it *Container) MakeLinksRepository() repo.LinksRepository {
|
func (it *Container) MakeLinksRepository() repo.LinksRepository {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
package routes
|
package routes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"pink_fox/src/app/http_server"
|
hs "pink_fox/src/app/http_server"
|
||||||
le "pink_fox/src/app/lerror"
|
le "pink_fox/src/app/lerror"
|
||||||
"pink_fox/src/app/routes_manager"
|
"pink_fox/src/app/routes_manager"
|
||||||
"pink_fox/src/controllers"
|
"pink_fox/src/controllers"
|
||||||
@ -12,12 +12,18 @@ func RegistrationRoutes(r *routes_manager.RoutesManager) {
|
|||||||
r.GET("/", IndexController)
|
r.GET("/", IndexController)
|
||||||
|
|
||||||
r.GET("/link/:token", GoController)
|
r.GET("/link/:token", GoController)
|
||||||
|
|
||||||
|
r.GET("/html", HtmlController)
|
||||||
}
|
}
|
||||||
|
|
||||||
func IndexController(depend *di.Container) (http_server.Response, *le.Error) {
|
func HtmlController(depend *di.Container) (hs.Response, *le.Error) {
|
||||||
|
return controllers.NewHtmlController(depend).IndexAction()
|
||||||
|
}
|
||||||
|
|
||||||
|
func IndexController(depend *di.Container) (hs.Response, *le.Error) {
|
||||||
return controllers.NewIndexController(depend).IndexAction()
|
return controllers.NewIndexController(depend).IndexAction()
|
||||||
}
|
}
|
||||||
|
|
||||||
func GoController(depend *di.Container) (http_server.Response, *le.Error) {
|
func GoController(depend *di.Container) (hs.Response, *le.Error) {
|
||||||
return controllers.NewGoController().IndexAction(depend)
|
return controllers.NewGoController().IndexAction(depend)
|
||||||
}
|
}
|
||||||
|
|||||||
21
pink_fox_app/src/views/base.go
Normal file
21
pink_fox_app/src/views/base.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package views
|
||||||
|
|
||||||
|
import (
|
||||||
|
repo "pink_fox/src/repositories"
|
||||||
|
)
|
||||||
|
|
||||||
|
const Base int16 = 1
|
||||||
|
|
||||||
|
type BaseView struct {
|
||||||
|
Title string
|
||||||
|
}
|
||||||
|
|
||||||
|
type BaseViewInterface interface {
|
||||||
|
MakeLinksRepository() repo.LinksRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBase(_ BaseViewInterface) *BaseView {
|
||||||
|
return &BaseView{
|
||||||
|
Title: "Hello World!",
|
||||||
|
}
|
||||||
|
}
|
||||||
16
pink_fox_app/src/views/registration.go
Normal file
16
pink_fox_app/src/views/registration.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package views
|
||||||
|
|
||||||
|
import (
|
||||||
|
"pink_fox/src/app/views_manager"
|
||||||
|
"pink_fox/src/dependence"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RegistrationViews(tm *views_manager.ViewsManager) {
|
||||||
|
tm.Add(Base, MakeBaseView())
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakeBaseView() func(container *dependence.Container) any {
|
||||||
|
return func(depend *dependence.Container) any {
|
||||||
|
return NewBase(depend)
|
||||||
|
}
|
||||||
|
}
|
||||||
2
pink_fox_app/views/test.jet
Normal file
2
pink_fox_app/views/test.jet
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<h1>{{ vi.Title }}</h1>
|
||||||
|
<p>{{ it }}</p>
|
||||||
Loading…
Reference in New Issue
Block a user