Skip to content

Instantly share code, notes, and snippets.

@danielrichman
Last active December 29, 2015 10:34
Show Gist options
  • Save danielrichman/5876099 to your computer and use it in GitHub Desktop.
Save danielrichman/5876099 to your computer and use it in GitHub Desktop.
flask & bootstrap pagination li width and phone/tablet/desktop page show sizes are suitable for up to 3 digit page numbers
@app.template_global('show_which_pages')
def show_which_pages(page, pages, show=5):
"""
Work out which page numbers to display
Pages are numbered 1 to pages, inclusive.
page: the current page
pages: the total number of pages.
show: maximum number of pages to show
show must be odd.
"""
assert show % 2 == 1
if pages < show:
return range(1, pages + 1)
elif page <= (show // 2):
return range(1, show + 1)
elif page > pages - (show // 2):
return range(pages - show + 1, pages + 1)
else:
return range(page - (show // 2), page + (show // 2) + 1)
@app.template_global('show_which_pages_responsive')
def show_which_pages_responsive(page, pages, phone=5, tablet=7, desktop=11):
"""
Run show_which_pages for multiple show sizes
For each type (phone, tablet, desktop) calls
show_which_pages(page, pages, type).
It then takes the unions of all the page numbers returned, and builds
(and returns) a list of (page_number, class) tuples,
where class is 'hidden-tablet' or 'hidden-phone hidden-tablet' as
appropriate.
Need phone <= tablet <= desktop.
"""
if not phone <= tablet <= desktop:
raise ValueError("Need phone <= tablet <= desktop")
all_pages = show_which_pages(page, pages, desktop)
tablet_pages = set(show_which_pages(page, pages, tablet))
phone_pages = set(show_which_pages(page, pages, phone))
# phone_pages < tablet_pages < all_pages
assert tablet_pages - set(all_pages) == set()
assert phone_pages - tablet_pages == set()
def page_class(page):
if page in phone_pages:
return ''
elif page in tablet_pages:
return 'hidden-phone'
else:
return 'hidden-phone hidden-tablet'
return [(page, page_class(page)) for page in all_pages]
.pagination .page_number {
width: 25px;
}
{% macro pagination(page, pages) %}
<div class="pagination pagination-centered">
<ul>
{% if page != 1 %}
<li><a href="{{ url_for(request.endpoint, page=1) }}">&laquo;<span class="hidden-phone"> Oldest</span></a></li>
<li><a href="{{ url_for(request.endpoint, page=page - 1) }}">&lsaquo;<span class="hidden-phone"> Older</span></a></li>
{% else %}
<li class="disabled"><span>&laquo;<span class="hidden-phone"> Oldest</span></span></li>
<li class="disabled"><span>&lsaquo;<span class="hidden-phone"> Older</span></span></li>
{% endif %}
{% for n, hide in show_which_pages_responsive(page, pages) %}
{% if n == page %}
<li class="active {{ hide }}"><span class="page_number">{{ n }}</span></li>
{% else %}
<li class="{{ hide }}"><a class="page_number" href="{{ url_for(request.endpoint, page=n) }}">{{ n }}</a></li>
{% endif %}
{% endfor %}
{% if page != pages %}
<li><a href="{{ url_for(request.endpoint, page=page + 1) }}"><span class="hidden-phone">Newer </span>&rsaquo;</a></li>
<li><a href="{{ url_for(request.endpoint, page=pages) }}"><span class="hidden-phone">Newest </span>&raquo;</a></li>
{% else %}
<li class="disabled"><span><span class="hidden-phone">Newer </span>&rsaquo;</span></li>
<li class="disabled"><span><span class="hidden-phone">Newest </span>&raquo;</span></li>
{% endif %}
</ul>
</div>
{% endmacro %}
{% extends "base.html" %}
{% from "pagination.html" import pagination %}
{% set page_title = "Things" %}
{% block content %}
<div class="row">
<div class="span12">
{{ pagination(page, pages) }}
<table class="table table-hover table-bordered table-condensed" id="things">
<thead>
<th>A</th>
<th>B</th>
<th>C</th>
<th>D</th>
</thead>
<tbody>
{% for thing in things %}
<tr>
<td>{{ thing.a }}</td>
<td>{{ thing.b }}</td>
<td>{{ thing.c }}</td>
<td>{{ thing.d }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% if things|length > 20 %}
{{ pagination(page, pages) }}
{% endif %}
</div>
</div>
{% endblock %}
@app.route("/things")
@app.route("/things/<int:page>")
def things(page=None):
page_size = 100
count = things_count()
if count == 0:
if page is not None:
abort(404)
else:
return render_template("things_empty.html")
pages = count / page_size
if count % page_size:
pages += 1
if page is None:
# default to last page
return redirect(url_for(request.endpoint, page=pages))
# default to first page
return redirect(url_for(request.endpoint, page=1))
if page > pages or page < 1:
abort(404)
offset = (page - 1) * page_size
things = get_things(offset, page_size) # (offset, limit)
return render_template("things.html",
things=things, pages=pages, page=page)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment