优化 使搜索组件化

This commit is contained in:
xing 2023-03-09 22:36:41 +08:00
parent 1f7e51858b
commit 1da5062356
13 changed files with 181 additions and 42 deletions

View File

@ -31,7 +31,11 @@ const (
EntSpace = 8
)
func htmlSpecialChars(text string, flags int) string {
func SpecialChars(text string, flag ...int) string {
flags := EntQuotes
if len(flag) > 0 {
flags = flag[0]
}
r, ok := unEntitlesMap[flags]
e := entitlesMap[flags]
if !ok {
@ -48,7 +52,11 @@ func htmlSpecialChars(text string, flags int) string {
}
return text
}
func htmlSpecialCharsDecode(text string, flags int) string {
func SpecialCharsDecode(text string, flag ...int) string {
flags := EntQuotes
if len(flag) > 0 {
flags = flag[0]
}
r, ok := entitlesMap[flags]
u := unEntitlesMap[flags]
if !ok {

View File

@ -32,8 +32,8 @@ func Test_htmlSpecialChars(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := htmlSpecialChars(tt.args.text, tt.args.flags); got != tt.want {
t.Errorf("htmlSpecialChars() = %v, want %v", got, tt.want)
if got := SpecialChars(tt.args.text, tt.args.flags); got != tt.want {
t.Errorf("SpecialChars() = %v, want %v", got, tt.want)
}
})
}
@ -88,8 +88,8 @@ func Test_htmlSpecialCharsDecode(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := htmlSpecialCharsDecode(tt.args.text, tt.args.flags); got != tt.want {
t.Errorf("htmlSpecialCharsDecode() = %v, want %v", got, tt.want)
if got := SpecialCharsDecode(tt.args.text, tt.args.flags); got != tt.want {
t.Errorf("SpecialCharsDecode() = %v, want %v", got, tt.want)
}
})
}

View File

@ -1,6 +1,6 @@
package slice
func IsContained[T comparable](a T, arr []T) bool {
func IsContained[T comparable](arr []T, a T) bool {
for _, v := range arr {
if a == v {
return true
@ -23,7 +23,7 @@ func Diff[T comparable](a []T, b ...[]T) (r []T) {
for _, t := range a {
f := false
for _, ts := range b {
if IsContained(t, ts) {
if IsContained(ts, t) {
f = true
break
}
@ -74,7 +74,7 @@ func Intersect[T comparable](a []T, b ...[]T) (r []T) {
for _, t := range a {
f := false
for _, ts := range b {
if !IsContained(t, ts) {
if !IsContained(ts, t) {
f = true
break
}

View File

@ -8,7 +8,7 @@ import (
func ThemeHook(scene int) func(*gin.Context) {
return func(ctx *gin.Context) {
t := theme.GetTemplateName()
t := theme.GetCurrentTemplateName()
h := wp.NewHandle(ctx, scene, t)
h.Index = wp.NewIndexHandle(h)
h.Detail = wp.NewDetailHandle(h)

View File

@ -29,7 +29,7 @@ func SetupRouter() *gin.Engine {
}
}
r.HTMLRender = theme.GetTemplate()
r.HTMLRender = theme.Template()
wpconfig.SetTemplateFs(theme.TemplateFs)
siteFlowLimitMiddleware, siteFlow := middleware.FlowLimit(c.MaxRequestSleepNum, c.MaxRequestNum, c.CacheTime.SleepTime)
r.Use(

View File

@ -14,7 +14,7 @@ var TemplateFs embed.FS
var templates map[string]*template.Template //方便外部获取模板render后的字符串不然在gin中获取不了
func GetTemplate() *multipTemplate.MultipleFsTemplate {
func Template() *multipTemplate.MultipleFsTemplate {
t := multipTemplate.NewFsTemplate(TemplateFs)
templates = t.Template
t.FuncMap = FuncMap()
@ -24,6 +24,11 @@ func GetTemplate() *multipTemplate.MultipleFsTemplate {
return t
}
func GetTemplate(name string) (*template.Template, bool) {
t, ok := templates[name]
return t, ok
}
// 所有主题模板通用设置
func commonTemplate(t *multipTemplate.MultipleFsTemplate) {
m, err := fs.Glob(t.Fs, "*/posts/*.gohtml")

View File

@ -14,7 +14,7 @@ func InitTheme() {
twentyseventeen.Init(TemplateFs)
}
func GetTemplateName() string {
func GetCurrentTemplateName() string {
tmlp := config.GetConfig().Theme
if tmlp == "" {
tmlp = wpconfig.GetOption("template")

View File

@ -0,0 +1,5 @@
package components
const (
SearchFormArgs = "SearchFormArgs"
)

View File

@ -48,6 +48,10 @@ func (i *IndexHandle) ParseIndex(parm *IndexParams) (err error) {
i.Param = parm
switch i.scene {
case constraints.Home, constraints.Search:
s := i.C.Query("s")
if s != "" && strings.Replace(s, " ", "", -1) != "" {
i.scene = constraints.Search
}
i.Param.ParseSearch()
case constraints.Category:
err = i.Param.ParseCategory()

View File

@ -105,7 +105,7 @@ func NewIndexParams(ctx *gin.Context) *IndexParams {
func (i *IndexParams) parseSearch() {
s := i.Ctx.Query("s")
if s != "" && strings.Replace(s, " ", "", -1) != "" {
if s != "" {
q := str.Join("%", s, "%")
i.Where = append(i.Where, []string{
"and", "post_title", "like", q, "",

View File

@ -0,0 +1,60 @@
package wp
import (
"github.com/fthvgb1/wp-go/helper/html"
"github.com/fthvgb1/wp-go/helper/maps"
"github.com/fthvgb1/wp-go/helper/slice"
str "github.com/fthvgb1/wp-go/helper/strings"
"github.com/fthvgb1/wp-go/internal/theme/wp/components"
"github.com/fthvgb1/wp-go/internal/wpconfig"
"strings"
)
var searchTemplate = `{$before_widget}
{$title}
{$form}
{$after_widget}`
var searchArgs = map[string]string{
"{$before_widget}": `<aside id="search-2" class="widget widget_search">`,
"{$aria_label}": "",
"{$title}": "",
"{$before_title}": `<h2 class="widget-title">`,
"{$after_title}": `</h2>`,
"{$button}": "搜索",
"{$placeholder}": "搜索&hellip;",
"{$label}": "搜索:",
}
var html5SearchForm = `<form role="search" {$aria_label} method="get" class="search-form" action="/">
<label>
<span class="screen-reader-text">{$label}</span>
<input type="search" class="search-field" placeholder="{$placeholder}" value="{$value}" name="s" />
</label>
<input type="submit" class="search-submit" value="{$button}" />
</form>`
var xmlSearchForm = `<form role="search" {$aria_label} method="get" id="searchform" class="searchform" action="/">
<div>
<label class="screen-reader-text" for="s">{$label}</label>
<input type="text" value="{$value}" name="s" id="s" />
<input type="submit" id="searchsubmit" value="{$button}" />
</div>
</form>`
func GetSearchForm(h *Handle) string {
args := GetComponentsArgs(h, components.SearchFormArgs, searchArgs)
args = maps.Merge(searchArgs, args)
if args["{$title}"] == "" {
args["{$title}"] = wpconfig.GetPHPArrayVal("widget_search", "", int64(2), "title")
}
if args["{$title}"] != "" {
args["{$title}"] = str.Join(args["{$before_title}"], args["{$title}"], args["{$after_title}"])
}
args["{$value}"] = html.SpecialChars(h.Index.Param.Search)
form := html5SearchForm
if !slice.IsContained(h.CommonThemeMods().ThemeSupport.HTML5, "search-form") {
form = xmlSearchForm
}
s := strings.ReplaceAll(searchTemplate, "{$form}", form)
return str.Replace(s, args)
}

View File

@ -16,23 +16,24 @@ import (
)
type Handle struct {
Index *IndexHandle
Detail *DetailHandle
C *gin.Context
theme string
Session sessions.Session
ginH gin.H
password string
scene int
Code int
Stats int
templ string
class []string
components map[string][]Components
themeMods wpconfig.ThemeMods
handleFns map[int][]HandleCall
err error
abort bool
Index *IndexHandle
Detail *DetailHandle
C *gin.Context
theme string
Session sessions.Session
ginH gin.H
password string
scene int
Code int
Stats int
templ string
class []string
components map[string][]Components
themeMods wpconfig.ThemeMods
handleFns map[int][]HandleCall
err error
abort bool
componentsArgs map[string]any
}
type HandlePlugins map[string]HandleFn[*Handle]
@ -91,19 +92,75 @@ func (h *Handle) PushClass(class ...string) {
h.class = append(h.class, class...)
}
func GetComponentsArgs[T any](h *Handle, k string, defaults T) T {
v, ok := h.componentsArgs[k]
if ok {
vv, ok := v.(T)
if ok {
return vv
}
}
return defaults
}
func PushComponentsArgsForSlice[T any](h *Handle, name string, v ...T) {
val, ok := h.componentsArgs[name]
if !ok {
var vv []T
vv = append(vv, v...)
h.componentsArgs[name] = vv
return
}
vv, ok := val.([]T)
if ok {
vv = append(vv, v...)
h.componentsArgs[name] = vv
}
}
func SetComponentsArgsForMap[K comparable, V any](h *Handle, name string, key K, v V) {
val, ok := h.componentsArgs[name]
if !ok {
vv := make(map[K]V)
vv[key] = v
h.componentsArgs[name] = vv
return
}
vv, ok := val.(map[K]V)
if ok {
vv[key] = v
h.componentsArgs[name] = vv
}
}
func MergeComponentsArgsForMap[K comparable, V any](h *Handle, name string, m map[K]V) {
val, ok := h.componentsArgs[name]
if !ok {
h.componentsArgs[name] = m
return
}
vv, ok := val.(map[K]V)
if ok {
h.componentsArgs[name] = maps.Merge(vv, m)
}
}
func (h *Handle) SetComponentsArgs(key string, value any) {
h.componentsArgs[key] = value
}
func NewHandle(c *gin.Context, scene int, theme string) *Handle {
mods, err := wpconfig.GetThemeMods(theme)
logs.ErrPrintln(err, "获取mods失败")
return &Handle{
C: c,
theme: theme,
Session: sessions.Default(c),
ginH: gin.H{},
scene: scene,
Stats: constraints.Ok,
themeMods: mods,
components: make(map[string][]Components),
handleFns: make(map[int][]HandleCall),
C: c,
theme: theme,
Session: sessions.Default(c),
ginH: gin.H{},
scene: scene,
Stats: constraints.Ok,
themeMods: mods,
components: make(map[string][]Components),
handleFns: make(map[int][]HandleCall),
componentsArgs: make(map[string]any),
}
}

View File

@ -23,7 +23,7 @@ func (w SqlBuilder) parseWhereField(ss []string, s *strings.Builder) {
}
func (w SqlBuilder) parseIn(ss []string, s *strings.Builder, c *int, args *[]any, in *[][]any) (t bool) {
if slice.IsContained(ss[1], []string{"in", "not in"}) && len(*in) > 0 {
if slice.IsContained([]string{"in", "not in"}, strings.ToLower(ss[1])) && len(*in) > 0 {
s.WriteString(" (")
x := strings.TrimRight(strings.Repeat("?,", len((*in)[*c])), ",")
s.WriteString(x)
@ -152,7 +152,7 @@ func (w SqlBuilder) ParseWhere(in *[][]any) (string, []any, error) {
func (w SqlBuilder) parseOrderBy() string {
s := strings.Builder{}
for _, ss := range w {
if len(ss) == 2 && ss[0] != "" && slice.IsContained(strings.ToLower(ss[1]), []string{"asc", "desc"}) {
if len(ss) == 2 && ss[0] != "" && slice.IsContained([]string{"asc", "desc"}, strings.ToLower(ss[1])) {
s.WriteString(" ")
s.WriteString(ss[0])
s.WriteString(" ")