Render the site with parametrized paths

This commit is contained in:
Fred 2020-10-10 16:48:48 +02:00
parent ae2922b78e
commit e9183bd445
7 changed files with 177 additions and 0 deletions

2
.gitignore vendored
View File

@ -1,3 +1,5 @@
.vscode/*
# ---> Python
# Byte-compiled / optimized / DLL files
__pycache__/

2
requirements/base.txt Normal file
View File

@ -0,0 +1,2 @@
jinja2==2.11.2
markdown==3.3

70
src/main.py Normal file
View File

@ -0,0 +1,70 @@
import codecs
import logging
import os
from jinja2 import Environment, FileSystemLoader
from markdown import markdown
import typer
from models import Site
def write(site: Site, output_directory: str):
"""Write site content: articles, tags, categories and archives.
Args:
site (Site): L'ensemble des articles à écrire.
output_directory (Path)
"""
if not os.path.exists(output_directory):
os.makedirs(output_directory)
template_env = Environment(loader=FileSystemLoader('./templates'))
template = template_env.get_template("articles-list.html")
articles_content = template.render(
articles=sorted(site.articles, key=lambda x: x.date, reverse=True)
)
with codecs.open(os.path.join(output_directory, "index.html"), "w", "utf-8-sig") as output:
output.write(articles_content)
article_template = template_env.get_template("article.html")
for article in site.articles:
html = markdown(article.content, extensions=['fenced_code', 'codehilite'])
article_content = article_template.render(article=article, content=html)
output_article_directory = os.path.join(
output_directory,
os.sep.join(article.relative_filepath)
)
if not os.path.exists(output_article_directory):
os.makedirs(output_article_directory)
output_article_path = os.path.join(
output_article_directory,
article.filename.replace(".md", ".html")
)
with codecs.open(output_article_path, "w", "utf-8-sig") as article_file:
article_file.write(article_content)
def main(root_directory: str, output_directory: str):
site = Site(root_directory)
for root, dirs, files in os.walk(root_directory, topdown=False):
for filename in [x for x in files if x.endswith(".md")]:
site.add(root, filename)
logging.info(
"Parsing is finished; site has {} elements".format(len(site.articles))
)
write(site, output_directory)
if __name__ == "__main__":
typer.run(main)

68
src/models.py Normal file
View File

@ -0,0 +1,68 @@
"""Modèles et structures d'informations."""
from datetime import datetime
import logging
import os
class Article:
def __init__(self, site_directory: str, root_directory: str, filename: str):
self.filename = filename
self.absolute_filepath = os.path.join(root_directory, filename)
self.relative_filepath = list(
set(root_directory.split(os.sep)) - set(site_directory.split(os.sep))
)
self.category = self.relative_filepath[0]
self.tags = self.relative_filepath[1:]
self.date = datetime.strptime(filename[0:10], "%Y-%m-%d")
with open(self.absolute_filepath, "r", encoding="utf-8") as article:
self.content = article.readlines()
if self.content:
self.title = self.content[0]
self.content = "\n".join(self.content[1:])
else:
self.content = ""
self.url = os.path.join(
"\n".join(self.relative_filepath),
self.filename.replace(".md", ".html")
)
class Site:
"""Un site est composé d'un ensemble d'articles.
Chaque article est associé à
* une catégorie (éventuellement par défaut)
* un ou plusieurs tags (éventuellement zéro :-p)
"""
def __init__(self, root_directory: str):
self.root_directory = root_directory
self.articles = []
self.categories = {}
self.tags = {}
def add(self, folder: str, article_filepath: str):
"""Ajoute un nouvel article au site actuel.
Args:
article (Article): Le nouvel article à ajouter à ceux existants.
"""
try:
article = Article(self.root_directory, folder, article_filepath)
logging.info("Append article {}".format(article))
self.articles.append(article)
category = self.categories.setdefault(article.category, [])
category.append(article)
for tag in article.tags:
tag_key = self.tags.setdefault(tag, [])
tag_key.append(article)
except ValueError as value_error:
logging.warn("Article does not support {}".format(value_error))

8
templates/article.html Normal file
View File

@ -0,0 +1,8 @@
{% extends "base.html" %}
{% block content %}
<h1>Article</h1>
{{ content|safe }}
{% endblock %}

View File

@ -0,0 +1,24 @@
{% extends "base.html" %}
{% block content %}
<h1>Articles list</h1>
<ul>
{% for year, year_group in articles|groupby('date.year') %}
<li>{{ year }}
<ul>
{% for month, list in year_group|groupby('date.month') %}
<li>{{ month }}
<ul>
{% for article in list %}
<li><a href="{{ article.url }}">{{ article.title }}</a></li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
{% endblock %}

3
templates/base.html Normal file
View File

@ -0,0 +1,3 @@
{% block content %}
{% endblock %}