diff --git a/docs/settings.rst b/docs/settings.rst index b93c8c11..69e2adc8 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -121,6 +121,12 @@ Setting name (default value) what does it do? use the default language. `PAGE_LANG_SAVE_AS` ('pages/{slug}-{lang}.html') The location we will save the page which doesn't use the default language. +`AUTHOR_URL` ('author/{name}.html') The URL to use for an author. +`AUTHOR_SAVE_AS` ('author/{name}.html') The location to save an author. +`CATEGORY_URL` ('category/{name}.html') The URL to use for a category. +`CATEGORY_SAVE_AS` ('category/{name}.html') The location to save a category. +`TAG_URL` ('tag/{name}.html') The URL to use for a tag. +`TAG_SAVE_AS` ('tag/{name}.html') The location to save the tag page. ================================================ ===================================================== Timezone diff --git a/pelican/contents.py b/pelican/contents.py index bc42d41e..316a0e56 100644 --- a/pelican/contents.py +++ b/pelican/contents.py @@ -38,9 +38,9 @@ class Page(object): # default author to the one in settings if not defined if not hasattr(self, 'author'): if 'AUTHOR' in settings: - self.author = Author(settings['AUTHOR']) + self.author = Author(settings['AUTHOR'], settings) else: - self.author = Author(getenv('USER', 'John Doe')) + self.author = Author(getenv('USER', 'John Doe'), settings) warning(u"Author of `{0}' unknow, assuming that his name is `{1}'".format(filename or self.title, self.author)) # manage languages @@ -159,8 +159,9 @@ class Quote(Page): base_properties = ('author', 'date') class URLWrapper(object): - def __init__(self, name): + def __init__(self, name, settings): self.name = unicode(name) + self.settings = settings def __hash__(self): return hash(self.name) @@ -181,20 +182,32 @@ class URLWrapper(object): class Category(URLWrapper): @property def url(self): - return 'category/%s.html' % self + return self.settings.get('CATEGORY_URL', 'category/{name}.html').format(name=self.name) + + @property + def save_as(self): + return self.settings.get('CATEGORY_SAVE_AS', 'category/{name}.html').format(name=self.name) class Tag(URLWrapper): - def __init__(self, name): - self.name = unicode.strip(name) + def __init__(self, name, *args, **kwargs): + super(Tag, self).__init__(unicode.strip(name), *args, **kwargs) @property def url(self): - return 'tag/%s.html' % self + return self.settings.get('TAG_URL', 'tag/{name}.html').format(name=self.name) + + @property + def save_as(self): + return self.settings.get('TAG_SAVE_AS', 'tag/{name}.html').format(name=self.name) class Author(URLWrapper): @property def url(self): - return 'author/%s.html' % self + return self.settings.get('AUTHOR_URL', 'author/{name}.html').format(name=self.name) + + @property + def save_as(self): + return self.settings.get('AUTHOR_SAVE_AS', 'author/{name}.html').format(name=self.name) def is_valid_content(content, f): try: diff --git a/pelican/generators.py b/pelican/generators.py index 7ad3d276..38bfb5b8 100644 --- a/pelican/generators.py +++ b/pelican/generators.py @@ -179,7 +179,7 @@ class ArticlesGenerator(Generator): for tag, articles in self.tags.items(): articles.sort(key=attrgetter('date'), reverse=True) dates = [article for article in self.dates if article in articles] - write(tag.url, tag_template, self.context, tag=tag, + write(tag.save_as, tag_template, self.context, tag=tag, articles=articles, dates=dates, paginated={'articles': articles, 'dates': dates}, page_name='tag/%s' % tag) @@ -187,7 +187,7 @@ class ArticlesGenerator(Generator): category_template = self.get_template('category') for cat, articles in self.categories: dates = [article for article in self.dates if article in articles] - write(cat.url, category_template, self.context, + write(cat.save_as, category_template, self.context, category=cat, articles=articles, dates=dates, paginated={'articles': articles, 'dates': dates}, page_name='category/%s' % cat) @@ -195,7 +195,7 @@ class ArticlesGenerator(Generator): author_template = self.get_template('author') for aut, articles in self.authors: dates = [article for article in self.dates if article in articles] - write(aut.url, author_template, self.context, + write(aut.save_as, author_template, self.context, author=aut, articles=articles, dates=dates, paginated={'articles': articles, 'dates': dates}, page_name='author/%s' % aut) @@ -228,7 +228,7 @@ class ArticlesGenerator(Generator): category = os.path.basename(os.path.dirname(f)).decode('utf-8') if category != '': - metadata['category'] = Category(category) + metadata['category'] = Category(category, self.settings) if 'date' not in metadata.keys()\ and self.settings['FALLBACK_ON_FS_DATE']: diff --git a/pelican/readers.py b/pelican/readers.py index e760b662..814f81d2 100644 --- a/pelican/readers.py +++ b/pelican/readers.py @@ -15,28 +15,30 @@ except ImportError: Markdown = False import re -from pelican.contents import Category, Tag, Author +from pelican.contents import Category, Tag, Author, URLWrapper from pelican.utils import get_date, open _METADATA_PROCESSORS = { - 'tags': lambda x: map(Tag, unicode(x).split(',')), - 'date': lambda x: get_date(x), - 'status': unicode.strip, + 'tags': lambda x, y: [Tag(tag, y) for tag in unicode(x).split(',')], + 'date': lambda x, y: get_date(x), + 'status': lambda x,y: unicode.strip(x), 'category': Category, 'author': Author, } -def _process_metadata(name, value): - if name.lower() in _METADATA_PROCESSORS: - return _METADATA_PROCESSORS[name.lower()](value) - return value - - class Reader(object): enabled = True extensions = None + def __init__(self, settings): + self.settings = settings + + def process_metadata(self, name, value): + if name.lower() in _METADATA_PROCESSORS: + return _METADATA_PROCESSORS[name.lower()](value, self.settings) + return value + class _FieldBodyTranslator(HTMLTranslator): def astext(self): @@ -54,29 +56,25 @@ def render_node_to_html(document, node): node.walkabout(visitor) return visitor.astext() -def get_metadata(document): - """Return the dict containing document metadata""" - output = {} - for docinfo in document.traverse(docutils.nodes.docinfo): - for element in docinfo.children: - if element.tagname == 'field': # custom fields (e.g. summary) - name_elem, body_elem = element.children - name = name_elem.astext() - value = render_node_to_html(document, body_elem) - else: # standard fields (e.g. address) - name = element.tagname - value = element.astext() - - output[name] = _process_metadata(name, value) - return output - - class RstReader(Reader): enabled = bool(docutils) extension = "rst" def _parse_metadata(self, document): - return get_metadata(document) + """Return the dict containing document metadata""" + output = {} + for docinfo in document.traverse(docutils.nodes.docinfo): + for element in docinfo.children: + if element.tagname == 'field': # custom fields (e.g. summary) + name_elem, body_elem = element.children + name = name_elem.astext() + value = render_node_to_html(document, body_elem) + else: # standard fields (e.g. address) + name = element.tagname + value = element.astext() + + output[name] = self.process_metadata(name, value) + return output def _get_publisher(self, filename): extra_params = {'initial_header_level': '2'} @@ -113,7 +111,7 @@ class MarkdownReader(Reader): metadata = {} for name, value in md.Meta.items(): name = name.lower() - metadata[name] = _process_metadata(name, value[0]) + metadata[name] = self.process_metadata(name, value[0]) return content, metadata @@ -129,7 +127,7 @@ class HtmlReader(Reader): key = i.split(':')[0][5:].strip() value = i.split(':')[-1][:-3].strip() name = key.lower() - metadata[name] = _process_metadata(name, value) + metadata[name] = self.process_metadata(name, value) return content, metadata @@ -143,7 +141,7 @@ def read_file(filename, fmt=None, settings=None): fmt = filename.split('.')[-1] if fmt not in _EXTENSIONS.keys(): raise TypeError('Pelican does not know how to parse %s' % filename) - reader = _EXTENSIONS[fmt]() + reader = _EXTENSIONS[fmt](settings) settings_key = '%s_EXTENSIONS' % fmt.upper() if settings and settings_key in settings: reader.extensions = settings[settings_key]