package models
import (
"math"
"net/http"
"strconv"
)
// Pagination result object.
type Pagination struct {
Page int
PerPage int
Total int64
Sort string
}
// Page for Iter.
type Page struct {
IsCurrent bool
// Load the page from form or query parameters.
func (p *Pagination) ParsePage(r *http.Request) {
raw := r.FormValue("page")
a, err := strconv.Atoi(raw)
if err == nil {
if a <= 0 {
a = 1
p.Page = a
} else {
p.Page = 1
// Iter the pages, for templates.
func (p *Pagination) Iter() []Page {
var (
pages = []Page{}
total = p.Pages()
for i := 1; i <= total; i++ {
pages = append(pages, Page{
Page: i,
IsCurrent: i == p.Page,
})
return pages
func (p *Pagination) Pages() int {
return int(math.Ceil(float64(p.Total) / float64(p.PerPage)))
func (p *Pagination) GetOffset() int {
return (p.Page - 1) * p.PerPage
func (p *Pagination) HasNext() bool {
return p.Page < p.Pages()
func (p *Pagination) HasPrevious() bool {
return p.Page > 1
func (p *Pagination) Next() int {
if p.Page >= p.Pages() {
return p.Pages()
return p.Page + 1
func (p *Pagination) Previous() int {
if p.Page > 1 {
return p.Page - 1
return 1