Sort articles by date. A bit more templates. Add an author field.

--HG--
rename : pelican/templates/archives.html => pelican/themes/archives.html
rename : pelican/templates/article.html => pelican/themes/article.html
rename : pelican/templates/categories.html => pelican/themes/categories.html
rename : pelican/templates/category.html => pelican/themes/category.html
rename : pelican/templates/index.html => pelican/themes/index.html
rename : pelican/templates/tag.html => pelican/themes/tag.html
rename : pelican/templates/tags.html => pelican/themes/tags.html
This commit is contained in:
Alexis Metaireau 2010-08-17 20:28:51 +02:00
commit 3634e5c49d
20 changed files with 123 additions and 30 deletions

1
TODO Normal file
View file

@ -0,0 +1 @@
* Add a settings.py file/option

View file

@ -5,6 +5,7 @@ from codecs import open
from datetime import datetime from datetime import datetime
from docutils import core from docutils import core
from functools import partial from functools import partial
from operator import attrgetter
from jinja2 import Environment, FileSystemLoader from jinja2 import Environment, FileSystemLoader
@ -14,10 +15,11 @@ _TEMPLATES = ('index', 'tag', 'tags', 'article', 'category', 'categories',
'archives') 'archives')
_DIRECT_TEMPLATES = ('index', 'tags', 'categories', 'archives') _DIRECT_TEMPLATES = ('index', 'tags', 'categories', 'archives')
_DEFAULT_TEMPLATE_PATH =\ _DEFAULT_TEMPLATE_PATH =\
os.sep.join([os.path.dirname(os.path.abspath(__file__)), "templates"]) os.sep.join([os.path.dirname(os.path.abspath(__file__)), "themes"])
def generate_output(files, templates_path=None, output_path=None, markup=None): def generate_output(files, templates_path=None, output_path=None, markup=None,
settings=None):
"""Given a list of files, a template and a destination, """Given a list of files, a template and a destination,
output the static files. output the static files.
@ -25,6 +27,7 @@ def generate_output(files, templates_path=None, output_path=None, markup=None):
:param templates_path: where to search for templates :param templates_path: where to search for templates
:param output_path: where to output the generated files :param output_path: where to output the generated files
:param markup: the markup language to use while parsing :param markup: the markup language to use while parsing
:param settings: the settings file to use
""" """
if not templates_path: if not templates_path:
templates_path = _DEFAULT_TEMPLATE_PATH templates_path = _DEFAULT_TEMPLATE_PATH
@ -32,7 +35,7 @@ def generate_output(files, templates_path=None, output_path=None, markup=None):
output_path = './output' output_path = './output'
output_path = os.path.realpath(output_path) output_path = os.path.realpath(output_path)
articles, months, years, tags, categories = [], {}, {}, {}, {} articles, dates, years, tags, categories = [], {}, {}, {}, {}
# for each file, get the informations. # for each file, get the informations.
for f in files: for f in files:
@ -40,7 +43,7 @@ def generate_output(files, templates_path=None, output_path=None, markup=None):
article = Article(open(f, encoding='utf-8').read(), markup) article = Article(open(f, encoding='utf-8').read(), markup)
articles.append(article) articles.append(article)
if hasattr(article, 'date'): if hasattr(article, 'date'):
update_dict(months, article.date.month, article) update_dict(dates, article.date.strftime('%Y-%m-%d'), article)
update_dict(years, article.date.year, article) update_dict(years, article.date.year, article)
if hasattr(article, 'tags'): if hasattr(article, 'tags'):
for tag in article.tags: for tag in article.tags:
@ -48,18 +51,24 @@ def generate_output(files, templates_path=None, output_path=None, markup=None):
if hasattr(article, 'category'): if hasattr(article, 'category'):
update_dict(categories, article.category, article) update_dict(categories, article.category, article)
# order the articles by date
articles.sort(key=attrgetter('date'), reverse=True)
templates = get_templates(templates_path) templates = get_templates(templates_path)
context = {} context = {}
for item in ('articles', 'months', 'years', 'tags', 'categories'): for item in ('articles', 'dates', 'years', 'tags', 'categories'):
context[item] = locals()[item] value = locals()[item]
if hasattr(value, 'items'):
value = value.items()
context[item] = value
read_settings(context, settings)
generate = partial(generate_file, output_path) generate = partial(generate_file, output_path)
for template in _DIRECT_TEMPLATES: for template in _DIRECT_TEMPLATES:
generate(template, templates[template], context) generate('%s.html' % template, templates[template], context)
for tag in tags: for tag in tags:
generate('tag/%s' % tag, templates['tag'], context, tag=tag) generate('tag/%s.html' % tag, templates['tag'], context, tag=tag)
for cat in categories: for cat in categories:
generate('category/%s' % cat, templates['category'], context, generate('category/%s.html' % cat, templates['category'], context,
category=cat) category=cat)
for article in articles: for article in articles:
generate('%s' % article.url, generate('%s' % article.url,
@ -69,7 +78,7 @@ def generate_output(files, templates_path=None, output_path=None, markup=None):
def generate_file(path, name, template, context, **kwargs): def generate_file(path, name, template, context, **kwargs):
context.update(kwargs) context.update(kwargs)
output = template.render(context) output = template.render(context)
filename = os.sep.join((path, '%s.html' % name)) filename = os.sep.join((path, name))
try: try:
os.makedirs(os.path.dirname(filename)) os.makedirs(os.path.dirname(filename))
except Exception: except Exception:
@ -86,11 +95,6 @@ def get_templates(path=None):
templates[template] = env.get_template('%s.html' % template) templates[template] = env.get_template('%s.html' % template)
return templates return templates
_METADATA = re.compile('.. ([a-z]+): (.*)', re.M)
_METADATAS_FIELDS = {'tags': lambda x: x.split(', '),
'date': lambda x: datetime.strptime(x, '%Y/%m/%d %H:%M'),
'category': lambda x: x}
def update_dict(mapping, key, value): def update_dict(mapping, key, value):
if key not in mapping: if key not in mapping:
@ -98,8 +102,29 @@ def update_dict(mapping, key, value):
mapping[key].append(value) mapping[key].append(value)
def parse_metadatas(string): def read_settings(context, filename):
"""Return a dict, containing a list of metadatas informations, found """Load a Python file into a dictionary.
"""
if filename:
from importlib import import_module
d = import_module(filename)
for key in dir(d):
if key.isupper():
context[key] = getattr(d, key)
from ipdb import set_trace
set_trace()
return context
_METADATA = re.compile('.. ([a-z]+): (.*)', re.M)
_METADATAS_FIELDS = {'tags': lambda x: x.split(', '),
'date': lambda x: datetime.strptime(x, '%Y-%m-%d %H:%M'),
'category': lambda x: x,
'author': lambda x: x}
def parse_metadata(string):
"""Return a dict, containing a list of metadata informations, found
whithin the given string. whithin the given string.
:param string: the string to search the metadata in :param string: the string to search the metadata in
@ -138,7 +163,7 @@ class Article(object):
if markup == None: if markup == None:
markup = 'rest' markup = 'rest'
for key, value in parse_metadatas(string).items(): for key, value in parse_metadata(string).items():
setattr(self, key, value) setattr(self, key, value)
if markup == 'rest': if markup == 'rest':
extra_params = {'input_encoding': 'unicode', extra_params = {'input_encoding': 'unicode',
@ -150,7 +175,11 @@ class Article(object):
@property @property
def url(self): def url(self):
return slugify(self.title) return '%s.html' % slugify(self.title)
@property
def summary(self):
return self.content
def __repr__(self): def __repr__(self):
return '<%s "%s">' % (self.__class__.__name__, self.title) return '<%s "%s">' % (self.__class__.__name__, self.title)

View file

@ -19,11 +19,14 @@ parser.add_argument('-o', '--output', default=None, dest='output',
parser.add_argument('-m', '--markup', default='rest', dest='markup', parser.add_argument('-m', '--markup', default='rest', dest='markup',
help='the markup language to use. Currently only ReSTreucturedtext is' help='the markup language to use. Currently only ReSTreucturedtext is'
' available.') ' available.')
parser.add_argument('-s', '--settings', default=None, dest='settings',
help='the settings of the application. Default to None.')
if __name__ == '__main__': if __name__ == '__main__':
args = parser.parse_args() args = parser.parse_args()
files = [] files = []
for root, dirs, temp_files in os.walk(args.path, followlinks=True): for root, dirs, temp_files in os.walk(args.path, followlinks=True):
files.extend([os.sep.join((root, f)) for f in temp_files]) files.extend([os.sep.join((root, f)) for f in temp_files])
generate_output(files, args.templates, args.output, args.markup) generate_output(files, args.templates, args.output, args.markup,
args.settings)
print 'Done !' print 'Done !'

View file

@ -1,5 +0,0 @@
<h1>{{ article.title }}</h1>
{% for tag in article.tags %}
{{ tag }}
{% endfor %}
{{ article.content }}

View file

@ -1,4 +0,0 @@
{% for article in articles %}
<h2>{{ article.title }}</h2>
{{ article.content }}
{% endfor %}

View file

@ -0,0 +1,13 @@
{% extends "base.html" %}
{% block content %}
<h1>Archives for {{ blogname }}</h1>
<dl>
{% for date, articles in dates %}
{% for article in articles %}
<dt>{{ date }}</dt>
<dd><a href='{{ article.url }}'>{{ article.title }}</a></dd>
{% endfor %}
{% endfor %}
</dl>
{% endblock %}

View file

@ -0,0 +1,19 @@
{% extends "base.html" %}
{% block content %}
<section id="content" class="body">
<header> <h2 class="entry-title"><a href="{{ article.url }}" rel="bookmark" title="Permalink to {{ article.title}}">{{ article.title }}</a></h2> </header>
<footer class="post-info">
<abbr class="published" title="{{ article.date.isoformat() }}">
{{ article.date.strftime('%Y-%m-%d %H:%M') }}
</abbr>
{% if article.author %}
<address class="vcard author">
By <a class="url fn" href="#">{{ article.author }}</a>
</address>
{% endif %}
</footer><!-- /.post-info -->
<div class="entry-content">
{{ article.content }}
</div><!-- /.entry-content -->
</section>
{% endblock %}

17
pelican/themes/index.html Normal file
View file

@ -0,0 +1,17 @@
{% extends "base.html" %}
{% block content %}
<section id="content">
<ol id="post-list">
{% for article in articles %}
<li><article class="hentry">
<header> <h2 class="entry-title"><a href="{{ article.url }}" rel="bookmark" title="Permalink to {{ article.title}}">{{ article.title }}</a></h2> </header>
<footer class="post-info">
<abbr class="published" title="{{ article.date.isoformat() }}"> {{ article.date.strftime('%Y-%m-%d %H:%M') }} </abbr>
{% if article.author %}<address class="vcard author">By <a class="url fn" href="#">{{ article.author }}</a></address>{% endif %}
</footer><!-- /.post-info -->
<div class="entry-content"> {{ article.summary }} </div><!-- /.entry-content -->
</article></li>
{% endfor %}
</ol><!-- /#posts-list -->
</section><!-- /#content -->
{% endblock content %}

View file

@ -0,0 +1,13 @@
Oh yeah !
#########################
.. tags: oh, bar, yeah
.. date: 2010-10-20 10:14
.. category: bar
.. author: Alexis Métaireau
Why not ?
=========
After all, why not ? It's pretty simple to do it, and it will allow me to write my blogposts in rst !
YEAH !

View file

@ -2,8 +2,9 @@ This is a super article !
######################### #########################
.. tags: foo, bar, foobar .. tags: foo, bar, foobar
.. date: 2010/10/10 10:14 .. date: 2010-10-02 10:14
.. category: yeah .. category: yeah
.. author: Alexis Métaireau
Some content here ! Some content here !

View file

@ -0,0 +1,6 @@
Unbelievable !
##############
.. date: 2010-10-15 20:30
Or completely awesome. Depends the needs.