diff --git a/helper/func.go b/helper/func.go index 1538a24..f182d1b 100644 --- a/helper/func.go +++ b/helper/func.go @@ -22,3 +22,12 @@ func StructColumn[T any, M any](arr []M, field string) (r []T) { } return } + +func RangeSlice[T ~int | ~uint | ~int64 | ~int8 | ~int16 | ~int32 | ~uint64](start, end, step T) []T { + r := make([]T, 0, int(end/step+1)) + for i := start; i <= end; { + r = append(r, i) + i = i + step + } + return r +} diff --git a/helper/func_test.go b/helper/func_test.go index 58fc311..8783794 100644 --- a/helper/func_test.go +++ b/helper/func_test.go @@ -73,3 +73,42 @@ func TestStructColumn(t *testing.T) { }) } } + +func TestRangeSlice(t *testing.T) { + type args struct { + start int + end int + step int + } + tests := []struct { + name string + args args + want []int + }{ + { + name: "t1", + args: args{ + start: 1, + end: 5, + step: 1, + }, + want: []int{1, 2, 3, 4, 5}, + }, + { + name: "t2", + args: args{ + start: 0, + end: 5, + step: 2, + }, + want: []int{0, 2, 4}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := RangeSlice(tt.args.start, tt.args.end, tt.args.step); !reflect.DeepEqual(got, tt.want) { + t.Errorf("RangeSlice() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/models/globalInit.go b/models/globalInit.go index 3ab6df2..2be76e9 100644 --- a/models/globalInit.go +++ b/models/globalInit.go @@ -1,7 +1,8 @@ package models var Options = make(map[string]string) -var TermsIds []uint64 +var Terms = map[uint64]WpTerms{} +var TermTaxonomy = map[uint64]WpTermTaxonomy{} func InitOptions() error { ops, err := SimpleFind[WpOptions](SqlBuilder{{"autoload", "yes"}}, "option_name, option_value") @@ -21,17 +22,19 @@ func InitOptions() error { } func InitTerms() (err error) { - var themes []interface{} - themes = append(themes, "wp_theme") - var name []interface{} - name = append(name, "twentyfifteen") - terms, err := Find[WpTerms](SqlBuilder{{ - "tt.taxonomy", "in", "", - }, {"t.name", "in", ""}}, "t.term_id", "", nil, SqlBuilder{{ - "t", "inner join", "wp_term_taxonomy tt", "t.term_id = tt.term_id", - }}, 1, themes, name) + terms, err := Find[WpTerms](nil, "*", "", nil, nil, 0) + if err != nil { + return err + } for _, wpTerms := range terms { - TermsIds = append(TermsIds, wpTerms.TermId) + Terms[wpTerms.TermId] = wpTerms + } + termTax, err := Find[WpTermTaxonomy](nil, "*", "", nil, nil, 0) + if err != nil { + return err + } + for _, taxonomy := range termTax { + TermTaxonomy[taxonomy.TermTaxonomyId] = taxonomy } return } diff --git a/models/model.go b/models/model.go index d66f75d..2a0a397 100644 --- a/models/model.go +++ b/models/model.go @@ -89,9 +89,9 @@ func (w SqlBuilder) parseOrderBy() string { s := strings.Builder{} for _, ss := range w { if len(ss) == 2 && ss[0] != "" && helper.IsContainInArr(ss[1], []string{"asc", "desc"}) { - s.WriteString(" `") + s.WriteString(" ") s.WriteString(ss[0]) - s.WriteString("` ") + s.WriteString(" ") s.WriteString(ss[1]) s.WriteString(",") } @@ -215,7 +215,12 @@ func Select[T Model](sql string, params ...interface{}) ([]T, error) { func Find[T Model](where ParseWhere, fields, group string, order SqlBuilder, join SqlBuilder, limit int, in ...[]interface{}) (r []T, err error) { var rr T - w, args := where.ParseWhere(in...) + w := "" + var args []interface{} + if where != nil { + w, args = where.ParseWhere(in...) + } + j := join.parseJoin() groupBy := "" if group != "" { diff --git a/models/wp_terms.go b/models/wp_terms.go index 63afe0b..98f7bd7 100644 --- a/models/wp_terms.go +++ b/models/wp_terms.go @@ -13,3 +13,15 @@ func (t WpTerms) PrimaryKey() string { func (t WpTerms) Table() string { return "wp_terms" } + +type WpTermsMy struct { + WpTerms + WpTermTaxonomy +} + +func (t WpTermsMy) PrimaryKey() string { + return "term_id" +} +func (t WpTermsMy) Table() string { + return "wp_terms" +} diff --git a/route/actions.go b/route/actions.go index 8dc87ef..25b9cc9 100644 --- a/route/actions.go +++ b/route/actions.go @@ -1,10 +1,13 @@ package route import ( + "fmt" "github.com/gin-gonic/gin" "github/fthvgb1/wp-go/models" + "math" "net/http" "strconv" + "strings" "sync" ) @@ -14,13 +17,24 @@ func index(c *gin.Context) { page := 1 pageSize := 10 p := c.Query("paged") - if pa, err := strconv.Atoi(p); err != nil { - page = pa + if p == "" { + p = c.Param("page") } + if p != "" { + if pa, err := strconv.Atoi(p); err == nil { + page = pa + } + } + status := []interface{}{"publish", "private"} - posts, _, err := models.SimplePagination[models.WpPosts](models.SqlBuilder{{ + posts, totalRaw, err := models.SimplePagination[models.WpPosts](models.SqlBuilder{{ "post_type", "post", }, {"post_status", "in", ""}}, "ID", page, pageSize, models.SqlBuilder{{"post_date", "desc"}}, nil, status) + defer func() { + if err != nil { + c.Error(err) + } + }() if err != nil { return } @@ -56,14 +70,23 @@ func index(c *gin.Context) { pp := post.(models.WpPosts) allPosts = append(allPosts, pp) } - recent, _ := recentPosts() - archive, _ := archives() - + recent, err := recentPosts() + archive, err := archives() + categoryItems, err := categories() + totalPage := int(math.Ceil(float64(totalRaw) / float64(pageSize))) + q := c.Request.URL.Query().Encode() + if q != "" { + q = fmt.Sprintf("?%s", q) + } c.HTML(http.StatusOK, "index.html", gin.H{ "posts": allPosts, "options": models.Options, "recentPosts": recent, "archives": archive, + "categories": categoryItems, + "totalPage": totalPage, + "queryRaw": q, + "pagination": pagination(page, totalPage, 1, q), }) } @@ -74,9 +97,97 @@ func recentPosts() (r []models.WpPosts, err error) { return } +func categories() (terms []models.WpTermsMy, err error) { + var in = []interface{}{"category"} + terms, err = models.Find[models.WpTermsMy](models.SqlBuilder{ + {"tt.count", ">", "0", "int"}, + {"tt.taxonomy", "in", ""}, + }, "t.term_id", "", models.SqlBuilder{ + {"t.name", "asc"}, + }, models.SqlBuilder{ + {"t", "inner join", "wp_term_taxonomy tt", "t.term_id = tt.term_id"}, + }, 0, in) + for i := 0; i < len(terms); i++ { + if v, ok := models.Terms[terms[i].WpTerms.TermId]; ok { + terms[i].WpTerms = v + } + if v, ok := models.TermTaxonomy[terms[i].WpTerms.TermId]; ok { + terms[i].WpTermTaxonomy = v + } + } + + return +} + func archives() (r []models.PostArchive, err error) { r, err = models.Find[models.PostArchive](models.SqlBuilder{ {"post_type", "post"}, {"post_status", "publish"}, }, "YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, count(ID) as posts", "year,month", models.SqlBuilder{{"year", "desc"}, {"month", "desc"}}, nil, 0) return } + +func pagination(currentPage, totalPage, step int, query string) (html string) { + html = "" + s := strings.Builder{} + if currentPage > totalPage { + currentPage = totalPage + } + + start := currentPage - step + end := currentPage + step + if start < 1 { + start = currentPage + } + if currentPage > 1 { + pp := "" + if currentPage > 2 { + pp = fmt.Sprintf("page/%d", currentPage-1) + } + s.WriteString(fmt.Sprintf(``, pp, query)) + } + if currentPage >= step+2 { + d := "" + if currentPage > step+2 { + d = `` + } + s.WriteString(fmt.Sprintf(` +1 +%s +`, query, d)) + } + if totalPage < end { + end = totalPage + } + + for page := start; page <= end; page++ { + h := "" + if currentPage == page { + h = fmt.Sprintf(` + + %d +`, page) + + } else { + d := fmt.Sprintf("/page/%d", page) + if currentPage > page && page == 1 { + d = "/" + } + h = fmt.Sprintf(` + +%d +`, d, query, page) + } + s.WriteString(h) + + } + if totalPage > currentPage+step+2 { + s.WriteString(fmt.Sprintf(` + +%d`, totalPage, query, totalPage)) + } + if currentPage < totalPage { + s.WriteString(fmt.Sprintf(``, currentPage+1, query)) + } + html = s.String() + return +} diff --git a/route/route.go b/route/route.go index 1cfdd03..814a87e 100644 --- a/route/route.go +++ b/route/route.go @@ -31,6 +31,7 @@ func SetupRouter() *gin.Engine { })) loadTemplates(r, "**/*") r.GET("/", index) + r.GET("/page/:page", index) return r } diff --git a/templates/index/index.html b/templates/index/index.html index 97f01c4..0aa5f0b 100644 --- a/templates/index/index.html +++ b/templates/index/index.html @@ -38,18 +38,7 @@ {{end}} - - + {{template "layout/page" .}} {{end}} diff --git a/templates/layout/pagination.html b/templates/layout/pagination.html new file mode 100644 index 0000000..ebaf778 --- /dev/null +++ b/templates/layout/pagination.html @@ -0,0 +1,8 @@ +{{define "layout/page"}} + +{{end}} \ No newline at end of file diff --git a/templates/layout/sidebar.html b/templates/layout/sidebar.html index ee3d1a4..df1fc2f 100644 --- a/templates/layout/sidebar.html +++ b/templates/layout/sidebar.html @@ -40,27 +40,9 @@