forked from github/pelican
Support configurable URL's & SAVE_AS path for Author, Category and Tag
This commit is contained in:
parent
a39787c1a2
commit
44cf2ad400
4 changed files with 60 additions and 43 deletions
|
|
@ -121,6 +121,12 @@ Setting name (default value) what does it do?
|
||||||
use the default language.
|
use the default language.
|
||||||
`PAGE_LANG_SAVE_AS` ('pages/{slug}-{lang}.html') The location we will save the page which doesn't
|
`PAGE_LANG_SAVE_AS` ('pages/{slug}-{lang}.html') The location we will save the page which doesn't
|
||||||
use the default language.
|
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
|
Timezone
|
||||||
|
|
|
||||||
|
|
@ -38,9 +38,9 @@ class Page(object):
|
||||||
# default author to the one in settings if not defined
|
# default author to the one in settings if not defined
|
||||||
if not hasattr(self, 'author'):
|
if not hasattr(self, 'author'):
|
||||||
if 'AUTHOR' in settings:
|
if 'AUTHOR' in settings:
|
||||||
self.author = Author(settings['AUTHOR'])
|
self.author = Author(settings['AUTHOR'], settings)
|
||||||
else:
|
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))
|
warning(u"Author of `{0}' unknow, assuming that his name is `{1}'".format(filename or self.title, self.author))
|
||||||
|
|
||||||
# manage languages
|
# manage languages
|
||||||
|
|
@ -159,8 +159,9 @@ class Quote(Page):
|
||||||
base_properties = ('author', 'date')
|
base_properties = ('author', 'date')
|
||||||
|
|
||||||
class URLWrapper(object):
|
class URLWrapper(object):
|
||||||
def __init__(self, name):
|
def __init__(self, name, settings):
|
||||||
self.name = unicode(name)
|
self.name = unicode(name)
|
||||||
|
self.settings = settings
|
||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return hash(self.name)
|
return hash(self.name)
|
||||||
|
|
@ -181,20 +182,32 @@ class URLWrapper(object):
|
||||||
class Category(URLWrapper):
|
class Category(URLWrapper):
|
||||||
@property
|
@property
|
||||||
def url(self):
|
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):
|
class Tag(URLWrapper):
|
||||||
def __init__(self, name):
|
def __init__(self, name, *args, **kwargs):
|
||||||
self.name = unicode.strip(name)
|
super(Tag, self).__init__(unicode.strip(name), *args, **kwargs)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def url(self):
|
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):
|
class Author(URLWrapper):
|
||||||
@property
|
@property
|
||||||
def url(self):
|
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):
|
def is_valid_content(content, f):
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,7 @@ class ArticlesGenerator(Generator):
|
||||||
for tag, articles in self.tags.items():
|
for tag, articles in self.tags.items():
|
||||||
articles.sort(key=attrgetter('date'), reverse=True)
|
articles.sort(key=attrgetter('date'), reverse=True)
|
||||||
dates = [article for article in self.dates if article in articles]
|
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,
|
articles=articles, dates=dates,
|
||||||
paginated={'articles': articles, 'dates': dates},
|
paginated={'articles': articles, 'dates': dates},
|
||||||
page_name='tag/%s' % tag)
|
page_name='tag/%s' % tag)
|
||||||
|
|
@ -187,7 +187,7 @@ class ArticlesGenerator(Generator):
|
||||||
category_template = self.get_template('category')
|
category_template = self.get_template('category')
|
||||||
for cat, articles in self.categories:
|
for cat, articles in self.categories:
|
||||||
dates = [article for article in self.dates if article in articles]
|
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,
|
category=cat, articles=articles, dates=dates,
|
||||||
paginated={'articles': articles, 'dates': dates},
|
paginated={'articles': articles, 'dates': dates},
|
||||||
page_name='category/%s' % cat)
|
page_name='category/%s' % cat)
|
||||||
|
|
@ -195,7 +195,7 @@ class ArticlesGenerator(Generator):
|
||||||
author_template = self.get_template('author')
|
author_template = self.get_template('author')
|
||||||
for aut, articles in self.authors:
|
for aut, articles in self.authors:
|
||||||
dates = [article for article in self.dates if article in articles]
|
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,
|
author=aut, articles=articles, dates=dates,
|
||||||
paginated={'articles': articles, 'dates': dates},
|
paginated={'articles': articles, 'dates': dates},
|
||||||
page_name='author/%s' % aut)
|
page_name='author/%s' % aut)
|
||||||
|
|
@ -228,7 +228,7 @@ class ArticlesGenerator(Generator):
|
||||||
category = os.path.basename(os.path.dirname(f)).decode('utf-8')
|
category = os.path.basename(os.path.dirname(f)).decode('utf-8')
|
||||||
|
|
||||||
if category != '':
|
if category != '':
|
||||||
metadata['category'] = Category(category)
|
metadata['category'] = Category(category, self.settings)
|
||||||
|
|
||||||
if 'date' not in metadata.keys()\
|
if 'date' not in metadata.keys()\
|
||||||
and self.settings['FALLBACK_ON_FS_DATE']:
|
and self.settings['FALLBACK_ON_FS_DATE']:
|
||||||
|
|
|
||||||
|
|
@ -15,28 +15,30 @@ except ImportError:
|
||||||
Markdown = False
|
Markdown = False
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from pelican.contents import Category, Tag, Author
|
from pelican.contents import Category, Tag, Author, URLWrapper
|
||||||
from pelican.utils import get_date, open
|
from pelican.utils import get_date, open
|
||||||
|
|
||||||
|
|
||||||
_METADATA_PROCESSORS = {
|
_METADATA_PROCESSORS = {
|
||||||
'tags': lambda x: map(Tag, unicode(x).split(',')),
|
'tags': lambda x, y: [Tag(tag, y) for tag in unicode(x).split(',')],
|
||||||
'date': lambda x: get_date(x),
|
'date': lambda x, y: get_date(x),
|
||||||
'status': unicode.strip,
|
'status': lambda x,y: unicode.strip(x),
|
||||||
'category': Category,
|
'category': Category,
|
||||||
'author': Author,
|
'author': Author,
|
||||||
}
|
}
|
||||||
|
|
||||||
def _process_metadata(name, value):
|
|
||||||
if name.lower() in _METADATA_PROCESSORS:
|
|
||||||
return _METADATA_PROCESSORS[name.lower()](value)
|
|
||||||
return value
|
|
||||||
|
|
||||||
|
|
||||||
class Reader(object):
|
class Reader(object):
|
||||||
enabled = True
|
enabled = True
|
||||||
extensions = None
|
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):
|
class _FieldBodyTranslator(HTMLTranslator):
|
||||||
|
|
||||||
def astext(self):
|
def astext(self):
|
||||||
|
|
@ -54,29 +56,25 @@ def render_node_to_html(document, node):
|
||||||
node.walkabout(visitor)
|
node.walkabout(visitor)
|
||||||
return visitor.astext()
|
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):
|
class RstReader(Reader):
|
||||||
enabled = bool(docutils)
|
enabled = bool(docutils)
|
||||||
extension = "rst"
|
extension = "rst"
|
||||||
|
|
||||||
def _parse_metadata(self, document):
|
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):
|
def _get_publisher(self, filename):
|
||||||
extra_params = {'initial_header_level': '2'}
|
extra_params = {'initial_header_level': '2'}
|
||||||
|
|
@ -113,7 +111,7 @@ class MarkdownReader(Reader):
|
||||||
metadata = {}
|
metadata = {}
|
||||||
for name, value in md.Meta.items():
|
for name, value in md.Meta.items():
|
||||||
name = name.lower()
|
name = name.lower()
|
||||||
metadata[name] = _process_metadata(name, value[0])
|
metadata[name] = self.process_metadata(name, value[0])
|
||||||
return content, metadata
|
return content, metadata
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -129,7 +127,7 @@ class HtmlReader(Reader):
|
||||||
key = i.split(':')[0][5:].strip()
|
key = i.split(':')[0][5:].strip()
|
||||||
value = i.split(':')[-1][:-3].strip()
|
value = i.split(':')[-1][:-3].strip()
|
||||||
name = key.lower()
|
name = key.lower()
|
||||||
metadata[name] = _process_metadata(name, value)
|
metadata[name] = self.process_metadata(name, value)
|
||||||
|
|
||||||
return content, metadata
|
return content, metadata
|
||||||
|
|
||||||
|
|
@ -143,7 +141,7 @@ def read_file(filename, fmt=None, settings=None):
|
||||||
fmt = filename.split('.')[-1]
|
fmt = filename.split('.')[-1]
|
||||||
if fmt not in _EXTENSIONS.keys():
|
if fmt not in _EXTENSIONS.keys():
|
||||||
raise TypeError('Pelican does not know how to parse %s' % filename)
|
raise TypeError('Pelican does not know how to parse %s' % filename)
|
||||||
reader = _EXTENSIONS[fmt]()
|
reader = _EXTENSIONS[fmt](settings)
|
||||||
settings_key = '%s_EXTENSIONS' % fmt.upper()
|
settings_key = '%s_EXTENSIONS' % fmt.upper()
|
||||||
if settings and settings_key in settings:
|
if settings and settings_key in settings:
|
||||||
reader.extensions = settings[settings_key]
|
reader.extensions = settings[settings_key]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue