From dceea3aabe36e206d014e2540f86572dcb7c8859 Mon Sep 17 00:00:00 2001 From: Deniz Turgut Date: Thu, 16 Apr 2015 19:16:23 -0400 Subject: [PATCH] Change URLWrapper.slug to a property Main goal is to delay `slugify` call until `slug` is needed. `slugify` can be expensive depending on the input string (see #1172). Changing it to a property gives plugins time to place custom `slug`s before `name` is unnecessarily slugified. With this change, default behavior is same except the time slugification happens. But if you set custom slug, `slugify` won't be used at all. So, this is a partial solution to #1172. The rest, setting a custom slug, would best be handled by a plugin. --- pelican/urlwrappers.py | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/pelican/urlwrappers.py b/pelican/urlwrappers.py index 06cfa2ab..60bc6a3a 100644 --- a/pelican/urlwrappers.py +++ b/pelican/urlwrappers.py @@ -13,12 +13,10 @@ logger = logging.getLogger(__name__) @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.settings = settings self._name = name - self.slug = slugify(name, self.settings.get('SLUG_SUBSTITUTIONS', ())) - self.name = name + self._slug = None + self._slug_from_name = True @property def name(self): @@ -27,11 +25,28 @@ class URLWrapper(object): @name.setter def name(self, name): self._name = name - self.slug = slugify(name, self.settings.get('SLUG_SUBSTITUTIONS', ())) + # if slug wasn't explicitly set, it needs to be regenerated from name + # so, changing name should reset slug for slugification + if self._slug_from_name: + self._slug = None + + @property + def slug(self): + if self._slug is None: + self._slug = slugify(self.name, + self.settings.get('SLUG_SUBSTITUTIONS', ())) + return self._slug + + @slug.setter + def slug(self, slug): + # if slug is expliticly set, changing name won't alter slug + self._slug_from_name = False + self._slug = slug def as_dict(self): d = self.__dict__ d['name'] = self.name + d['slug'] = self.slug return d def __hash__(self):