package fiber import ( "html/template" "log" "strconv" "time" "github.com/dmitriygnatenko/internal/interfaces" "github.com/dmitriygnatenko/internal/services/handler" adminHandler "github.com/dmitriygnatenko/internal/services/handler/admin" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/basicauth" "github.com/gofiber/fiber/v2/middleware/cors" "github.com/gofiber/fiber/v2/middleware/monitor" "github.com/gofiber/fiber/v2/middleware/recover" "github.com/gofiber/template/html" ) const ( appName = "dmitriygnatenko" templatesPath = "./../../internal/templates" staticPath = "../../web" ) func Init(sp interfaces.IServiceProvider) (*fiber.App, error) { fiberApp := fiber.New(getConfig(sp)) // Configure web root fiberApp.Static("/", staticPath) // Configure CORS middleware fiberApp.Use(cors.New()) // Configure recover middleware fiberApp.Use(recover.New()) // Configure handlers fiberApp.Get("/", handler.MainPageHandler(sp)) fiberApp.Get("/tag/:tag", handler.TagHandler(sp)) fiberApp.Get("/article/:article", handler.ArticleHandler(sp)) // Admin user := sp.GetEnvService().GetAdminUser() password := sp.GetEnvService().GetAdminPassword() if user != "" && password != "" { admin := fiberApp.Group("/admin", basicauth.New(basicauth.Config{ Users: map[string]string{ user: password, }, })) admin.Get("/metrics", monitor.New(monitor.Config{})) admin.Get("/", adminHandler.ArticleHandler(sp)) admin.All("/article/add", adminHandler.AddArticleHandler(sp)) admin.All("/article/edit/:id", adminHandler.EditArticleHandler(sp)) admin.All("/article/delete/:id", adminHandler.DeleteArticleHandler(sp)) admin.Get("/tag", adminHandler.TagHandler(sp)) admin.All("/tag/add", adminHandler.AddTagHandler(sp)) admin.All("/tag/edit/:id", adminHandler.EditTagHandler(sp)) admin.All("/tag/delete/:id", adminHandler.DeleteTagHandler(sp)) } return fiberApp, nil } func getConfig(sp interfaces.IServiceProvider) fiber.Config { return fiber.Config{ AppName: appName, DisableStartupMessage: true, Views: initEngine(sp.GetEnvService()), ErrorHandler: initErrorHandler(sp), } } func initEngine(env interfaces.IEnv) *html.Engine { engine := html.New(templatesPath, ".html") // nolint:gocritic engine.AddFunc("now", func() time.Time { return time.Now() }) // nolint:gosec engine.AddFunc("noescape", func(str string) template.HTML { return template.HTML(str) }) engine.AddFunc("gridsep", func(i, l int) bool { i++ return i%3 == 0 && i != l }) engine.AddFunc("version", func() string { return env.GetStaticVersion() }) engine.AddFunc("ga", func() bool { return env.IsGAEnabled() }) return engine } func initErrorHandler(sp interfaces.IServiceProvider) fiber.ErrorHandler { return func(ctx *fiber.Ctx, err error) error { errCode := fiber.StatusInternalServerError errText := err.Error() if e, ok := err.(*fiber.Error); ok { errCode = e.Code } var renderData fiber.Map if errCode == fiber.StatusNotFound { renderData = fiber.Map{ "pageTitle": "Страница не найдена", "code": fiber.StatusNotFound, "text": "Запрашиваемая вами страница не найдена", } } else { renderData = fiber.Map{ "pageTitle": "Внутренняя ошибка", "code": fiber.StatusInternalServerError, "text": "Внутренняя ошибка сервера, идем исправлять...", } } if errText != "" && errCode != fiber.StatusNotFound && errCode != fiber.StatusMethodNotAllowed { sendErr := sp.GetMailerService().Send( sp.GetEnvService().GetAdminEmail(), "Ошибка на сайте dmitriygnatenko.ru", "Код: "+strconv.Itoa(errCode)+"\r\n"+"Текст: "+errText, ) if sendErr != nil { log.Print(sendErr) } } renderData["headTitle"] = "От слона к суслику - статьи про PHP, Go, алгоритмы" return ctx.Render("error", renderData, "_layout") } }