HOW TO PAGINATE IN GO(GOLANG) USING ECHO, PONGO2, AND BEEGO PAGINATION

Golang is still a relatively new language, and building enterprise applications around it can seem like a daunting task at times.

What is pagination?

Imagine you have a list of results to show. The list can be as short as one item, or as long as ten thousand items. You can tabulate these results and it would look great if it was a few rows of items to show. What about the case where we have ten thousand items? You figured correctly! We will need a way to only show a certain number of results per page. We don’t need a situation where a user needs to infinitely scroll down a page.

Recently, i needed a way to paginate our results. After searching for a good while, i decided to use this package that looked quite handy. This is probably the best way so far, and is also pure Golang. I am sure there are other ways, but this way works with almost any Golang application that has a Http request and context.

Before we import our application, let us see what package documentation says about it.

Package pagination provides utilities to setup a paginator within the context of a http request.

If you look closely at the example provided, they set up a paginator using the Beego controller context.

If you are not using Beego, don’t worry, it still works, but it needs a little change. The example provided uses beego controller context, and in the background, it calls a new paginator instance.

If you have an http request, go ahead and follow my example.

But I don’t use Beego? If you don’t use Beego, it is still a very simple task to accomplish.

In this example I will use Echo and Pongo2 context. All we need is a Http request from Echo, and a way to pass a paginator in Context. We will use Pongo2 Context to pass context here.

You can also get a link to Beego pagination below.
Beego Pagination
This example is also be available on GitHub

Show me the code.

package main


import (
	"github.com/astaxie/beego/utils/pagination"
	"github.com/labstack/echo"
	"net/http"
	"github.com/flosch/pongo2"
	"github.com/labstack/echo/middleware"
	"github.com/siredwin/pongorenderer/renderer" // this package is not publicly available
)

var (
	paginator = &pagination.Paginator{}
	data = pongo2.Context{}
	MainRenderer = renderer.Renderer{Debug:true}
)

//generator
func NewSlice(start, count, step int) []int {
	s := make([]int, count)
	for i := range s {
		s[i] = start
		start += step
	}
	return s
}

func ListAllUsers(c echo.Context) (error){
	// Lets use the Forbes top 7.
	usernames := []string{"Larry Ellison","Carlos Slim Helu", "Mark Zuckerberg", "Amancio Ortega ", "Jeff Bezos", " Warren Buffett ", "Bill Gates"}

	// sets paginator with the current offset (from the url query param)
	postsPerPage := 2
	paginator = pagination.NewPaginator(c.Request(), postsPerPage, len(usernames))

	// fetch the next posts "postsPerPage"
	idrange := NewSlice(paginator.Offset(), postsPerPage, 1)

	//create a new page list that shows up on html
	myusernames := []string{}
	for _, num := range idrange {
		//Prevent index out of range errors
		if num <= len(usernames)-1{
			myuser := usernames[num]
			myusernames = append(myusernames, myuser)
		}
	}

	// set the paginator in context
	// also set the page list in context
	// if you also have more data, set it context
	data = pongo2.Context{"paginator":paginator, "posts":myusernames}

	return c.Render(http.StatusOK, "templates/page.html", data)
}

func main() {
	// Echo instance
	e := echo.New()
	e.Renderer = MainRenderer // This example does not include the renderer.

	// Middleware
	e.Use(middleware.Logger())
	e.Use(middleware.Recover())

	// Route => handler
	e.GET("/", ListAllUsers)

	// Start server
	e.Logger.Fatal(e.Start(":8000"))
}

Edwin Siror avatar
About Edwin Siror
Edwin Siror writes about interesting topics on web technology, and is a avid user of Go(Golang). He is also the creator of S3zipper - an Aws S3 file zipping service(https://docs.s3zipper.com/)
comments powered by Disqus