npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

express-paginatorjs

v1.0.1

Published

Pagination module for Express.js

Downloads

7

Readme

express-paginatorjs

Pagination module for express.js

Install

npm i express-paginatorjs

Basic usage with Express.js and express-handlebars

app.js: require

Misc dependencies: express-handlebars [https://github.com/ericf/express-handlebars]

const express = require('express')
const path = require('path')
const app = express()
// We need to have express-handlebars installed.
const hbs = require('express-handlebars')

app.js: Use Handlebars as the template engine and register helpers

// View engine setup
app.engine('hbs', hbs({
    extname: 'hbs',
    defaultLayout: 'layout',
    layoutsDir: __dirname + '/views/layouts/',
    helpers: {
        paginator: require('express-paginatorjs')
    }
}));
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');

app.js: Example routing with the paginator object that is required.

app.get('/posts', function (req, res, next) {
  res.render('index', {
      paginator: {
          limit: 10, // This key:value pair is required.
          defaultPage: 'posts', // This key:value pair defaults to 'posts' if not set.
          currentPage: req.params.page, // This key:value pair is required.
          totalPages: 20, // This key:value pair is required.
      }
  })
})

app.get('/posts/:page', function(req, res, next) {
  res.render('index', {
      paginator: {
          limit: 10, // This key:value pair is required.
          defaultPage: 'posts', // This key:value pair defaults to 'posts' if not set.
          currentPage: req.params.page, // This key:value pair is required.
          totalPages: 20, // This key:value pair is required.
      }
  })
})

index.hbs: Will output a default pagination based on bootstrap 4. [https://v4-alpha.getbootstrap.com/components/pagination/]

{{#paginator paginator}}
{{/paginator}}

index.hbs will output the following code block (active class will be automatically set on currentpage):

<nav aria-label="Page navigation">
  <ul class="pagination">
    <li class="page-item"><a class="page-link active" href="#">Previous</a></li>
    <li class="page-item"><a class="page-link" href="#">1</a></li>
    <li class="page-item"><a class="page-link" href="#">2</a></li>
    <li class="page-item"><a class="page-link" href="#">3</a></li>
    <li class="page-item"><a class="page-link" href="#">Next</a></li>
  </ul>
</nav>

Customizing the output

In the handlebars file you can customize the pagination.

Limit

{{#paginator paginator limit="4"}}
{{/paginator}}

Type

customizing your own block of code that will be output. Example:

{{#if paginator}}
  <nav aria-label="page navigation">
    <ul class="pagination">
    
      {{#paginator paginator type="prev"}}
        <li class="page-item"><a class="page-link" href="{{prev}}">Previous</a></li>
      {{/paginator}}
      
      {{#paginator paginator type="links" limit="10"}}
        <li class="page-item {{#if active}}active{{/if}}"><a class="page-link" href="{{href}}">{{n}}</a></li>
      {{/paginator}}
      
      {{#paginator paginator type="next"}}
        <li class="page-item"><a class="page-link" href="{{next}}">Next</a></li>
      {{/paginator}}
      
    </ul>
  </nav>
{{/if}}
{{#paginator paginator type="prev"}}
  ...This renders the previous link. Make sure to use the {{href}} key so that it will link correctly.
{{/paginator}}
      
{{#paginator paginator type="links"}}
  ...This renders the list items with their numbers and correct links as long as you provide the {{href}}
  and {{n}} keys.
{{/paginator}}
      
{{#paginator paginator type="next"}}
  ...This renders the next link. Make sure to use the {{href}} key so that it will link correctly.
{{/paginator}}

Advanced usage with MySQL (or other Databases)

This module was created to make dynamic paginations for web apps that connects to databases that will provide them with content.

This is an example of a web app that connects to a database and retrieves blog posts from it.

app.js

'use strict';
const express = require('express')
const path = require('path')
const app = express()
// We need to have express-handlebars installed.
const hbs = require('express-handlebars')
// And we need to connect to our database.
const db = require('<location-of-file>')


// The paginator object is declared outside of the render scope:
let paginator = {};
paginator.limit = 10; // Set your default limit here.
paginator.defaultPage = 'posts'; // Set your default page here.

/**
 * Middleware function to create pages and to set paginator key: values.
 */
 
let pages = (req, res, next) => {

    let currentPage = parseInt(req.params.page) || 1;

    let sql = "SELECT COUNT(post_id) AS total FROM blog_posts";
    db.query(sql, function(err, result){
        if (err) next(err);
        
        // We can do the queries with the paginator values.
        // But this is useful when we don't have a paginator plugin.
        res.locals.currentPage = currentPage;
        res.locals.totalPages = Math.ceil(parseInt(result[0].total) / paginator.limit);
        res.locals.totalPosts = result[0].total;

        // Make the same variable accessible in the pagination object.
        paginator.totalPages = res.locals.totalPages;
        paginator.currentPage = req.params.page;

        next();
    });
}

app.get('/', pages, function(req, res, next) {
    let limit = paginator.limit;
    let offset = res.locals.totalPosts - (paginator.limit * res.locals.currentPage);

    let sql = "SELECT * FROM (SELECT *, DATE_FORMAT(post_published, '%Y-%m-%d') AS published FROM blog_posts LIMIT ? OFFSET ?) sub ORDER BY post_id DESC";

    db.query(sql, [limit, offset], function(err, rows) {
        if (err) next(err);
        res.render('posts', {
            posts: rows,
            paginator: paginator
        })
    });
});

app.get('/:page', pages, function(req, res, next) {

    // Only render pages that do have posts.
    if (res.locals.currentPage > res.locals.totalPages)
        return res.redirect('/posts');

    // If there are 100 posts. Page two will query post 90 to 81. Page three: 71 to 80.
    let limit = paginator.limit;
    let offset = res.locals.totalPosts - (paginator.limit * res.locals.currentPage);
    
    if (offset < 0) {
        limit += offset; // Algebraic double negative
        offset = 0;
    }

    let sql = "SELECT * FROM (SELECT *, DATE_FORMAT(post_published, '%Y-%m-%d') AS published FROM blog_posts LIMIT ? OFFSET ?) sub ORDER BY post_id DESC";

    db.query(sql, [limit, offset], function(err, rows) {
        if (err) next(err);
        res.render('posts', {
            posts: rows,
            paginator: paginator
        })
    });
});