flask-ypaginate is a simple pagination extension for flask , and it is forked from flask-paginate.
Plus points of flask-ypaginate:
On the command line, run:
$ pip install flask-ypaginate
This assumes that you have pip installed.
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%;
}
Using this mode is essentially the same as using flask-paginate.
It is the default mode, and can be explicitly stated by supplying the mode keyword argument to the Pagination constructor and giving it a value of Pagination.MODE_ORIGINAL:
pagination = Pagination()
# alternatively
pagination = Pagination(mode=Pagination.MODE_ORIGINAL)
In your flask views file (e.g. views/users.py):
from flask import Blueprint
from flask.ext.ypaginate import Pagination
mod = Blueprint('users', __name__)
@mod.route('/')
def index():
search = False
q = request.args.get('q')
if q:
search = True
try:
page = int(request.args.get('page', 1))
except ValueError:
page = 1
users = User.find(...)
pagination = Pagination(page=page, total=users.count(),
search=search, record_name='users')
return render_template('users/index.html',
users=users,
pagination=pagination,
)
In the users/index.html:
{{ pagination.info|safe }}
{{ pagination.links|safe }}
<table>
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th>Email</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<td>{{ loop.index + users.skip }}</td>
<td>{{ user.name }}</td>
<td>{{ user.email }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{{ pagination.links|safe }}
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
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')
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 «
nextLabel: text for next page, default is »
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