Dancer2::Plugin::Paginator - Born Again

HISTORY

I would call it re-birth. It all started during end of July 2017, I was going through the documentation of Dancer2::Plugins and stumbled upon Dancer2::Plugin::Paginator. To my surprise, I found the link broken. My initial thought was, if there was any typo in the name. All my investigation led to the dark corner of BackPAN. At this point, I decided to bring it live.

REBIRTH

Following the advise from Neil Bowers, I contacted the author Blabos de Blebe by email, if he was happy for me take it forward. He not only encouraged me but also gave me permission to make it usable.

CHALLENGE

After getting the push from the author, my first challenge was to make it compatible with Dancer2::Plugins. Having done this with other plugins e.g. Dancer2::Plugin::Captcha, Dancer2::Plugin::Res and Dancer2::Plugin::Chain earlier helped with this task. I should give credit to Sawyer X for this gift, part of Perl Dancer Advent Calendar 2014.

EXAMPLE

Let me show you an example as described in the official document for Dancer2::Plugin::Paginator.

use Dancer2;
use Dancer2::Plugin::Paginator;

get '/list' => sub {
    my $paginator = paginator(
       'curr'     => $page,
       'items'    => rset('Post')->count,
       'base_url' => '/posts/page/',
    );

    template 'list', { paginator => $paginator };
};

true;

CONFIGURATION

To bring the above example live, we need to tune the configuration slightly as below.

plugins:
   Paginator:
      frame_size: 3
      page_size: 7

REAL HANDS-ON

Having seen the details, now let us try real example. I have got GitHub repository that I use to try new things related to Dancer2 i.e. Dancer2 Cookbook. You should find a link "Books" showing the pagination magic.

Example Configuration

plugins:
  Paginator:
    frame_size: 1
    page_size: 3

Action

get '/books/:page' => sub {
    my $books = _books();
    my $curr  = params->{page} || 1;

    template 'books' => _paginator($books, $curr);
};

sub _paginator {
    my ($books, $curr) = @_;

    my $items = scalar(@$books);
    my $paginator = paginator(
       curr     => $curr,
       items    => $items,
       base_url => '/books',
       mode     => 'path'
    );

    my $page_size = $paginator->page_size;
    my $i = ($curr - 1) * $page_size;
    my $j = ($i + $page_size) - 1;
    my $results = [ @$books[$i..$j] ];

    return {
       results   => $results,
       paginator => $paginator,
       prev_l    => $paginator->prev,
       next_l    => $paginator->next,
     };
}

Template

<% IF results.size %>
   <ul>
      <% FOREACH book IN results %>
         <% IF book.name %>
            <li><b><% book.name %></b> &nbsp; <a href="/edit/book/<% book.id %>">Edit</a></li>
         <% END %>
      <% END %>
   </ul>
   <br/>
   <hr/>
   <a href="/books/<% prev_l %>">[prev]</a>...<a href="/books/<% next_l %>">[next]</a>
   <hr/>
<% ELSE %>
   <ul><li><b>No book found.</b></li></ul>
<% END %>

CONCLUSION

This is all you need to get started. If you feel lucky, you can take a look at Paginator::Lite for more insights. Any questions/suggestions, feel free to get in touch mohammad.anwar@yahoo.com.

AUTHOR

This article has been written by Mohammad S Anwar for the Perl Dancer Advent Calendar 2018.

COPYRIGHT

No copyright retained. Enjoy.

Mohammad S Anwar