wp-go/app/theme/wp/wp.go

297 lines
7.0 KiB
Go
Raw Normal View History

2023-03-01 05:17:12 +00:00
package wp
import (
2023-08-26 13:29:55 +00:00
"errors"
2023-05-04 12:37:06 +00:00
"github.com/fthvgb1/wp-go/app/cmd/reload"
2023-05-13 10:50:10 +00:00
"github.com/fthvgb1/wp-go/app/pkg/config"
2023-05-04 12:37:06 +00:00
"github.com/fthvgb1/wp-go/app/pkg/constraints"
"github.com/fthvgb1/wp-go/app/pkg/logs"
2023-05-08 13:43:20 +00:00
"github.com/fthvgb1/wp-go/app/plugins/wphandle/apply"
2023-05-04 12:37:06 +00:00
"github.com/fthvgb1/wp-go/app/wpconfig"
2023-02-28 15:38:23 +00:00
"github.com/fthvgb1/wp-go/helper/maps"
2023-02-23 09:26:20 +00:00
str "github.com/fthvgb1/wp-go/helper/strings"
2023-02-10 13:23:30 +00:00
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
2023-04-24 13:51:43 +00:00
"html/template"
"net/http"
2023-05-13 10:50:10 +00:00
"os"
2023-07-04 15:36:25 +00:00
"strings"
)
type Handle struct {
Index *IndexHandle
Detail *DetailHandle
C *gin.Context
theme string
Session sessions.Session
ginH gin.H
password string
2023-04-24 13:51:43 +00:00
scene string
Code int
2023-04-24 13:51:43 +00:00
Stats string
templ string
2023-04-30 13:17:33 +00:00
components map[string]map[string][]Components[string]
2023-04-29 14:05:24 +00:00
componentHook map[string][]func(Components[string]) (Components[string], bool)
themeMods wpconfig.ThemeMods
2023-04-24 13:51:43 +00:00
handlers map[string]map[string][]HandleCall
handleHook map[string][]func(HandleCall) (HandleCall, bool)
err error
abort bool
2023-04-21 17:12:39 +00:00
stopPipe bool
componentsArgs map[string]any
2023-03-27 03:37:24 +00:00
componentFilterFn map[string][]func(*Handle, string, ...any) string
2023-04-24 13:51:43 +00:00
template *template.Template
}
2023-08-26 13:29:55 +00:00
func (h *Handle) Theme() string {
return h.theme
}
2023-05-05 12:45:20 +00:00
func (h *Handle) GinH() gin.H {
return h.ginH
}
func (h *Handle) SetScene(scene string) {
h.scene = scene
}
2023-04-30 13:17:33 +00:00
func (h *Handle) Components() map[string]map[string][]Components[string] {
2023-04-29 14:05:24 +00:00
return h.components
}
func (h *Handle) ComponentHook() map[string][]func(Components[string]) (Components[string], bool) {
return h.componentHook
}
func (h *Handle) Handlers() map[string]map[string][]HandleCall {
return h.handlers
}
func (h *Handle) HandleHook() map[string][]func(HandleCall) (HandleCall, bool) {
return h.handleHook
}
2023-04-24 13:51:43 +00:00
func (h *Handle) SetTemplate(template *template.Template) {
h.template = template
}
func (h *Handle) Template() *template.Template {
return h.template
}
2023-04-02 15:37:12 +00:00
2023-03-02 15:49:28 +00:00
type HandlePlugins map[string]HandleFn[*Handle]
2023-02-28 15:38:23 +00:00
// Components Order 为执行顺序,降序执行
2023-03-18 13:02:24 +00:00
type Components[T any] struct {
2023-04-29 14:05:24 +00:00
Name string
Val T
Fn func(*Handle) T
2023-06-15 10:00:57 +00:00
Order float64
2023-04-29 14:05:24 +00:00
Cached bool
2023-02-28 15:38:23 +00:00
}
type HandleFn[T any] func(T)
type HandleCall struct {
Fn HandleFn[*Handle]
2023-06-15 10:00:57 +00:00
Order float64
2023-04-21 17:12:39 +00:00
Name string
2023-02-28 15:38:23 +00:00
}
2023-05-03 15:57:49 +00:00
func InitHandle(fn func(*Handle), h *Handle) {
var inited = false
hh := reload.GetAnyValBys("themeArgAndConfig", h, func(h *Handle) Handle {
2023-04-30 13:17:33 +00:00
h.components = make(map[string]map[string][]Components[string])
h.componentsArgs = make(map[string]any)
h.componentFilterFn = make(map[string][]func(*Handle, string, ...any) string)
2023-04-24 13:51:43 +00:00
h.handlers = make(map[string]map[string][]HandleCall)
h.handleHook = make(map[string][]func(HandleCall) (HandleCall, bool))
2023-04-07 14:59:07 +00:00
h.ginH = gin.H{}
2023-05-03 15:57:49 +00:00
fnMap = map[string]map[string]any{}
fnHook = map[string]map[string]any{}
2023-06-13 04:02:46 +00:00
fn(h)
2023-05-08 13:43:20 +00:00
v := apply.UsePlugins()
pluginFn, ok := v.(func(*Handle))
if ok {
pluginFn(h)
}
2023-05-05 12:45:20 +00:00
h.C.Set("inited", true)
inited = true
2023-04-07 14:59:07 +00:00
return *h
})
h.ginH = maps.Copy(hh.ginH)
2023-04-24 13:51:43 +00:00
h.ginH["calPostClass"] = postClass(h)
h.ginH["calBodyClass"] = bodyClass(h)
h.ginH["customLogo"] = customLogo(h)
if inited {
return
}
2023-04-29 14:05:24 +00:00
h.components = hh.components
h.Index.postsPlugin = hh.Index.postsPlugin
h.Index.pageEle = hh.Index.pageEle
h.Detail.CommentRender = hh.Detail.CommentRender
2023-04-21 17:12:39 +00:00
h.handlers = hh.handlers
h.handleHook = hh.handleHook
2023-04-29 14:05:24 +00:00
h.componentHook = hh.componentHook
2023-04-02 15:37:12 +00:00
h.componentsArgs = hh.componentsArgs
h.componentFilterFn = hh.componentFilterFn
2023-05-05 12:45:20 +00:00
h.C.Set("inited", true)
2023-04-02 15:37:12 +00:00
}
2023-03-02 15:49:28 +00:00
func (h *Handle) Abort() {
h.abort = true
2023-05-08 13:43:20 +00:00
h.stopPipe = true
2023-03-02 15:49:28 +00:00
}
2023-04-21 17:12:39 +00:00
func (h *Handle) StopPipe() {
h.stopPipe = true
}
2023-05-08 13:43:20 +00:00
func (h *Handle) StopHandle() {
h.abort = true
}
2023-03-02 15:49:28 +00:00
func (h *Handle) CommonThemeMods() wpconfig.ThemeMods {
return h.themeMods
}
2023-02-28 15:38:23 +00:00
func (h *Handle) Err() error {
return h.err
}
func (h *Handle) SetErr(err error) {
2023-08-26 13:29:55 +00:00
h.err = errors.Join(err)
2023-02-28 15:38:23 +00:00
}
func (h *Handle) SetTempl(templ string) {
h.templ = templ
}
2023-04-24 13:51:43 +00:00
func (h *Handle) Scene() string {
2023-02-28 15:38:23 +00:00
return h.scene
}
func (h *Handle) SetDatas(GinH gin.H) {
maps.Merge(h.ginH, GinH)
}
func (h *Handle) SetData(k string, v any) {
h.ginH[k] = v
}
2023-04-24 13:51:43 +00:00
func NewHandle(c *gin.Context, scene string, theme string) *Handle {
2023-02-18 15:35:39 +00:00
mods, err := wpconfig.GetThemeMods(theme)
2023-04-07 14:59:07 +00:00
logs.IfError(err, "获取mods失败")
return &Handle{
C: c,
theme: theme,
Session: sessions.Default(c),
scene: scene,
Stats: constraints.Ok,
themeMods: mods,
}
2023-02-09 08:08:18 +00:00
}
2023-05-03 15:57:49 +00:00
func (h *Handle) GetPassword() string {
if h.password != "" {
return h.password
}
2023-02-22 14:11:25 +00:00
pw := h.Session.Get("post_password")
if pw != nil {
2023-02-28 15:38:23 +00:00
h.password = pw.(string)
}
2023-05-03 15:57:49 +00:00
return h.password
}
2023-03-14 11:21:00 +00:00
func PreTemplate(h *Handle) {
2023-02-28 15:38:23 +00:00
if h.templ == "" {
h.templ = str.Join(h.theme, "/posts/index.gohtml")
if h.scene == constraints.Detail {
h.templ = str.Join(h.theme, "/posts/detail.gohtml")
2023-02-23 09:26:20 +00:00
}
2023-02-22 14:11:25 +00:00
}
2023-02-27 14:58:35 +00:00
}
2023-03-14 11:21:00 +00:00
func PreCodeAndStats(h *Handle) {
2023-04-24 13:51:43 +00:00
if h.Stats != "" && h.Code != 0 {
2023-02-27 14:58:35 +00:00
return
2023-02-23 10:21:51 +00:00
}
2023-02-27 14:58:35 +00:00
switch h.Stats {
case constraints.Ok:
h.Code = http.StatusOK
case constraints.ParamError, constraints.Error404:
h.Code = http.StatusNotFound
case constraints.InternalErr:
h.Code = http.StatusInternalServerError
}
}
2023-05-05 12:45:20 +00:00
var htmlContentType = []string{"text/html; charset=utf-8"}
func (h *Handle) RenderHtml(t *template.Template, statsCode int, name string) {
header := h.C.Writer.Header()
if val := header["Content-Type"]; len(val) == 0 {
header["Content-Type"] = htmlContentType
}
h.C.Status(statsCode)
err := t.ExecuteTemplate(h.C.Writer, name, h.ginH)
h.Abort()
if err != nil {
panic(err)
}
}
func (h *Handle) PushHandlers(pipeScene string, call HandleCall, statsOrScene ...string) {
for _, s := range statsOrScene {
h.PushHandler(pipeScene, s, call)
}
}
2023-03-03 15:09:39 +00:00
func (h *Handle) CommonComponents() {
2023-04-30 13:17:33 +00:00
h.PushCacheGroupHeadScript(constraints.AllScene, "siteIconAndCustomCss", 0, CalSiteIcon, CalCustomCss)
2023-06-15 10:00:57 +00:00
h.PushRender(constraints.AllStats, NewHandleFn(CalComponents, 10.001, "wp.CalComponents"))
2023-05-05 12:45:20 +00:00
h.PushRender(constraints.AllStats, NewHandleFn(PreRenderTemplate, 0, "wp.PreRenderTemplate"))
2023-05-13 10:50:10 +00:00
AdditionScript(h)
}
func AdditionScript(h *Handle) {
s := config.GetConfig().ExternScript
if len(s) < 1 {
return
}
fn := func(f, name string) {
2023-05-13 10:52:19 +00:00
if f == "" {
return
}
2023-05-13 10:50:10 +00:00
ss, err := os.ReadFile(f)
if err != nil {
logs.Error(err, str.Join("解析", name, "失败"), f)
} else {
h.PushComponents(constraints.AllScene, constraints.HeadScript, NewComponent(name, string(ss), false, 0, nil))
}
}
switch len(s) {
case 1:
fn(s[0], "externHead")
case 2:
fn(s[0], "externHead")
fn(s[1], "externFooter")
}
2023-04-21 17:12:39 +00:00
}
2023-05-05 12:45:20 +00:00
func PreRenderTemplate(h *Handle) {
2023-04-21 17:12:39 +00:00
h.C.HTML(h.Code, h.templ, h.ginH)
2023-05-06 14:57:34 +00:00
h.Abort()
2023-02-09 15:15:10 +00:00
}
2023-06-15 10:00:57 +00:00
func NewHandleFn(fn HandleFn[*Handle], order float64, name string) HandleCall {
2023-04-21 17:12:39 +00:00
return HandleCall{Fn: fn, Order: order, Name: name}
2023-02-28 12:51:02 +00:00
}
2023-05-08 13:43:20 +00:00
func NothingToDo(h *Handle) {
h.Abort()
}
2023-07-04 15:36:25 +00:00
func (h *Handle) IsHttps() bool {
if h.C.Request.TLS != nil {
return true
}
return "https" == strings.ToLower(h.C.Request.Header.Get("X-Forwarded-Proto"))
}