Merge branch 'master' into assets

This commit is contained in:
Simon 2012-05-11 22:00:20 +02:00
commit d7f28d4328
12 changed files with 229 additions and 136 deletions

View file

@ -21,9 +21,9 @@ Here is a list of settings for Pelican:
Basic settings Basic settings
============== ==============
================================================ ===================================================== ===================================================================== =====================================================================
Setting name (default value) What does it do? Setting name (default value) What does it do?
================================================ ===================================================== ===================================================================== =====================================================================
`AUTHOR` Default author (put your name) `AUTHOR` Default author (put your name)
`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"
@ -85,7 +85,12 @@ Setting name (default value) What does it do?
`LESS_GENERATOR` (``FALSE``) Set to True or complete path to `lessc` (if not `LESS_GENERATOR` (``FALSE``) Set to True or complete path to `lessc` (if not
found in system PATH) to enable compiling less found in system PATH) to enable compiling less
css files. Requires installation of `less css`_. css files. Requires installation of `less css`_.
================================================ ===================================================== `DIRECT_TEMPLATES` (``('index', 'tags', 'categories', 'archives')``) List of templates that are used directly to render
content. Typically direct templates are used to generate
index pages for collections of content e.g. tags and
category index pages.
`PAGINATED_DIRECT_TEMPLATES` (``('index',)``) Provides the direct templates that should be paginated.
===================================================================== =====================================================================
.. [#] Default is the system locale. .. [#] Default is the system locale.
@ -101,9 +106,10 @@ your articles in a location such as '{slug}/index.html' and link to them as
'{slug}' for clean URLs. These settings give you the flexibility to place your '{slug}' for clean URLs. These settings give you the flexibility to place your
articles and pages anywhere you want. articles and pages anywhere you want.
Note: If you specify a datetime directive, it will be substituted using the .. note::
input files' date metadata attribute. If the date is not specified for a If you specify a datetime directive, it will be substituted using the
particular file, Pelican will rely on the file's mtime timestamp. input files' date metadata attribute. If the date is not specified for a
particular file, Pelican will rely on the file's mtime timestamp.
Check the Python datetime documentation at http://bit.ly/cNcJUC for more Check the Python datetime documentation at http://bit.ly/cNcJUC for more
information. information.
@ -145,9 +151,14 @@ Setting name (default value) what does it do?
`CATEGORY_SAVE_AS` ('category/{name}.html') The location to save 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_URL` ('tag/{name}.html') The URL to use for a tag.
`TAG_SAVE_AS` ('tag/{name}.html') The location to save the tag page. `TAG_SAVE_AS` ('tag/{name}.html') The location to save the tag page.
`<DIRECT_TEMPLATE_NAME>_SAVE_AS` The location to save content generated from direct
templates. Where <DIRECT_TEMPLATE_NAME> is the
upper case template name.
================================================ ===================================================== ================================================ =====================================================
Note: when any of `*_SAVE_AS` is set to False, files will not be created. .. note::
When any of `*_SAVE_AS` is set to False, files will not be created.
Timezone Timezone
-------- --------

View file

@ -163,31 +163,32 @@ class ArticlesGenerator(Generator):
writer.write_feed(items, self.context, writer.write_feed(items, self.context,
self.settings['TRANSLATION_FEED'] % lang) self.settings['TRANSLATION_FEED'] % lang)
def generate_pages(self, writer): def generate_articles(self, write):
"""Generate the pages on the disk""" """Generate the articles."""
write = partial(writer.write_file,
relative_urls=self.settings.get('RELATIVE_URLS'))
# to minimize the number of relative path stuff modification
# in writer, articles pass first
article_template = self.get_template('article') article_template = self.get_template('article')
for article in chain(self.translations, self.articles): for article in chain(self.translations, self.articles):
write(article.save_as, write(article.save_as,
article_template, self.context, article=article, article_template, self.context, article=article,
category=article.category) category=article.category)
def generate_direct_templates(self, write):
"""Generate direct templates pages"""
PAGINATED_TEMPLATES = self.settings.get('PAGINATED_DIRECT_TEMPLATES') PAGINATED_TEMPLATES = self.settings.get('PAGINATED_DIRECT_TEMPLATES')
for template in self.settings.get('DIRECT_TEMPLATES'): for template in self.settings.get('DIRECT_TEMPLATES'):
paginated = {} paginated = {}
if template in PAGINATED_TEMPLATES: if template in PAGINATED_TEMPLATES:
paginated = {'articles': self.articles, 'dates': self.dates} paginated = {'articles': self.articles, 'dates': self.dates}
save_as = self.settings.get("%s_SAVE_AS" % template.upper(),
'%s.html' % template)
if not save_as:
continue
write('%s.html' % template, self.get_template(template), write(save_as, self.get_template(template),
self.context, blog=True, paginated=paginated, self.context, blog=True, paginated=paginated,
page_name=template) page_name=template)
# and subfolders after that def generate_tags(self, write):
"""Generate Tags pages."""
tag_template = self.get_template('tag') tag_template = self.get_template('tag')
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)
@ -197,6 +198,8 @@ class ArticlesGenerator(Generator):
paginated={'articles': articles, 'dates': dates}, paginated={'articles': articles, 'dates': dates},
page_name=u'tag/%s' % tag) page_name=u'tag/%s' % tag)
def generate_categories(self, write):
"""Generate category pages."""
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]
@ -205,6 +208,8 @@ class ArticlesGenerator(Generator):
paginated={'articles': articles, 'dates': dates}, paginated={'articles': articles, 'dates': dates},
page_name=u'category/%s' % cat) page_name=u'category/%s' % cat)
def generate_authors(self, write):
"""Generate Author pages."""
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]
@ -213,10 +218,30 @@ class ArticlesGenerator(Generator):
paginated={'articles': articles, 'dates': dates}, paginated={'articles': articles, 'dates': dates},
page_name=u'author/%s' % aut) page_name=u'author/%s' % aut)
def generate_drafts(self, write):
"""Generate drafts pages."""
article_template = self.get_template('article')
for article in self.drafts: for article in self.drafts:
write('drafts/%s.html' % article.slug, article_template, write('drafts/%s.html' % article.slug, article_template,
self.context, article=article, category=article.category) self.context, article=article, category=article.category)
def generate_pages(self, writer):
"""Generate the pages on the disk"""
write = partial(writer.write_file,
relative_urls=self.settings.get('RELATIVE_URLS'))
# to minimize the number of relative path stuff modification
# in writer, articles pass first
self.generate_articles(write)
self.generate_direct_templates(write)
# and subfolders after that
self.generate_tags(write)
self.generate_categories(write)
self.generate_authors(write)
self.generate_drafts(write)
def generate_context(self): def generate_context(self):
"""change the context""" """change the context"""

View file

@ -174,5 +174,6 @@ def read_file(filename, fmt=None, settings=None):
if settings and settings['TYPOGRIFY']: if settings and settings['TYPOGRIFY']:
from typogrify import Typogrify from typogrify import Typogrify
content = Typogrify.typogrify(content) content = Typogrify.typogrify(content)
metadata['title'] = Typogrify.typogrify(metadata['title'])
return content, metadata return content, metadata

View file

@ -4,13 +4,17 @@ body {
font:1.3em/1.3 "Hoefler Text","Georgia",Georgia,serif,sans-serif; font:1.3em/1.3 "Hoefler Text","Georgia",Georgia,serif,sans-serif;
} }
.body, #banner nav, #banner nav ul, #about, #featured, #content{ .post-info{
width: inherit; display: none;
} }
#banner nav { #banner nav {
display: none;
-moz-border-radius: 0px; -moz-border-radius: 0px;
margin-bottom: 0px; margin-bottom: 20px;
overflow: hidden;
font-size: 1em;
background: #F5F4EF;
} }
#banner nav ul{ #banner nav ul{
@ -19,10 +23,11 @@ body {
#banner nav li{ #banner nav li{
float: right; float: right;
color: #000;
} }
#banner nav li:first-child a { #banner nav li a {
-moz-border-radius: 0px; color: #000;
} }
#banner h1 { #banner h1 {

View file

@ -6,7 +6,7 @@
<dl> <dl>
{% for article in dates %} {% for article in dates %}
<dt>{{ article.locale_date }}</dt> <dt>{{ article.locale_date }}</dt>
<dd><a href="{{ article.url }}">{{ article.title }}</a></dd> <dd><a href="{{ SITEURL }}/{{ article.url }}">{{ article.title }}</a></dd>
{% endfor %} {% endfor %}
</dl> </dl>
</section> </section>

View file

@ -1,11 +1,15 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block title %}{{ article.title }}{% endblock %} {% block title %}{{ article.title|striptags }}{% endblock %}
{% block content %} {% block content %}
<section id="content" class="body"> <section id="content" class="body">
<article> <article>
<header> <h1 class="entry-title"><a href="{{ pagename }}" <header>
rel="bookmark" title="Permalink to {{ article.title }}">{{ article.title <h1 class="entry-title">
}}</a></h1> {% include 'twitter.html' %} </header> <a href="{{ article.url }}" rel="bookmark"
title="Permalink to {{ article.title|striptags }}">{{ article.title}}</a></h1>
{% include 'twitter.html' %}
</header>
<div class="entry-content"> <div class="entry-content">
{% include 'article_infos.html' %} {% include 'article_infos.html' %}
{{ article.content }} {{ article.content }}
@ -25,6 +29,6 @@
</div> </div>
{% endif %} {% endif %}
</article> </article>
</section> </section>
{% endblock %} {% endblock %}

View file

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

View file

@ -5,7 +5,7 @@
<dl> <dl>
{% for article in dates %} {% for article in dates %}
<dt>{{ article.locale_date }}</dt> <dt>{{ article.locale_date }}</dt>
<dd><a href="{{ article.url }}">{{ article.title }}</a></dd> <dd><a href="{{ SITEURL }}/{{ article.url }}">{{ article.title }}</a></dd>
{% endfor %} {% endfor %}
</dl> </dl>
{% endblock %} {% endblock %}

View file

@ -1,7 +1,11 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block content %} {% block content %}
<section id="content" class="body"> <section id="content" class="body">
<header> <h2 class="entry-title"><a href="{{ pagename }}" rel="bookmark" title="Permalink to {{ article.title}}">{{ article.title }}</a></h2> </header> <header>
<h2 class="entry-title">
<a href="{{ article.url }}" rel="bookmark"
title="Permalink to {{ article.title|striptags }}">{{ article.title }}</a></h2>
</header>
<footer class="post-info"> <footer class="post-info">
<abbr class="published" title="{{ article.date.isoformat() }}"> <abbr class="published" title="{{ article.date.isoformat() }}">
{{ article.locale_date }} {{ article.locale_date }}

View file

@ -8,6 +8,7 @@ import logging
from codecs import open as _open from codecs import open as _open
from datetime import datetime from datetime import datetime
from itertools import groupby from itertools import groupby
from jinja2 import Markup
from operator import attrgetter from operator import attrgetter
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -44,6 +45,7 @@ def slugify(value):
Took from django sources. Took from django sources.
""" """
value = Markup(value).striptags()
if type(value) == unicode: if type(value) == unicode:
import unicodedata import unicodedata
value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore') value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore')

View file

@ -8,8 +8,8 @@ import logging
from codecs import open from codecs import open
from functools import partial from functools import partial
from feedgenerator import Atom1Feed, Rss201rev2Feed from feedgenerator import Atom1Feed, Rss201rev2Feed
from jinja2 import Markup
from pelican.paginator import Paginator from pelican.paginator import Paginator
from pelican.utils import get_relative_path, set_date_tzinfo from pelican.utils import get_relative_path, set_date_tzinfo
@ -25,8 +25,9 @@ class Writer(object):
def _create_new_feed(self, feed_type, context): def _create_new_feed(self, feed_type, context):
feed_class = Rss201rev2Feed if feed_type == 'rss' else Atom1Feed feed_class = Rss201rev2Feed if feed_type == 'rss' else Atom1Feed
sitename = Markup(context['SITENAME']).striptags()
feed = feed_class( feed = feed_class(
title=context['SITENAME'], title=sitename,
link=(self.site_url + '/'), link=(self.site_url + '/'),
feed_url=self.feed_url, feed_url=self.feed_url,
description=context.get('SITESUBTITLE', '')) description=context.get('SITESUBTITLE', ''))
@ -34,8 +35,9 @@ class Writer(object):
def _add_item_to_the_feed(self, feed, item): def _add_item_to_the_feed(self, feed, item):
title = Markup(item.title).striptags()
feed.add_item( feed.add_item(
title=item.title, title=title,
link='%s/%s' % (self.site_url, item.url), link='%s/%s' % (self.site_url, item.url),
unique_id='tag:%s,%s:%s' % (self.site_url.replace('http://', ''), unique_id='tag:%s,%s:%s' % (self.site_url.replace('http://', ''),
item.date.date(), item.url), item.date.date(), item.url),

View file

@ -54,6 +54,45 @@ class TestArticlesGenerator(unittest.TestCase):
categories, ['Default', 'TestCategory', 'Yeah', 'test', categories, ['Default', 'TestCategory', 'Yeah', 'test',
'yeah']) 'yeah'])
def test_direct_templates_save_as_default(self):
settings = _DEFAULT_CONFIG.copy()
settings['DIRECT_TEMPLATES'] = ['archives']
generator = ArticlesGenerator(settings.copy(), settings, None,
_DEFAULT_CONFIG['THEME'], None,
_DEFAULT_CONFIG['MARKUP'])
write = MagicMock()
generator.generate_direct_templates(write)
write.assert_called_with("archives.html",
generator.get_template("archives"), settings,
blog=True, paginated={}, page_name='archives')
def test_direct_templates_save_as_modified(self):
settings = _DEFAULT_CONFIG.copy()
settings['DIRECT_TEMPLATES'] = ['archives']
settings['ARCHIVES_SAVE_AS'] = 'archives/index.html'
generator = ArticlesGenerator(settings, settings, None,
_DEFAULT_CONFIG['THEME'], None,
_DEFAULT_CONFIG['MARKUP'])
write = MagicMock()
generator.generate_direct_templates(write)
write.assert_called_with("archives/index.html",
generator.get_template("archives"), settings,
blog=True, paginated={}, page_name='archives')
def test_direct_templates_save_as_false(self):
settings = _DEFAULT_CONFIG.copy()
settings['DIRECT_TEMPLATES'] = ['archives']
settings['ARCHIVES_SAVE_AS'] = 'archives/index.html'
generator = ArticlesGenerator(settings, settings, None,
_DEFAULT_CONFIG['THEME'], None,
_DEFAULT_CONFIG['MARKUP'])
write = MagicMock()
generator.generate_direct_templates(write)
write.assert_called_count == 0
class TestLessCSSGenerator(unittest.TestCase): class TestLessCSSGenerator(unittest.TestCase):