From 3634e5c49d596cd3f61f5bd1aaa605e88c48c5f8 Mon Sep 17 00:00:00 2001 From: Alexis Metaireau Date: Tue, 17 Aug 2010 20:28:51 +0200 Subject: [PATCH] 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 --- TODO | 1 + pelican/generator.py | 67 +++++++++++++------ pelican/pelican | 5 +- pelican/templates/archives.html | 0 pelican/templates/article.html | 5 -- pelican/templates/index.html | 4 -- pelican/themes/archives.html | 13 ++++ pelican/themes/article.html | 19 ++++++ pelican/{templates => themes}/categories.html | 0 pelican/{templates => themes}/category.html | 0 pelican/themes/index.html | 17 +++++ pelican/{templates => themes}/tag.html | 0 pelican/{templates => themes}/tags.html | 0 samples/content/another_super_article.rst | 13 ++++ samples/content/super_article.rst | 3 +- samples/content/unbelievable.rst | 6 ++ 16 files changed, 123 insertions(+), 30 deletions(-) create mode 100644 TODO delete mode 100644 pelican/templates/archives.html delete mode 100644 pelican/templates/article.html delete mode 100644 pelican/templates/index.html create mode 100644 pelican/themes/archives.html create mode 100644 pelican/themes/article.html rename pelican/{templates => themes}/categories.html (100%) rename pelican/{templates => themes}/category.html (100%) create mode 100644 pelican/themes/index.html rename pelican/{templates => themes}/tag.html (100%) rename pelican/{templates => themes}/tags.html (100%) create mode 100644 samples/content/another_super_article.rst create mode 100644 samples/content/unbelievable.rst diff --git a/TODO b/TODO new file mode 100644 index 00000000..c9c3834c --- /dev/null +++ b/TODO @@ -0,0 +1 @@ +* Add a settings.py file/option diff --git a/pelican/generator.py b/pelican/generator.py index 69e80116..bf723fd4 100644 --- a/pelican/generator.py +++ b/pelican/generator.py @@ -5,6 +5,7 @@ from codecs import open from datetime import datetime from docutils import core from functools import partial +from operator import attrgetter from jinja2 import Environment, FileSystemLoader @@ -14,10 +15,11 @@ _TEMPLATES = ('index', 'tag', 'tags', 'article', 'category', 'categories', 'archives') _DIRECT_TEMPLATES = ('index', 'tags', 'categories', 'archives') _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, 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 output_path: where to output the generated files :param markup: the markup language to use while parsing + :param settings: the settings file to use """ if not templates_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 = os.path.realpath(output_path) - articles, months, years, tags, categories = [], {}, {}, {}, {} + articles, dates, years, tags, categories = [], {}, {}, {}, {} # for each file, get the informations. 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) articles.append(article) 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) if hasattr(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'): update_dict(categories, article.category, article) + # order the articles by date + articles.sort(key=attrgetter('date'), reverse=True) templates = get_templates(templates_path) context = {} - for item in ('articles', 'months', 'years', 'tags', 'categories'): - context[item] = locals()[item] + for item in ('articles', 'dates', 'years', 'tags', 'categories'): + value = locals()[item] + if hasattr(value, 'items'): + value = value.items() + context[item] = value + read_settings(context, settings) generate = partial(generate_file, output_path) for template in _DIRECT_TEMPLATES: - generate(template, templates[template], context) + generate('%s.html' % template, templates[template], context) 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: - generate('category/%s' % cat, templates['category'], context, + generate('category/%s.html' % cat, templates['category'], context, category=cat) for article in articles: 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): context.update(kwargs) output = template.render(context) - filename = os.sep.join((path, '%s.html' % name)) + filename = os.sep.join((path, name)) try: os.makedirs(os.path.dirname(filename)) except Exception: @@ -86,11 +95,6 @@ def get_templates(path=None): templates[template] = env.get_template('%s.html' % template) 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): if key not in mapping: @@ -98,8 +102,29 @@ def update_dict(mapping, key, value): mapping[key].append(value) -def parse_metadatas(string): - """Return a dict, containing a list of metadatas informations, found +def read_settings(context, filename): + """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. :param string: the string to search the metadata in @@ -138,7 +163,7 @@ class Article(object): if markup == None: markup = 'rest' - for key, value in parse_metadatas(string).items(): + for key, value in parse_metadata(string).items(): setattr(self, key, value) if markup == 'rest': extra_params = {'input_encoding': 'unicode', @@ -150,7 +175,11 @@ class Article(object): @property def url(self): - return slugify(self.title) + return '%s.html' % slugify(self.title) + @property + def summary(self): + return self.content + def __repr__(self): return '<%s "%s">' % (self.__class__.__name__, self.title) diff --git a/pelican/pelican b/pelican/pelican index ca57263d..737774a4 100755 --- a/pelican/pelican +++ b/pelican/pelican @@ -19,11 +19,14 @@ parser.add_argument('-o', '--output', default=None, dest='output', parser.add_argument('-m', '--markup', default='rest', dest='markup', help='the markup language to use. Currently only ReSTreucturedtext is' ' available.') +parser.add_argument('-s', '--settings', default=None, dest='settings', + help='the settings of the application. Default to None.') if __name__ == '__main__': args = parser.parse_args() files = [] for root, dirs, temp_files in os.walk(args.path, followlinks=True): 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 !' diff --git a/pelican/templates/archives.html b/pelican/templates/archives.html deleted file mode 100644 index e69de29b..00000000 diff --git a/pelican/templates/article.html b/pelican/templates/article.html deleted file mode 100644 index c33626f4..00000000 --- a/pelican/templates/article.html +++ /dev/null @@ -1,5 +0,0 @@ -

{{ article.title }}

-{% for tag in article.tags %} - {{ tag }} -{% endfor %} -{{ article.content }} diff --git a/pelican/templates/index.html b/pelican/templates/index.html deleted file mode 100644 index 6008ecf2..00000000 --- a/pelican/templates/index.html +++ /dev/null @@ -1,4 +0,0 @@ -{% for article in articles %} -

{{ article.title }}

- {{ article.content }} -{% endfor %} diff --git a/pelican/themes/archives.html b/pelican/themes/archives.html new file mode 100644 index 00000000..19da15ff --- /dev/null +++ b/pelican/themes/archives.html @@ -0,0 +1,13 @@ +{% extends "base.html" %} +{% block content %} +

Archives for {{ blogname }}

+ +
+{% for date, articles in dates %} + {% for article in articles %} +
{{ date }}
+
{{ article.title }}
+ {% endfor %} +{% endfor %} +
+{% endblock %} diff --git a/pelican/themes/article.html b/pelican/themes/article.html new file mode 100644 index 00000000..c28634f9 --- /dev/null +++ b/pelican/themes/article.html @@ -0,0 +1,19 @@ +{% extends "base.html" %} +{% block content %} +
+

{{ article.title }}

+
+ + {{ article.date.strftime('%Y-%m-%d %H:%M') }} + + {% if article.author %} +
+ By {{ article.author }} +
+ {% endif %} +
+
+ {{ article.content }} +
+
+{% endblock %} diff --git a/pelican/templates/categories.html b/pelican/themes/categories.html similarity index 100% rename from pelican/templates/categories.html rename to pelican/themes/categories.html diff --git a/pelican/templates/category.html b/pelican/themes/category.html similarity index 100% rename from pelican/templates/category.html rename to pelican/themes/category.html diff --git a/pelican/themes/index.html b/pelican/themes/index.html new file mode 100644 index 00000000..8c309191 --- /dev/null +++ b/pelican/themes/index.html @@ -0,0 +1,17 @@ +{% extends "base.html" %} +{% block content %} +
+
    +{% for article in articles %} +
  1. +{% endfor %} +
+
+{% endblock content %} diff --git a/pelican/templates/tag.html b/pelican/themes/tag.html similarity index 100% rename from pelican/templates/tag.html rename to pelican/themes/tag.html diff --git a/pelican/templates/tags.html b/pelican/themes/tags.html similarity index 100% rename from pelican/templates/tags.html rename to pelican/themes/tags.html diff --git a/samples/content/another_super_article.rst b/samples/content/another_super_article.rst new file mode 100644 index 00000000..a6bb18a6 --- /dev/null +++ b/samples/content/another_super_article.rst @@ -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 ! diff --git a/samples/content/super_article.rst b/samples/content/super_article.rst index 4146fbe8..f11a2cc0 100644 --- a/samples/content/super_article.rst +++ b/samples/content/super_article.rst @@ -2,8 +2,9 @@ This is a super article ! ######################### .. tags: foo, bar, foobar -.. date: 2010/10/10 10:14 +.. date: 2010-10-02 10:14 .. category: yeah +.. author: Alexis Métaireau Some content here ! diff --git a/samples/content/unbelievable.rst b/samples/content/unbelievable.rst new file mode 100644 index 00000000..bb3c6318 --- /dev/null +++ b/samples/content/unbelievable.rst @@ -0,0 +1,6 @@ +Unbelievable ! +############## + +.. date: 2010-10-15 20:30 + +Or completely awesome. Depends the needs.