This commit is contained in:
Alexis Metaireau 2012-03-09 11:42:21 +01:00
commit a7cea63db6
17 changed files with 229 additions and 114 deletions

View file

@ -24,12 +24,7 @@ Basic settings
================================================ ===================================================== ================================================ =====================================================
Setting name (default value) What does it do? Setting name (default value) What does it do?
================================================ ===================================================== ================================================ =====================================================
`ARTICLE_PERMALINK_STRUCTURE` (``''``) Empty by default. Enables some customization of URL
structure (see below for more detail).
`AUTHOR` Default author (put your name) `AUTHOR` Default author (put your name)
`CLEAN_URLS` (``False``) If set to `True`, the URLs will not be suffixed by
`.html`, so you will have to setup URL rewriting on
your web server.
`DATE_FORMATS` (``{}``) If you do manage multiple languages, you can `DATE_FORMATS` (``{}``) If you do manage multiple languages, you can
set the date formatting here. See "Date format and locales" set the date formatting here. See "Date format and locales"
section below for details. section below for details.
@ -79,16 +74,14 @@ Setting name (default value) What does it do?
.. [#] Default is the system locale. .. [#] Default is the system locale.
Article permalink structure URL Settings
--------------------------- ------------
This setting allows you to output your articles sorted by date, provided that You can customize the URL's and locations where files will be saved. The URL's and
you specify a format as specified below. This format follows the Python SAVE_AS variables use python's format strings. These variables allow you to place
``datetime`` directives: your articles in a location such as '{slug}/index.html' and link to then as
'{slug}' for clean urls. These settings give you the flexibility to place your
* %Y: Year with century as a decimal number. articles and pages anywhere you want.
* %m: Month as a decimal number [01,12].
* %d: Day of the month as a decimal number [01,31].
Note: If you specify a datetime directive, it will be substituted using the Note: If you specify a datetime directive, it will be substituted using the
input files' date metadata attribute. If the date is not specified for a input files' date metadata attribute. If the date is not specified for a
@ -99,15 +92,42 @@ information.
Also, you can use other file metadata attributes as well: Also, you can use other file metadata attributes as well:
* category: '%(category)s' * slug
* author: '%(author)s' * date
* tags: '%(tags)s' * lang
* date: '%(date)s' * author
* category
Example usage: Example usage:
* '/%Y/%m/' will render something like '/2011/07/sample-post.html'. * ARTICLE_URL = 'posts/{date:%Y}/{date:%b}/{date:%d}/{slug}/'
* '/%Y/%(category)s/' will render something like '/2011/life/sample-post.html'. * ARTICLE_SAVE_AS = 'posts/{date:%Y}/{date:%b}/{date:%d}/{slug}/index.html'
This would save your articles in something like '/posts/2011/Aug/07/sample-post/index.html',
and the URL to this would be '/posts/2011/Aug/07/sample-post/'.
================================================ =====================================================
Setting name (default value) what does it do?
================================================ =====================================================
`ARTICLE_URL` ('{slug}.html') The URL to refer to an ARTICLE.
`ARTICLE_SAVE_AS` ('{slug}.html') The place where we will save an article.
`ARTICLE_LANG_URL` ('{slug}-{lang}.html') The URL to refer to an ARTICLE which doesn't use the
default language.
`ARTICLE_LANG_SAVE_AS` ('{slug}-{lang}.html' The place where we will save an article which
doesn't use the default language.
`PAGE_URL` ('pages/{slug}.html') The URL we will use to link to a page.
`PAGE_SAVE_AS` ('pages/{slug}.html') The location we will save the page.
`PAGE_LANG_URL` ('pages/{slug}-{lang}.html') The URL we will use to link to a page which doesn't
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 Timezone
-------- --------

View file

@ -1,5 +1,6 @@
import argparse import argparse
import os, sys import os, sys
import re
import time import time
from pelican.generators import (ArticlesGenerator, PagesGenerator, from pelican.generators import (ArticlesGenerator, PagesGenerator,
@ -26,6 +27,42 @@ class Pelican(object):
if self.path.endswith('/'): if self.path.endswith('/'):
self.path = self.path[:-1] self.path = self.path[:-1]
if settings.get('CLEAN_URLS', False):
log.warning('Found deprecated `CLEAN_URLS` in settings. Modifing'
' the following settings for the same behaviour.')
settings['ARTICLE_URL'] = '{slug}/'
settings['ARTICLE_LANG_URL'] = '{slug}-{lang}/'
settings['PAGE_URL'] = 'pages/{slug}/'
settings['PAGE_LANG_URL'] = 'pages/{slug}-{lang}/'
for setting in ('ARTICLE_URL', 'ARTICLE_LANG_URL', 'PAGE_URL',
'PAGE_LANG_URL'):
log.warning("%s = '%s'" % (setting, settings[setting]))
if settings.get('ARTICLE_PERMALINK_STRUCTURE', False):
log.warning('Found deprecated `ARTICLE_PERMALINK_STRUCTURE` in'
' settings. Modifing the following settings for'
' the same behaviour.')
structure = settings['ARTICLE_PERMALINK_STRUCTURE']
# Convert %(variable) into {variable}.
structure = re.sub('%\((\w+)\)s', '{\g<1>}', structure)
# Convert %x into {date:%x} for strftime
structure = re.sub('(%[A-z])', '{date:\g<1>}', structure)
# Strip a / prefix
structure = re.sub('^/', '', structure)
for setting in ('ARTICLE_URL', 'ARTICLE_LANG_URL', 'PAGE_URL',
'PAGE_LANG_URL', 'ARTICLE_SAVE_AS',
'ARTICLE_LANG_SAVE_AS', 'PAGE_SAVE_AS',
'PAGE_LANG_SAVE_AS'):
settings[setting] = os.path.join(structure, settings[setting])
log.warning("%s = '%s'" % (setting, settings[setting]))
# define the default settings # define the default settings
self.settings = settings self.settings = settings
self.theme = theme or settings['THEME'] self.theme = theme or settings['THEME']

View file

@ -24,6 +24,7 @@ class Page(object):
if not settings: if not settings:
settings = _DEFAULT_CONFIG settings = _DEFAULT_CONFIG
self.settings = settings
self._content = content self._content = content
self.translations = [] self.translations = []
@ -37,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 = settings['AUTHOR'] self.author = Author(settings['AUTHOR'], settings)
else: else:
self.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
@ -55,29 +56,6 @@ class Page(object):
if not hasattr(self, 'slug') and hasattr(self, 'title'): if not hasattr(self, 'slug') and hasattr(self, 'title'):
self.slug = slugify(self.title) self.slug = slugify(self.title)
# create save_as from the slug (+lang)
if not hasattr(self, 'save_as') and hasattr(self, 'slug'):
if self.in_default_lang:
if settings.get('CLEAN_URLS', False):
self.save_as = '%s/index.html' % self.slug
else:
self.save_as = '%s.html' % self.slug
clean_url = '%s/' % self.slug
else:
if settings.get('CLEAN_URLS', False):
self.save_as = '%s-%s/index.html' % (self.slug, self.lang)
else:
self.save_as = '%s-%s.html' % (self.slug, self.lang)
clean_url = '%s-%s/' % (self.slug, self.lang)
# change the save_as regarding the settings
if settings.get('CLEAN_URLS', False):
self.url = clean_url
elif hasattr(self, 'save_as'):
self.url = self.save_as
if filename: if filename:
self.filename = filename self.filename = filename
@ -115,6 +93,30 @@ class Page(object):
if not hasattr(self, prop): if not hasattr(self, prop):
raise NameError(prop) raise NameError(prop)
@property
def url_format(self):
return {
'slug': getattr(self, 'slug', ''),
'lang': getattr(self, 'lang', 'en'),
'date': getattr(self, 'date', datetime.datetime.now()),
'author': self.author,
'category': getattr(self, 'category', 'misc'),
}
@property
def url(self):
if self.in_default_lang:
return self.settings.get('PAGE_URL', u'pages/{slug}.html').format(**self.url_format)
return self.settings.get('PAGE_LANG_URL', u'pages/{slug}-{lang}.html').format(**self.url_format)
@property
def save_as(self):
if self.in_default_lang:
return self.settings.get('PAGE_SAVE_AS', u'pages/{slug}.html').format(**self.url_format)
return self.settings.get('PAGE_LANG_SAVE_AS', u'pages/{slug}-{lang}.html').format(**self.url_format)
@property @property
def content(self): def content(self):
if hasattr(self, "_get_content"): if hasattr(self, "_get_content"):
@ -138,10 +140,74 @@ class Page(object):
class Article(Page): class Article(Page):
mandatory_properties = ('title', 'date', 'category') mandatory_properties = ('title', 'date', 'category')
@property
def url(self):
if self.in_default_lang:
return self.settings.get('ARTICLE_URL', u'{slug}.html').format(**self.url_format)
return self.settings.get('ARTICLE_LANG_URL', u'{slug}-{lang}.html').format(**self.url_format)
@property
def save_as(self):
if self.in_default_lang:
return self.settings.get('ARTICLE_SAVE_AS', u'{slug}.html').format(**self.url_format)
return self.settings.get('ARTICLE_LANG_SAVE_AS', u'{slug}-{lang}.html').format(**self.url_format)
class Quote(Page): class Quote(Page):
base_properties = ('author', 'date') base_properties = ('author', 'date')
class URLWrapper(object):
def __init__(self, name, settings):
self.name = unicode(name)
self.settings = settings
def __hash__(self):
return hash(self.name)
def __eq__(self, other):
return self.name == unicode(other)
def __str__(self):
return str(self.name)
def __unicode__(self):
return self.name
@property
def url(self):
return '%s.html' % self.name
class Category(URLWrapper):
@property
def url(self):
return self.settings.get('CATEGORY_URL', u'category/{name}.html').format(name=self.name)
@property
def save_as(self):
return self.settings.get('CATEGORY_SAVE_AS', u'category/{name}.html').format(name=self.name)
class Tag(URLWrapper):
def __init__(self, name, *args, **kwargs):
super(Tag, self).__init__(unicode.strip(name), *args, **kwargs)
@property
def url(self):
return self.settings.get('TAG_URL', u'tag/{name}.html').format(name=self.name)
@property
def save_as(self):
return self.settings.get('TAG_SAVE_AS', u'tag/{name}.html').format(name=self.name)
class Author(URLWrapper):
@property
def url(self):
return self.settings.get('AUTHOR_URL', u'author/{name}.html').format(name=self.name)
@property
def save_as(self):
return self.settings.get('AUTHOR_SAVE_AS', u'author/{name}.html').format(name=self.name)
def is_valid_content(content, f): def is_valid_content(content, f):
try: try:

View file

@ -13,7 +13,7 @@ from operator import attrgetter, itemgetter
from jinja2 import Environment, FileSystemLoader, PrefixLoader, ChoiceLoader from jinja2 import Environment, FileSystemLoader, PrefixLoader, ChoiceLoader
from jinja2.exceptions import TemplateNotFound from jinja2.exceptions import TemplateNotFound
from pelican.contents import Article, Page, is_valid_content from pelican.contents import Article, Page, Category, is_valid_content
from pelican.log import * from pelican.log import *
from pelican.readers import read_file from pelican.readers import read_file
from pelican.utils import copy, process_translations, open from pelican.utils import copy, process_translations, open
@ -179,26 +179,26 @@ 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/%s.html' % tag, 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=u'tag/%s' % tag)
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('category/%s.html' % cat, 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=u'category/%s' % cat)
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('author/%s.html' % aut, 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=u'author/%s' % aut)
for article in self.drafts: for article in self.drafts:
write('drafts/%s.html' % article.slug, article_template, self.context, write('drafts/%s.html' % article.slug, article_template, self.context,
@ -212,7 +212,6 @@ class ArticlesGenerator(Generator):
files = self.get_files(self.path, exclude=['pages',]) files = self.get_files(self.path, exclude=['pages',])
all_articles = [] all_articles = []
for f in files: for f in files:
try: try:
content, metadata = read_file(f, settings=self.settings) content, metadata = read_file(f, settings=self.settings)
except Exception, e: except Exception, e:
@ -228,7 +227,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'] = unicode(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']:
@ -239,21 +238,6 @@ class ArticlesGenerator(Generator):
if not is_valid_content(article, f): if not is_valid_content(article, f):
continue continue
add_to_url = u''
if 'ARTICLE_PERMALINK_STRUCTURE' in self.settings:
article_permalink_structure = self.settings['ARTICLE_PERMALINK_STRUCTURE']
article_permalink_structure = article_permalink_structure.lstrip('/').replace('%(', "%%(")
# try to substitute any python datetime directive
add_to_url = article.date.strftime(article_permalink_structure)
# try to substitute any article metadata in rest file
add_to_url = add_to_url % article.__dict__
add_to_url = [slugify(i) for i in add_to_url.split('/')]
add_to_url = os.path.join(*add_to_url)
article.url = urlparse.urljoin(add_to_url, article.url)
article.save_as = urlparse.urljoin(add_to_url, article.save_as)
if article.status == "published": if article.status == "published":
if hasattr(article, 'tags'): if hasattr(article, 'tags'):
for tag in article.tags: for tag in article.tags:
@ -348,7 +332,7 @@ class PagesGenerator(Generator):
def generate_output(self, writer): def generate_output(self, writer):
for page in chain(self.translations, self.pages): for page in chain(self.translations, self.pages):
writer.write_file('pages/%s' % page.save_as, self.get_template('page'), writer.write_file(page.save_as, self.get_template('page'),
self.context, page=page, self.context, page=page,
relative_urls = self.settings.get('RELATIVE_URLS')) relative_urls = self.settings.get('RELATIVE_URLS'))

View file

@ -15,25 +15,30 @@ except ImportError:
Markdown = False Markdown = False
import re import re
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(unicode.strip, 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,
'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):
@ -51,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'}
@ -110,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
@ -126,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
@ -140,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]

View file

@ -26,7 +26,14 @@ _DEFAULT_CONFIG = {'PATH': None,
'REVERSE_ARCHIVE_ORDER': False, 'REVERSE_ARCHIVE_ORDER': False,
'REVERSE_CATEGORY_ORDER': False, 'REVERSE_CATEGORY_ORDER': False,
'DELETE_OUTPUT_DIRECTORY': False, 'DELETE_OUTPUT_DIRECTORY': False,
'CLEAN_URLS': False, # use /blah/ instead /blah.html in urls 'ARTICLE_URL': '{slug}.html',
'ARTICLE_SAVE_AS': '{slug}.html',
'ARTICLE_LANG_URL': '{slug}-{lang}.html',
'ARTICLE_LANG_SAVE_AS': '{slug}-{lang}.html',
'PAGE_URL': 'pages/{slug}.html',
'PAGE_SAVE_AS': 'pages/{slug}.html',
'PAGE_LANG_URL': 'pages/{slug}-{lang}.html',
'PAGE_LANG_SAVE_AS': 'pages/{slug}-{lang}.html',
'RELATIVE_URLS': True, 'RELATIVE_URLS': True,
'DEFAULT_LANG': 'en', 'DEFAULT_LANG': 'en',
'TAG_CLOUD_STEPS': 4, 'TAG_CLOUD_STEPS': 4,

View file

@ -5,10 +5,10 @@
{% if article.author %} {% if article.author %}
<address class="vcard author"> <address class="vcard author">
By <a class="url fn" href="{{ SITEURL }}/author/{{ article.author }}.html">{{ article.author }}</a> By <a class="url fn" href="{{ SITEURL }}/{{ article.author.url }}">{{ article.author }}</a>
</address> </address>
{% endif %} {% endif %}
<p>In <a href="{{ SITEURL }}/category/{{ article.category }}.html">{{ article.category }}</a>. {% if PDF_PROCESSOR %}<a href="{{ SITEURL }}/pdf/{{ article.slug }}.pdf">get the pdf</a>{% endif %}</p> <p>In <a href="{{ SITEURL }}/{{ article.category.url }}">{{ article.category }}</a>. {% if PDF_PROCESSOR %}<a href="{{ SITEURL }}/pdf/{{ article.slug }}.pdf">get the pdf</a>{% endif %}</p>
{% include 'taglist.html' %} {% include 'taglist.html' %}
{% include 'translations.html' %} {% include 'translations.html' %}
</footer><!-- /.post-info --> </footer><!-- /.post-info -->

View file

@ -31,7 +31,7 @@
{% endfor %} {% endfor %}
{% if DISPLAY_PAGES_ON_MENU %} {% if DISPLAY_PAGES_ON_MENU %}
{% for page in PAGES %} {% for page in PAGES %}
<li><a href="{{ SITEURL }}/pages/{{ page.url }}">{{ page.title }}</a></li> <li><a href="{{ SITEURL }}/{{ page.url }}">{{ page.title }}</a></li>
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{% for cat, null in categories %} {% for cat, null in categories %}

View file

@ -2,7 +2,7 @@
{% block content %} {% block content %}
<ul> <ul>
{% for category, articles in categories %} {% for category, articles in categories %}
<li>{{ category }}</li> <li><a href="{{ category.url }}">{{ category }}</a></li>
{% endfor %} {% endfor %}
</ul> </ul>
{% endblock %} {% endblock %}

View file

@ -53,7 +53,7 @@
<section id="content" class="body"> <section id="content" class="body">
<h2>Pages</h2> <h2>Pages</h2>
{% for page in PAGES %} {% for page in PAGES %}
<li><a href="{{ SITEURL }}/pages/{{ page.url }}">{{ page.title }}</a></li> <li><a href="{{ SITEURL }}/{{ page.url }}">{{ page.title }}</a></li>
{% endfor %} {% endfor %}
</section> </section>
{% endif %} {% endif %}

View file

@ -1,2 +1,2 @@
{% if article.tags %}<p>tags: {% for tag in article.tags %}<a href="{{ SITEURL }}/tag/{{ tag }}.html">{{ tag }}</a>{% endfor %}</p>{% endif %} {% if article.tags %}<p>tags: {% for tag in article.tags %}<a href="{{ SITEURL }}/{{ tag.url }}">{{ tag }}</a>{% endfor %}</p>{% endif %}
{% if PDF_PROCESSOR %}<p><a href="{{ SITEURL }}/pdf/{{ article.slug }}.pdf">get the pdf</a></p>{% endif %} {% if PDF_PROCESSOR %}<p><a href="{{ SITEURL }}/pdf/{{ article.slug }}.pdf">get the pdf</a></p>{% endif %}

View file

@ -8,7 +8,7 @@
</abbr> </abbr>
{% if article.author %} {% if article.author %}
<address class="vcard author"> <address class="vcard author">
By <a class="url fn" href="#">{{ article.author }}</a> By <a class="url fn" href="{{ SITEURL }}/{{ article.author.url }}">{{ article.author }}</a>
</address> </address>
{% endif %} {% endif %}
</footer><!-- /.post-info --> </footer><!-- /.post-info -->

View file

@ -17,7 +17,7 @@
{% endfor %} {% endfor %}
{% if DISPLAY_PAGES_ON_MENU %} {% if DISPLAY_PAGES_ON_MENU %}
{% for p in PAGES %} {% for p in PAGES %}
<li{% if p == page %} class="active"{% endif %}><a href="{{ SITEURL }}/pages/{{ p.url }}">{{ p.title }}</a></li> <li{% if p == page %} class="active"{% endif %}><a href="{{ SITEURL }}/{{ p.url }}">{{ p.title }}</a></li>
{% endfor %} {% endfor %}
{% else %} {% else %}
{% for cat, null in categories %} {% for cat, null in categories %}

View file

@ -2,7 +2,7 @@
{% block content %} {% block content %}
<ul> <ul>
{% for category, articles in categories %} {% for category, articles in categories %}
<li>{{ category }}</li> <li><a href="{{ SITEURL }}/{{ category.url }}">{{ category }}</a></li>
{% endfor %} {% endfor %}
</ul> </ul>
{% endblock %} {% endblock %}

View file

@ -11,7 +11,7 @@
<header> <h2 class="entry-title"><a href="{{ SITEURL }}/{{ article.url }}" rel="bookmark" title="Permalink to {{ article.title}}">{{ article.title }}</a></h2> </header> <header> <h2 class="entry-title"><a href="{{ SITEURL }}/{{ article.url }}" rel="bookmark" title="Permalink to {{ article.title}}">{{ article.title }}</a></h2> </header>
<footer class="post-info"> <footer class="post-info">
<abbr class="published" title="{{ article.date.isoformat() }}"> {{ article.locale_date }} </abbr> <abbr class="published" title="{{ article.date.isoformat() }}"> {{ article.locale_date }} </abbr>
{% if article.author %}<address class="vcard author">By <a class="url fn" href="{{ SITEURL }}/author/{{ article.author }}.html">{{ article.author }}</a></address>{% endif %} {% if article.author %}<address class="vcard author">By <a class="url fn" href="{{ SITEURL }}/{{ article.author.url }}">{{ article.author }}</a></address>{% endif %}
</footer><!-- /.post-info --> </footer><!-- /.post-info -->
<div class="entry-content"> {{ article.summary }} </div><!-- /.entry-content --> <div class="entry-content"> {{ article.summary }} </div><!-- /.entry-content -->
</article></li> </article></li>

View file

@ -60,12 +60,12 @@ class TestPage(TestCase):
""" """
# if a title is defined, save_as should be set # if a title is defined, save_as should be set
page = Page(**self.page_kwargs) page = Page(**self.page_kwargs)
page.save_as = 'foo-bar.html' self.assertEqual(page.save_as, "pages/foo-bar.html")
# if a language is defined, save_as should include it accordingly # if a language is defined, save_as should include it accordingly
self.page_kwargs['metadata'].update({'lang': 'fr', }) self.page_kwargs['metadata'].update({'lang': 'fr', })
page = Page(**self.page_kwargs) page = Page(**self.page_kwargs)
self.assertEqual(page.save_as, "foo-bar-fr.html") self.assertEqual(page.save_as, "pages/foo-bar-fr.html")
def test_datetime(self): def test_datetime(self):
"""If DATETIME is set to a tuple, it should be used to override LOCALE """If DATETIME is set to a tuple, it should be used to override LOCALE

View file

@ -19,7 +19,7 @@ def _filename(*args):
class RstReaderTest(unittest2.TestCase): class RstReaderTest(unittest2.TestCase):
def test_article_with_metadata(self): def test_article_with_metadata(self):
reader = readers.RstReader() reader = readers.RstReader({})
content, metadata = reader.read(_filename('article_with_metadata.rst')) content, metadata = reader.read(_filename('article_with_metadata.rst'))
expected = { expected = {
'category': 'yeah', 'category': 'yeah',