flask-ypaginate 0.1.3 documentation

Overview

flask-ypaginate is a simple pagination extension for flask , and it is forked from flask-paginate.

Plus points of flask-ypaginate:

  • A rewritten page generation algorithm, which is better tested and in my opinion, is simpler to understand
  • Preserves behavior of flask-paginate, so your code does not need to change if you want to retain the old behavior. (This is apart from the page generation algorithm which is totally changed, so Pagination.links will probably look different)
  • 2 new modes of URL generation for page links
  • Unit Tests added
  • Better documentation (I hope!)

Requirements

  • Twitter Bootstrap framework.
  • Python 2.6+ (use string.format syntax)

Examples of HTML output

{{ pagination.info|safe }}
The screenshot of pagination information

or

The screenshot of pagination information when search
{{ pagination.links|safe }}
The screenshot of pagination links

Explanation of Pagination

Explanation of Pagination

Installation

On the command line, run:

$ pip install flask-ypaginate

This assumes that you have pip installed.

Configuration

If you want to show the pagination information, add below lines to your css file.

.pagination-page-info {
    padding: .6em;
    padding-left: 0;
    width: 40em;
    margin: .5em;
    margin-left: 0;
    font-size: 12px;
}
.pagination-page-info b {
    color: black;
    background: #6aa6ed;
    padding-left: 2px;
    padding: .1em .25em;
    font-size: 150%;
}

How to Use (Simple Endpoint style URL generation)

This mode is enabled by supplying Pagination.MODE_SIMPLE to the mode keyword argument of the Pagination constructor. An endpoint keyword argument, whose value is a URL prefix, is also expected.

p = Pagination(mode=Pagination.MODE_SIMPLE,
        page=3, total=90, perPage=10, endpoint='/some/page')

The above will generate the following url for page 5:

/some/page/5/perPage/10

The URLs generated in Pagination.MODE_SIMPLE are of this form:

endpoint + '/' + 'page' + '/' + page + 'perPage' + '/' + perPage

The page and perPage strings can be set to strings of your choice, by supplying the pageSep and perPageSep keyword arguments to the Pagination constructor, like this:

p = Pagination(page=3, total=200, perPage=15, endpoint='/some/page',
        pageSep='good', perPageSep='day')

The url generated for page 5 will be:

/some/page/good/5/day/15

How to Use (Fixed mode)

This mode of URL generation is very similar to flask-paginate’s behavior, except that bugs (in my opinion) are fixed.

To enable this mode, supply the Pagination.MODE_FIXED to the mode keyword argument of the Pagination constructor:

pagination = Pagination(mode=Pagination.MODE_FIXED)

Major differences between MODE_FIXED and MODE_ORIGINAL:

1. Instead of relying on request.endpoint, you can supply the endpoint keyword argument (a string). The endpoint is then passed to the flask.url_for function to obtain the link for the supplied endpoint.

This will come in handy if you have multiple URLs sharing the same view function, and you want to use one specific URL, which in general cannot be done using request.endpoint (I think).

Example:

import flask
import flask.views

app = flask.Flask(__name__)

class MyView(flask.views.MethodView):
    def __init__(self):
        pass

    def get(self, page, perPage):
        # do some stuff here...

        # finally...
        p = Pagination(mode=Pagination.MODE_FIXED, page=page,
                perPage=perPage)

# Notice that the 2 rules below share the same view function
myview_fn = MyView.as_view('myview_fn')
app.add_url_rule('/items/<page>/<perPage>', view_func=myview_fn,
    methods=['GET'])

app.add_url_rule('/items/<page>', view_func=myview_fn,
    methods=['GET'], defaults={ 'perPage': 10 })

In the code above, the url rules ‘/items/<page>/<perPage>’ and ‘/items/<page>’ share the same view function, myview_fn. If a user were to access that endpoint via the ‘/items/<page>’ rule, say using ‘/items/2’, this will cause the links generated to be of the form:

/items/<page>

and result in the ‘perPage’ portion to be omitted.

If you want the urls for that view to be of this form:

/items/<page>/<perPage>

The solution is, to name the different endpoints by supplying the endpoint argument to flask.Flask.add_url_rule. When creating a new Pagination object, supply the endpoint argument to the Pagination constructor, with its value being the name of the endpoint whose url you want:

import flask
import flask.views

app = flask.Flask(__name__)

class MyView(flask.views.MethodView):
    def __init__(self):
        pass

    def get(self, page, perPage):
        # do some stuff here...

        # we want the url rule to be of the form '/items/<page>/<perPage>'
        # It is given by the endpoint 'myview_a'
        # so we pass endpoint='myview_a' to the Pagination constructor here
        p = Pagination(mode=Pagination.MODE_FIXED, page=page,
                perPage=perPage, endpoint='myview_a')

myview_fn = MyView.as_view('myview_fn')
# observe that the url rules now have the 'endpoint' argument
app.add_url_rule('/items/<page>/<perPage>', view_func=myview_fn,
    endpoint='myview_a', methods=['GET'])

app.add_url_rule('/items/<page>', view_func=myview_fn,
    endpoint='myview_a', methods=['GET'], defaults={ 'perPage': 10 })

So even when the user accesses the view using this form:

/item/<page>

The URLs generated by the Pagination object will still be of this form:

/item/<page>/<perPage>

2. Instead of the ‘page’ variable, Pagination.MODE_FIXED allows you to specify the name of the variable in the endpoint to replace the page value of a link with. This is done through the ‘pageSep’ keyword argument in the Pagination constructor.

An example will make this more clear.

# assume you have this endpoint
@app.route('/some/<page>/value')
def some_fn():
    # here, the 'page' variable holds the value of the current page
    pagination = Pagination(mode=Pagination.MODE_FIXED, page=4,
        total=100, perPage=10)

So a link for page 5 will be:

/some/5/value?perPage=10

The ”?perPage=10” portion is part of request.view_args. request.args and request.view_args are appended as a query string to the generated URL if there are no URL parameters that can be substituted.

Now, flask-paginate assumes the use of the variable named page to specify a page (whether you have it as a variable in the endpoint, or as a query parameter). flask-ypaginate gives you the freedom to choose the name of that variable. Suppose you want to use cat to represent the page number. What you will do is:

@app.route('/some/<cat>/value')
def some_fn():
    # here, the 'cat' variable  holds the value of the current page
    pagination = Pagination(mode=Pagination.MODE_FIXED, page=4,
        total=100, perPage=10, pageSep='cat')

The critical part here is the pageSep keyword argument passed to the Pagination constructor. This allows you to access the page number through the cat variable inside the view function.

3. flask-ypaginate makes use of the perPage variable to specify the number of records per page. Like the page variable, flask-ypaginate allows you to change the name of this variable by supplying the perPageSep keyword argument to the Pagination constructor. Usage is just like the pageSep keyword argument above.

An example of the use of page and perPage:

@app.route('/<page>/branches/<sheep>')
def get_items():
    # here, the variable 'page' holds the value of the current page,
    # while the variable 'sheep' holds the number of items per page.
    #
    # notice that we pass in the 'perPageSep' keyword argument to
    # the Pagination constructo
    pagination = Pagination(mode=Pagination.MODE_FIXED, page=page,
        total=1000, perPage=sheep, perPageSep='sheep')

Pagination Constructor

These are the parameters for Pagination.__init__().

mode: One of:

Pagination.MODE_ORIGINAL: flask-paginate style URL generation. This is the default value if the mode keyword argument is not supplied

Pagination.MODE_SIMPLE: simple URL generation

Pagination.MODE_FIXED: similar to flask-paginate style URL generation, but with some bugs fixed. It allows you to supply the name of the endpoint function instead using request.endpoint . For more information, read the “How to use (Fixed mode)” section above

endpoint: url endpoint.

If self.mode is Pagination.MODE_ORIGINAL, this value is ignored, and request.endpoint is used

If self.mode is Pagination.MODE_SIMPLE, this is used as the prefix of URLs generated

If self.mode is Pagination.MODE_FIXED, this value is the name of the view function if supplied, and defaults to request.endpoint if not supplied.

found: used when searching

page: current page

perPage: how many items displayed on one page

pageSep: Defaults to ‘perPage’.

If self.mode is Pagination.MODE_SIMPLE, this is the path preceding the integer page value in a generated page url.

If self.mode is Pagination.MODE_FIXED, this is the request.args variable name in the flask url endpoint that will be substituted with an integer page value.

perPageSep: Defaults to ‘perPage’.

If self.mode is Pagination.MODE_SIMPLE, this is the path preceding the integer perPage value in a generated page url.

If self.mode is Pagination.MODE_FIXED, this is the request.args variable name in the flask url endpoint that will be substitude with an integer perPage value.

innerWindow: number of links before and after the current page.

If this is set to 2, then in Pagination.links, 2 pages will come before the current page, and 2 pages will come after the current page.

Suppose that there are 30 pages, our current page is 10, and innerWindow is set to 3. Then the “middle section” of Pagination.links will look consist of pages 7, 8, 9, 10, 11, 12, 13.

The default value of innerWindow is 1

outerWindow: number of links after the first page / before the last page.

Suppose that this is set to 2 and there are 20 pages in total. Then the left outerWindow will consist of pages 1, 2, 3 and the right outerWindow will consist of pages 18, 19, 20.

The default value of outerWindow is 2

prevLabel: text for previous page, default is &laquo;

nextLabel: text for next page, default is &raquo;

search: search or not?

total: total records for pagination

displayMsg: text for pagation information

searchMsg: text for search information

recordName: record name showed in pagination information

linkSize: font size of page links

alignment: the alignment of pagination links

API

class flaskext.ypaginate.Pagination(found=0, **kwargs)

A simple pagination extension for flask

info

get the pagination information

get all the pagination links

Fork me on GitHub