From fe76f20f0c4cdd880ca82aa868bb76d43500c237 Mon Sep 17 00:00:00 2001 From: str4d <str4d@mail.i2p> Date: Fri, 14 Dec 2012 06:26:21 +0000 Subject: [PATCH] Implemented pagination for meetings and blog entries --- i2p2www/__init__.py | 41 +++++++++++++++++++++++++------ i2p2www/helpers.py | 32 ++++++++++++++++++++++++ i2p2www/pages/blog/index.html | 2 ++ i2p2www/pages/global/macros | 26 ++++++++++++++++++++ i2p2www/pages/meetings/index.html | 2 ++ 5 files changed, 96 insertions(+), 7 deletions(-) create mode 100644 i2p2www/helpers.py diff --git a/i2p2www/__init__.py b/i2p2www/__init__.py index 74f924fbd..c8d98b11d 100644 --- a/i2p2www/__init__.py +++ b/i2p2www/__init__.py @@ -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): diff --git a/i2p2www/helpers.py b/i2p2www/helpers.py new file mode 100644 index 000000000..bbd8a6563 --- /dev/null +++ b/i2p2www/helpers.py @@ -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 diff --git a/i2p2www/pages/blog/index.html b/i2p2www/pages/blog/index.html index 2b8d7d056..06e997521 100644 --- a/i2p2www/pages/blog/index.html +++ b/i2p2www/pages/blog/index.html @@ -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 %} diff --git a/i2p2www/pages/global/macros b/i2p2www/pages/global/macros index 8fd460a68..a1470155a 100644 --- a/i2p2www/pages/global/macros +++ b/i2p2www/pages/global/macros @@ -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) + }}">« 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 »</a> + {%- endif %} + </div> +{%- endmacro -%} diff --git a/i2p2www/pages/meetings/index.html b/i2p2www/pages/meetings/index.html index 0046b71bb..8ca967923 100644 --- a/i2p2www/pages/meetings/index.html +++ b/i2p2www/pages/meetings/index.html @@ -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 %} -- GitLab