Implemented pagination for meetings and blog entries

This commit is contained in:
str4d
2012-12-14 06:26:21 +00:00
parent 3f19792df7
commit fe76f20f0c
5 changed files with 96 additions and 7 deletions

View File

@ -14,6 +14,7 @@ try:
except ImportError:
import simplejson as json
from helpers import Pagination
TEMPLATE_DIR = os.path.join(os.path.dirname(__file__), 'pages')
STATIC_DIR = os.path.join(os.path.dirname(__file__), 'static')
@ -21,6 +22,9 @@ STATIC_DIR = os.path.join(os.path.dirname(__file__), 'static')
BLOG_DIR = os.path.join(os.path.dirname(__file__), 'blog')
MEETINGS_DIR = os.path.join(os.path.dirname(__file__), 'meetings')
BLOG_ENTRIES_PER_PAGE = 20
MEETINGS_PER_PAGE = 20
MIRRORS_FILE = os.path.join(TEMPLATE_DIR, 'downloads/mirrors')
app = application = Flask('i2p2www', template_folder=TEMPLATE_DIR, static_url_path='/_static', static_folder=STATIC_DIR)
@ -141,7 +145,15 @@ def utility_processor():
except KeyError:
# The I2P site has no known clearnet address, so use an inproxy
return value + '.to'
return dict(i2pconv=convert_url_to_clearnet)
# Convert a paginated URL to that of another page
def url_for_other_page(page):
args = request.view_args.copy()
args['page'] = page
return url_for(request.endpoint, **args)
return dict(i2pconv=convert_url_to_clearnet,
url_for_other_page=url_for_other_page)
################
@ -156,6 +168,15 @@ def server_error(error):
return render_template('global/error_500.html'), 500
########################
# General helper methods
def get_for_page(items, page, per_page):
from_item = (page-1)*per_page
to_item = page*per_page
return items[from_item:to_item]
#######################
# General page handlers
@ -267,9 +288,12 @@ def render_meeting_rst(id):
@app.route('/<string:lang>/meetings/', defaults={'page': 1})
@app.route('/<string:lang>/meetings/page/<int:page>')
def meetings_index(page):
meetings = get_meetings()
return render_template('meetings/index.html', meetings=meetings)
all_meetings = get_meetings()
meetings = get_for_page(all_meetings, page, MEETINGS_PER_PAGE)
if not meetings and page != 1:
abort(404)
pagination = Pagination(page, MEETINGS_PER_PAGE, len(all_meetings))
return render_template('meetings/index.html', pagination=pagination, meetings=meetings)
# Renderer for specific meetings
@app.route('/<string:lang>/meetings/<int:id>')
@ -476,9 +500,12 @@ def render_blog_entry(slug):
@app.route('/<string:lang>/blog/', defaults={'page': 1})
@app.route('/<string:lang>/blog/page/<int:page>')
def blog_index(page):
entries = get_blog_entries()
return render_template('blog/index.html', entries=entries)
all_entries = get_blog_entries()
entries = get_for_page(all_entries, page, BLOG_ENTRIES_PER_PAGE)
if not entries and page != 1:
abort(404)
pagination = Pagination(page, BLOG_ENTRIES_PER_PAGE, len(all_entries))
return render_template('blog/index.html', pagination=pagination, entries=entries)
@app.route('/<string:lang>/blog/entry/<path:slug>')
def blog_entry(slug):

32
i2p2www/helpers.py Normal file
View File

@ -0,0 +1,32 @@
from math import ceil
class Pagination(object):
def __init__(self, page, per_page, total_count):
self.page = page
self.per_page = per_page
self.total_count = total_count
@property
def pages(self):
return int(ceil(self.total_count / float(self.per_page)))
@property
def has_prev(self):
return self.page > 1
@property
def has_next(self):
return self.page < self.pages
def iter_pages(self, left_edge=2, left_current=2,
right_current=5, right_edge=2):
last = 0
for num in xrange(1, self.pages + 1):
if num <= left_edge or \
(num > self.page - left_current - 1 and \
num < self.page + right_current) or \
num > self.pages - right_edge:
if last + 1 != num:
yield None
yield num
last = num

View File

@ -10,4 +10,6 @@
<li>{{ entry[1] }} - <a href="{{ url_for('blog_entry', slug=entry[0]) }}">{{ entry[2] }}</a></li>
{%- endfor %}
</ul>
{%- from "global/macros" import render_pagination with context -%}
{{ render_pagination(pagination) | safe }}
{% endblock %}

View File

@ -3,6 +3,7 @@
{%- else -%}{{ url_for('site_show', lang=g.lang) }}
{%- endif -%}
{%- endmacro -%}
{%- macro change_lang(lang) -%}
{%- if request.endpoint == 'site_show' -%}{{ url_for('site_show', lang=lang, page=page) }}
{%- elif request.endpoint == 'blog_entry' -%}{{ url_for('blog_entry', lang=lang, slug=slug) }}
@ -12,8 +13,33 @@
{%- else -%}{{ url_for('site_show', lang=lang) }}
{%- endif -%}
{%- endmacro -%}
{%- macro ver(string=None) -%}
{%- if string -%}{{ string % '0.9.3' }}
{%- else -%}{{ '0.9.3' }}
{%- endif -%}
{%- endmacro -%}
{%- macro render_pagination(pagination) %}
<div class="pagination">
{%- if pagination.has_prev %}
<a href="{{ url_for_other_page(pagination.page - 1)
}}">&laquo; Previous</a>
{%- endif %}
{%- for page in pagination.iter_pages() %}
{%- if page %}
{%- if page != pagination.page %}
<a href="{{ url_for_other_page(page) }}">{{ page }}</a>
{%- else %}
<strong>{{ page }}</strong>
{%- endif %}
{%- else %}
<span class="ellipsis">…</span>
{%- endif %}
{%- endfor %}
{%- if pagination.has_next %}
<a href="{{ url_for_other_page(pagination.page + 1)
}}">Next &raquo;</a>
{%- endif %}
</div>
{%- endmacro -%}

View File

@ -15,4 +15,6 @@
<li><a href="{{ meeting_url(meeting['id']) }}">Meeting {{ meeting['id'] }}</a>{% if meeting['date'] %} - {{ meeting['date'].strftime("%B %d, %Y") }}{% endif %}</li>
{%- endfor %}
</ul>
{%- from "global/macros" import render_pagination with context -%}
{{ render_pagination(pagination) | safe }}
{% endblock %}