diff --git a/docs/themes.rst b/docs/themes.rst index 664b4466..19fd9274 100644 --- a/docs/themes.rst +++ b/docs/themes.rst @@ -68,6 +68,19 @@ categories A list of (category, articles) tuples, containing pages The list of pages ============= =================================================== +Sorting +------- + +URL wrappers (currently categories, tags, and authors), have +comparison methods that allow them to be easily sorted by name: + + {% for tag, articles in tags|sort %} + +If you want to sort based on different criteria, `Jinja's sort +command`__ has a number of options. + +__ http://jinja.pocoo.org/docs/templates/#sort + index.html ---------- diff --git a/pelican/contents.py b/pelican/contents.py index 0dc0f0e9..5bde3c0a 100644 --- a/pelican/contents.py +++ b/pelican/contents.py @@ -8,6 +8,7 @@ import logging import functools import os import re +import sys from datetime import datetime from sys import platform, stdin @@ -90,7 +91,10 @@ class Page(object): self.date_format = settings['DEFAULT_DATE_FORMAT'] if isinstance(self.date_format, tuple): - locale.setlocale(locale.LC_ALL, self.date_format[0]) + locale_string = self.date_format[0] + if sys.version_info < (3, ) and isinstance(locale_string, six.text_type): + locale_string = locale_string.encode('ascii') + locale.setlocale(locale.LC_ALL, locale_string) self.date_format = self.date_format[1] if hasattr(self, 'date'): @@ -250,7 +254,9 @@ class Article(Page): class Quote(Page): base_properties = ('author', 'date') + @python_2_unicode_compatible +@functools.total_ordering class URLWrapper(object): def __init__(self, name, settings): self.name = name @@ -263,8 +269,20 @@ class URLWrapper(object): def __hash__(self): return hash(self.name) + def _key(self): + return self.name + + def _normalize_key(self, key): + return six.text_type(key) + def __eq__(self, other): - return self.name == other + return self._key() == self._normalize_key(other) + + def __ne__(self, other): + return self._key() != self._normalize_key(other) + + def __lt__(self, other): + return self._key() < self._normalize_key(other) def __str__(self): return self.name diff --git a/pelican/generators.py b/pelican/generators.py index 01d9fc9b..dda8c431 100644 --- a/pelican/generators.py +++ b/pelican/generators.py @@ -416,11 +416,10 @@ class ArticlesGenerator(Generator): # order the categories per name self.categories = list(self.categories.items()) self.categories.sort( - key=lambda item: item[0].name, reverse=self.settings['REVERSE_CATEGORY_ORDER']) self.authors = list(self.authors.items()) - self.authors.sort(key=lambda item: item[0].name) + self.authors.sort() self._update_context(('articles', 'dates', 'tags', 'categories', 'tag_cloud', 'authors', 'related_posts')) diff --git a/tests/test_contents.py b/tests/test_contents.py index 3f3d858c..9bb77ec3 100644 --- a/tests/test_contents.py +++ b/tests/test_contents.py @@ -1,8 +1,9 @@ # -*- coding: utf-8 -*- +from __future__ import unicode_literals from .support import unittest -from pelican.contents import Page, Article +from pelican.contents import Page, Article, URLWrapper from pelican.settings import _DEFAULT_CONFIG from pelican.utils import truncate_html_words from pelican.signals import content_object_init @@ -197,3 +198,31 @@ class TestArticle(TestPage): article_kwargs['metadata']['template'] = 'custom' custom_article = Article(**article_kwargs) self.assertEqual('custom', custom_article.template) + + +class TestURLWrapper(unittest.TestCase): + def test_comparisons(self): + """URLWrappers are sorted by name + """ + wrapper_a = URLWrapper(name='first', settings={}) + wrapper_b = URLWrapper(name='last', settings={}) + self.assertFalse(wrapper_a > wrapper_b) + self.assertFalse(wrapper_a >= wrapper_b) + self.assertFalse(wrapper_a == wrapper_b) + self.assertTrue(wrapper_a != wrapper_b) + self.assertTrue(wrapper_a <= wrapper_b) + self.assertTrue(wrapper_a < wrapper_b) + wrapper_b.name = 'first' + self.assertFalse(wrapper_a > wrapper_b) + self.assertTrue(wrapper_a >= wrapper_b) + self.assertTrue(wrapper_a == wrapper_b) + self.assertFalse(wrapper_a != wrapper_b) + self.assertTrue(wrapper_a <= wrapper_b) + self.assertFalse(wrapper_a < wrapper_b) + wrapper_a.name = 'last' + self.assertTrue(wrapper_a > wrapper_b) + self.assertTrue(wrapper_a >= wrapper_b) + self.assertFalse(wrapper_a == wrapper_b) + self.assertTrue(wrapper_a != wrapper_b) + self.assertFalse(wrapper_a <= wrapper_b) + self.assertFalse(wrapper_a < wrapper_b)