pelican/pelican/urlwrappers.py
Rogdham 91337940d3 Make tags and cats case insensitive. Fixes #704.
More precisely, group tags or categories without considering the case.
This fixes the bug where two categories with just the case as difference were
considered as distinct, but generate the same file: one overwriting the other.

Thanks to @Avaris for helping with the tests.
2013-05-03 17:37:45 +01:00

96 lines
2.5 KiB
Python

import os
import functools
import logging
import six
from pelican.utils import (slugify, python_2_unicode_compatible)
logger = logging.getLogger(__name__)
@python_2_unicode_compatible
@functools.total_ordering
class URLWrapper(object):
def __init__(self, name, settings):
# next 2 lines are redundant with the setter of the name property
# but are here for clarity
self._name = name
self.slug = slugify(name)
self.name = name
self.settings = settings
@property
def name(self):
return self._name
@name.setter
def name(self, name):
self._name = name
self.slug = slugify(name)
def as_dict(self):
d = self.__dict__
d['name'] = self.name
return d
def __hash__(self):
return hash(self.slug)
def _key(self):
return self.slug
def _normalize_key(self, key):
return six.text_type(slugify(key))
def __eq__(self, 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
def __repr__(self):
return '<{} {}>'.format(type(self).__name__, str(self))
def _from_settings(self, key, get_page_name=False):
"""Returns URL information as defined in settings.
When get_page_name=True returns URL without anything after {slug} e.g.
if in settings: CATEGORY_URL="cat/{slug}.html" this returns
"cat/{slug}" Useful for pagination.
"""
setting = "%s_%s" % (self.__class__.__name__.upper(), key)
value = self.settings[setting]
if not isinstance(value, six.string_types):
logger.warning('%s is set to %s' % (setting, value))
return value
else:
if get_page_name:
return os.path.splitext(value)[0].format(**self.as_dict())
else:
return value.format(**self.as_dict())
page_name = property(functools.partial(_from_settings, key='URL',
get_page_name=True))
url = property(functools.partial(_from_settings, key='URL'))
save_as = property(functools.partial(_from_settings, key='SAVE_AS'))
class Category(URLWrapper):
pass
class Tag(URLWrapper):
def __init__(self, name, *args, **kwargs):
super(Tag, self).__init__(name.strip(), *args, **kwargs)
class Author(URLWrapper):
pass