Browse Source

Blog pagination, settings, good pagination template

Vova Tkach 6 years ago
parent
commit
d4f8559de7

+ 1 - 0
.gitignore

@@ -31,6 +31,7 @@
 
 # All else
 /hosts/localhost/config/.installed
+/hosts/localhost/config/config.json
 
 # Skip cypress libs folder
 /cypress/screenshots

+ 4 - 0
assets/cp.styles.css

@@ -456,6 +456,10 @@ ul.pagination {
 	.data-form.users-modify .form-group.n7 {
 		margin-bottom: 0px;
 	}
+
+	.data-form.settings-pagination .form-group.n2 {
+		margin-bottom: 0px;
+	}
 }
 
 @media (max-width: 575px) {

File diff suppressed because it is too large
+ 0 - 0
assets/cp.styles.css.go


+ 12 - 0
engine/builder/data_form.go

@@ -10,6 +10,7 @@ import (
 const (
 	DFKHidden = iota
 	DFKText
+	DFKNumber
 	DFKEmail
 	DFKPassword
 	DFKTextArea
@@ -28,6 +29,8 @@ type DataFormField struct {
 	Target      string
 	Required    bool
 	Classes     string
+	Min         string
+	Max         string
 	CallBack    func(field *DataFormField) string
 }
 
@@ -73,6 +76,15 @@ func DataForm(wrap *wrapper.Wrapper, data []DataFormField) string {
 				html_element += `<div>`
 				if field.Kind == DFKText {
 					html_element += `<input class="form-control` + classes + `" type="text" id="lbl_` + field.Name + `" name="` + field.Name + `" value="` + html.EscapeString(field.Value) + `" placeholder="` + field.Placeholder + `" autocomplete="off"` + required + `>`
+				} else if field.Kind == DFKNumber {
+					html_element += `<input class="form-control` + classes + `" type="number" id="lbl_` + field.Name + `" name="` + field.Name + `" value="` + html.EscapeString(field.Value) + `" `
+					if field.Min != "" {
+						html_element += `min="` + field.Min + `" `
+					}
+					if field.Max != "" {
+						html_element += `max="` + field.Max + `" `
+					}
+					html_element += `placeholder="` + field.Placeholder + `" autocomplete="off"` + required + `>`
 				} else if field.Kind == DFKEmail {
 					html_element += `<input class="form-control` + classes + `" type="email" id="lbl_` + field.Name + `" name="` + field.Name + `" value="` + html.EscapeString(field.Value) + `" placeholder="` + field.Placeholder + `" autocomplete="off"` + required + `>`
 				} else if field.Kind == DFKPassword {

+ 64 - 7
engine/fetdata/blog.go

@@ -12,6 +12,7 @@ type BlogPagination struct {
 	Num     string
 	Link    string
 	Current bool
+	Dots    bool
 }
 
 type Blog struct {
@@ -134,8 +135,11 @@ func (this *Blog) init() {
 	}
 
 	if err := this.wrap.DB.QueryRow(sql_nums).Scan(&this.postsCount); err == nil {
-		// TODO: to control panel settings
-		this.postsPerPage = 5
+		if this.category == nil {
+			this.postsPerPage = (*this.wrap.Config).Blog.Pagination.Index
+		} else {
+			this.postsPerPage = (*this.wrap.Config).Blog.Pagination.Category
+		}
 		this.postsMaxPage = int(math.Ceil(float64(this.postsCount) / float64(this.postsPerPage)))
 		this.postsCurrPage = this.wrap.GetCurrentPage(this.postsMaxPage)
 		offset := this.postsCurrPage*this.postsPerPage - this.postsPerPage
@@ -151,16 +155,69 @@ func (this *Blog) init() {
 	}
 
 	// Build pagination
-	for i := 1; i <= this.postsMaxPage; i++ {
+	if true {
+		for i := 1; i < this.postsCurrPage; i++ {
+			if this.postsCurrPage >= 5 && i > 1 && i < this.postsCurrPage-1 {
+				continue
+			}
+			if this.postsCurrPage >= 5 && i > 1 && i < this.postsCurrPage {
+				this.pagination = append(this.pagination, &BlogPagination{
+					Dots: true,
+				})
+			}
+			link := this.wrap.R.URL.Path
+			if i > 1 {
+				link = link + "?p=" + utils.IntToStr(i)
+			}
+			this.pagination = append(this.pagination, &BlogPagination{
+				Num:     utils.IntToStr(i),
+				Link:    link,
+				Current: false,
+			})
+		}
+
+		// Current page
 		link := this.wrap.R.URL.Path
-		if i > 1 {
-			link = link + "?p=" + utils.IntToStr(i)
+		if this.postsCurrPage > 1 {
+			link = link + "?p=" + utils.IntToStr(this.postsCurrPage)
 		}
 		this.pagination = append(this.pagination, &BlogPagination{
-			Num:     utils.IntToStr(i),
+			Num:     utils.IntToStr(this.postsCurrPage),
 			Link:    link,
-			Current: i == this.postsCurrPage,
+			Current: true,
 		})
+
+		for i := this.postsCurrPage + 1; i <= this.postsMaxPage; i++ {
+			if this.postsCurrPage < this.postsMaxPage-3 && i == this.postsCurrPage+3 {
+				this.pagination = append(this.pagination, &BlogPagination{
+					Dots: true,
+				})
+			}
+			if this.postsCurrPage < this.postsMaxPage-3 && i > this.postsCurrPage+1 && i <= this.postsMaxPage-1 {
+				continue
+			}
+			link := this.wrap.R.URL.Path
+			if i > 1 {
+				link = link + "?p=" + utils.IntToStr(i)
+			}
+			this.pagination = append(this.pagination, &BlogPagination{
+				Num:     utils.IntToStr(i),
+				Link:    link,
+				Current: false,
+			})
+		}
+	} else {
+		for i := 1; i <= this.postsMaxPage; i++ {
+			link := this.wrap.R.URL.Path
+			if i > 1 {
+				link = link + "?p=" + utils.IntToStr(i)
+			}
+			this.pagination = append(this.pagination, &BlogPagination{
+				Num:     utils.IntToStr(i),
+				Link:    link,
+				Current: i == this.postsCurrPage,
+			})
+		}
 	}
 
 	// Pagination prev/next

+ 52 - 0
engine/wrapper/config.go

@@ -0,0 +1,52 @@
+package wrapper
+
+import (
+	"encoding/json"
+	"os"
+)
+
+type Config struct {
+	Blog struct {
+		Pagination struct {
+			Index    int
+			Category int
+		}
+	}
+}
+
+func configNew() *Config {
+	c := &Config{}
+	c.configDefault()
+	return c
+}
+
+func (this *Config) configDefault() {
+	this.Blog.Pagination.Index = 5
+	this.Blog.Pagination.Category = 5
+}
+
+func (this *Config) configRead(file string) error {
+	f, err := os.Open(file)
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+
+	dec := json.NewDecoder(f)
+	return dec.Decode(this)
+}
+
+func (this *Config) configWrite(file string) error {
+	r, err := json.Marshal(this)
+	if err != nil {
+		return err
+	}
+	f, err := os.Create(file)
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+
+	_, err = f.WriteString(string(r))
+	return err
+}

+ 10 - 0
engine/wrapper/wrapper.go

@@ -45,12 +45,17 @@ type Wrapper struct {
 	CurrModule      string
 	CurrSubModule   string
 	MSPool          *mysqlpool.MySqlPool
+	Config          *Config
 
 	DB   *sqlw.DB
 	User *utils.MySql_user
 }
 
 func New(l *logger.Logger, w http.ResponseWriter, r *http.Request, s *session.Session, host, port, chost, dirConfig, dirHtdocs, dirLogs, dirTemplate, dirTmp string, mp *mysqlpool.MySqlPool) *Wrapper {
+
+	conf := configNew()
+	_ = conf.configRead(dirConfig + string(os.PathSeparator) + "config.json")
+
 	return &Wrapper{
 		l:             l,
 		W:             w,
@@ -68,6 +73,7 @@ func New(l *logger.Logger, w http.ResponseWriter, r *http.Request, s *session.Se
 		CurrModule:    "",
 		CurrSubModule: "",
 		MSPool:        mp,
+		Config:        conf,
 	}
 }
 
@@ -276,3 +282,7 @@ func (this *Wrapper) GetCurrentPage(max int) int {
 	}
 	return curr
 }
+
+func (this *Wrapper) ConfigSave() error {
+	return this.Config.configWrite(this.DConfig + string(os.PathSeparator) + "config.json")
+}

+ 7 - 3
hosts/localhost/template/blog.html

@@ -34,9 +34,13 @@
 					</li>
 				{{end}}
 				{{range $.Data.Blog.Pagination}}
-					<li class="page-item{{if .Current}} active{{end}}">
-						<a class="page-link" href="{{.Link}}">{{.Num}}</a>
-					</li>
+					{{if .Dots}}
+						<li class="page-item disabled"><a class="page-link" href="">...</a></li>
+					{{else}}
+						<li class="page-item{{if .Current}} active{{end}}">
+							<a class="page-link" href="{{.Link}}">{{.Num}}</a>
+						</li>
+					{{end}}
 				{{end}}
 				{{if $.Data.Blog.PaginationNext}}
 					<li class="page-item{{if $.Data.Blog.PaginationNext.Current}} disabled{{end}}">

+ 42 - 0
modules/module_settings.go

@@ -9,6 +9,7 @@ import (
 	"golang-fave/consts"
 	"golang-fave/engine/builder"
 	"golang-fave/engine/wrapper"
+	"golang-fave/utils"
 )
 
 func (this *Modules) RegisterModule_Settings() *Module {
@@ -21,6 +22,7 @@ func (this *Modules) RegisterModule_Settings() *Module {
 		Icon:   assets.SysSvgIconGear,
 		Sub: &[]MISub{
 			{Mount: "default", Name: "Robots.txt", Show: true, Icon: assets.SysSvgIconBug},
+			{Mount: "pagination", Name: "Pagination", Show: true, Icon: assets.SysSvgIconList},
 		},
 	}, nil, func(wrap *wrapper.Wrapper) (string, string, string) {
 		content := ""
@@ -60,6 +62,46 @@ func (this *Modules) RegisterModule_Settings() *Module {
 				},
 			})
 
+			sidebar += `<button class="btn btn-primary btn-sidebar" id="add-edit-button">Save</button>`
+		} else if wrap.CurrSubModule == "pagination" {
+			content += this.getBreadCrumbs(wrap, &[]consts.BreadCrumb{
+				{Name: "Pagination"},
+			})
+
+			content += builder.DataForm(wrap, []builder.DataFormField{
+				{
+					Kind:  builder.DFKHidden,
+					Name:  "action",
+					Value: "settings-pagination",
+				},
+				{
+					Kind:     builder.DFKNumber,
+					Caption:  "Blog main page",
+					Name:     "blog-index",
+					Min:      "1",
+					Max:      "100",
+					Required: true,
+					Value:    utils.IntToStr((*wrap.Config).Blog.Pagination.Index),
+				},
+				{
+					Kind:     builder.DFKNumber,
+					Caption:  "Blog category page",
+					Name:     "blog-category",
+					Min:      "1",
+					Max:      "100",
+					Required: true,
+					Value:    utils.IntToStr((*wrap.Config).Blog.Pagination.Category),
+				},
+				{
+					Kind: builder.DFKMessage,
+				},
+				{
+					Kind:   builder.DFKSubmit,
+					Value:  "Save",
+					Target: "add-edit-button",
+				},
+			})
+
 			sidebar += `<button class="btn btn-primary btn-sidebar" id="add-edit-button">Save</button>`
 		}
 		return this.getSidebarModules(wrap), content, sidebar

+ 57 - 0
modules/module_settings_act_pagination.go

@@ -0,0 +1,57 @@
+package modules
+
+import (
+	"strconv"
+
+	"golang-fave/engine/wrapper"
+	"golang-fave/utils"
+)
+
+func (this *Modules) RegisterAction_SettingsPagination() *Action {
+	return this.newAction(AInfo{
+		WantDB:    true,
+		Mount:     "settings-pagination",
+		WantAdmin: true,
+	}, func(wrap *wrapper.Wrapper) {
+		pf_blog_index := wrap.R.FormValue("blog-index")
+		pf_blog_category := wrap.R.FormValue("blog-category")
+
+		if _, err := strconv.Atoi(pf_blog_index); err != nil {
+			wrap.MsgError(`Blog posts count per page on main page must be integer number`)
+			return
+		}
+		if _, err := strconv.Atoi(pf_blog_category); err != nil {
+			wrap.MsgError(`Blog posts count per page on category page must be integer number`)
+			return
+		}
+
+		pfi_blog_index := utils.StrToInt(pf_blog_index)
+		pfi_blog_category := utils.StrToInt(pf_blog_category)
+
+		// Correct some values
+		if pfi_blog_index < 0 {
+			pfi_blog_index = 1
+		}
+		if pfi_blog_index > 100 {
+			pfi_blog_index = 100
+		}
+
+		if pfi_blog_category < 0 {
+			pfi_blog_category = 1
+		}
+		if pfi_blog_category > 100 {
+			pfi_blog_category = 100
+		}
+
+		(*wrap.Config).Blog.Pagination.Index = pfi_blog_index
+		(*wrap.Config).Blog.Pagination.Category = pfi_blog_category
+
+		if err := wrap.ConfigSave(); err != nil {
+			wrap.MsgError(err.Error())
+			return
+		}
+
+		// Reload current page
+		wrap.Write(`window.location.reload(false);`)
+	})
+}

Some files were not shown because too many files changed in this diff