Render the site with parametrized paths
This commit is contained in:
parent
ae2922b78e
commit
e9183bd445
|
@ -1,3 +1,5 @@
|
|||
.vscode/*
|
||||
|
||||
# ---> Python
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
jinja2==2.11.2
|
||||
markdown==3.3
|
|
@ -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)
|
|
@ -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))
|
|
@ -0,0 +1,8 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Article</h1>
|
||||
|
||||
{{ content|safe }}
|
||||
|
||||
{% endblock %}
|
|
@ -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 %}
|
|
@ -0,0 +1,3 @@
|
|||
{% block content %}
|
||||
|
||||
{% endblock %}
|
Loading…
Reference in New Issue