Browse Source

Implementation of tags under /david/2021/

master
David Larlet 2 years ago
parent
commit
62be8fff80
5 changed files with 182 additions and 12 deletions
  1. 55
    0
      david/index.html
  2. 16
    0
      david/templates/article_2020.html
  3. 10
    0
      david/templates/profil.html
  4. 29
    0
      david/templates/tag_2021.html
  5. 72
    12
      site.py

+ 55
- 0
david/index.html View File

</p> </p>
<h3 id="tags">
Par tags <svg class="icon icon-tags">
<use xlink:href="/static/david/icons2/symbol-defs.svg#icon-tags"></use>
</svg>
</h3>
<p>
<a href="/david/2021/accessibilite/">#accessibilité (16)</a>
<a href="/david/2021/accompagnement/">#accompagnement (21)</a>
<a href="/david/2021/allie/">#allié (12)</a>
<a href="/david/2021/alterego/">#alterego (3)</a>
<a href="/david/2021/anarchisme/">#anarchisme (4)</a>
<a href="/david/2021/anxiete/">#anxiété (30)</a>
<a href="/david/2021/capitalocene/">#capitalocène (21)</a>
<a href="/david/2021/climat/">#climat (13)</a>
<a href="/david/2021/contemplation/">#contemplation (7)</a>
<a href="/david/2021/cooperative/">#coopérative (6)</a>
<a href="/david/2021/design/">#design (9)</a>
<a href="/david/2021/ecole/">#école (8)</a>
<a href="/david/2021/ecriture/">#écriture (13)</a>
<a href="/david/2021/etiquette/">#étiquette (2)</a>
<a href="/david/2021/exploration/">#exploration (5)</a>
<a href="/david/2021/feminisme/">#féminisme (3)</a>
<a href="/david/2021/foret/">#forêt (39)</a>
<a href="/david/2021/frugalite/">#frugalité (6)</a>
<a href="/david/2021/gafam/">#gafam (14)</a>
<a href="/david/2021/gratitude/">#gratitude (15)</a>
<a href="/david/2021/inclassable/">#inclassable (4)</a>
<a href="/david/2021/incompetence/">#incompétence (33)</a>
<a href="/david/2021/lecture/">#lecture (11)</a>
<a href="/david/2021/materiel/">#matériel (4)</a>
<a href="/david/2021/misanthropie/">#misanthropie (23)</a>
<a href="/david/2021/neige/">#neige (7)</a>
<a href="/david/2021/open-source/">#open-source (12)</a>
<a href="/david/2021/pandemie/">#pandémie (38)</a>
<a href="/david/2021/parentalite/">#parentalité (11)</a>
<a href="/david/2021/partage/">#partage (23)</a>
<a href="/david/2021/pharmakon/">#pharmakon (10)</a>
<a href="/david/2021/poesie/">#poésie (4)</a>
<a href="/david/2021/premieres-nations/">#premières-nations (4)</a>
<a href="/david/2021/produit/">#produit (16)</a>
<a href="/david/2021/protopie/">#protopie (3)</a>
<a href="/david/2021/publication/">#publication (15)</a>
<a href="/david/2021/recherche/">#recherche (25)</a>
<a href="/david/2021/rythme/">#rythme (18)</a>
<a href="/david/2021/scopyleft/">#scopyleft (4)</a>
<a href="/david/2021/sociologie/">#sociologie (26)</a>
<a href="/david/2021/technique/">#technique (47)</a>
<a href="/david/2021/traces/">#traces (15)</a>
<a href="/david/2021/transformation/">#transformation (45)</a>
<a href="/david/2021/travail/">#travail (14)</a>
<a href="/david/2021/utilisateur-ice/">#utilisateur·ice (5)</a>
<a href="/david/2021/video/">#vidéo (20)</a>
<a href="/david/2021/web/">#web (23)</a>
</p>
</nav> </nav>


<h2>Publications 2020</h2> <h2>Publications 2020</h2>

+ 16
- 0
david/templates/article_2020.html View File

</nav> </nav>
<hr> <hr>
{{ page.content }} {{ page.content }}
{% if page.tags %}
<nav>
<p>
{% for tag in page.tags %}
<a href="/david/2021/{{ slugify(tag) }}/"
title="Liste de tous les articles associés à cette étiquette"
>#{{ tag }}</a>
{% endfor %}
<a href="/david/#tags"
title="Liste de toutes les étiquettes existantes"
><svg class="icon icon-tags">
<use xlink:href="/static/david/icons2/symbol-defs.svg#icon-tags"></use>
</svg> tous ?</a>
</p>
</nav>
{% endif%}
<nav> <nav>
<p class="center"> <p class="center">
{% if prev and not prev.is_draft %}<a rel="prev" href="{{ prev.url }}" title="Publication précédente : {{ prev.title }}">← Précédent</a> •{% endif %} {% if prev and not prev.is_draft %}<a rel="prev" href="{{ prev.url }}" title="Publication précédente : {{ prev.title }}">← Précédent</a> •{% endif %}

+ 10
- 0
david/templates/profil.html View File

{% endfor %} {% endfor %}
</p> </p>
{% endfor %} {% endfor %}
<h3 id="tags">
Par tags <svg class="icon icon-tags">
<use xlink:href="/static/david/icons2/symbol-defs.svg#icon-tags"></use>
</svg>
</h3>
<p>
{% for slug, name, counter in tags -%}
<a href="/david/2021/{{ slug }}/">#{{ name }} ({{ counter }})</a>
{% endfor %}
</p>
</nav> </nav>


<h2>Publications 2020</h2> <h2>Publications 2020</h2>

+ 29
- 0
david/templates/tag_2021.html View File

{% extends "base_2020.html" %}
{% block title %}Tag #{{ tag_name }}{% endblock %}
{% block description %}Publications relatives au tag #{{ tag_name }}{% endblock %}
{% block content %}
<header>
<h1>Publications relatives au tag #{{ tag_name }}</h1>
</header>
<nav>
<p class="center">
<a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
<use xlink:href="/static/david/icons2/symbol-defs.svg#icon-home"></use>
</svg> Accueil</a>
• <a rel="tags" href="/david/#tags" title="Liste de toutes les étiquettes"><svg class="icon icon-tags">
<use xlink:href="/static/david/icons2/symbol-defs.svg#icon-tags"></use>
</svg> Étiquettes</a>
</p>
</nav>
<hr>
<main>
<p>Liste des publications en ordre chronologique :</p>
{% for page in page_list %}
<h2><a href="{{ page.url }}" title="Lien permanent vers cet article">{{ page.title }}</a> ({{ page.date }})</h2>
<details>
<summary>Déplier pour lire le contenu de l’article</summary>
{{ page.content }}
</details>
{% endfor %}
</main>
{% endblock content %}

+ 72
- 12
site.py View File

import fnmatch import fnmatch
import locale import locale
import os import os
from collections import defaultdict
from dataclasses import dataclass from dataclasses import dataclass
from datetime import datetime, timedelta from datetime import datetime, timedelta
from html import escape from html import escape
from itertools import groupby from itertools import groupby
from pathlib import Path from pathlib import Path
from string import Template
from textwrap import dedent from textwrap import dedent
from time import perf_counter from time import perf_counter


PUBLICATION_BUFFER = TODAY - timedelta(days=7) PUBLICATION_BUFFER = TODAY - timedelta(days=7)
NB_ITEMS_IN_FEED = 30 NB_ITEMS_IN_FEED = 30


all_tags = set()
pages_by_tags = defaultdict(list)
pages_by_url = {} pages_by_url = {}




return "<mark>" + text + "</mark>" return "<mark>" + text + "</mark>"




class TagsRenderer(mistune.HTMLRenderer):
"""Make the asumption each line starting with a `#` is a tag."""

def paragraph(self, text):
if text.startswith("#"):
tags = " ".join(
f'<a href="/david/2021/{slugify(tag.strip())}/">#{tag.strip()}</a>'
for tag in text.split("#")
if tag.strip()
)
return f"<nav><p>{tags}</p></nav>\n"
return super().paragraph(text)


class FrenchTypographyRenderer(mistune.HTMLRenderer): class FrenchTypographyRenderer(mistune.HTMLRenderer):
"""Apply French typographic rules to text.""" """Apply French typographic rules to text."""






class CustomAndBlockquoteLanguageRenderer( class CustomAndBlockquoteLanguageRenderer(
FrenchTypographyRenderer, InternalLinkTitleRenderer, MarkRenderer
FrenchTypographyRenderer, InternalLinkTitleRenderer, MarkRenderer, TagsRenderer
): ):
"""Sets the English language attribute for blockquotes with `[en]` prefix.""" """Sets the English language attribute for blockquotes with `[en]` prefix."""


# In case of a figure, we do not want the (non-standard) paragraph. # In case of a figure, we do not want the (non-standard) paragraph.
if text.strip().startswith("<figure>"): if text.strip().startswith("<figure>"):
return text return text
return f"<p>{text}</p>\n"
return super().paragraph(text)


def image(self, src, alt="", title=None): def image(self, src, alt="", title=None):
full_path = STATIC / Path(src[1:]) full_path = STATIC / Path(src[1:])
class Page: class Page:
title: str title: str
content: str content: str
tags: list
file_path: str file_path: str
lang: str = "fr" lang: str = "fr"


self.full_url = f"{DOMAIN}{self.url}" self.full_url = f"{DOMAIN}{self.url}"
self.normalized_date = self.date.strftime(NORMALIZED_STRFTIME) self.normalized_date = self.date.strftime(NORMALIZED_STRFTIME)
self.escaped_title = escape(self.title) self.escaped_title = escape(self.title)
tag_template = Template(
f'<a href="{DOMAIN}/david/2021/$tag_slug/">#$tag_name</a>'
)
tag_links = " ".join(
tag_template.substitute(tag_slug=slugify(tag), tag_name=tag)
for tag in self.tags
)
self.escaped_content = escape( self.escaped_content = escape(
self.content.replace('href="/', f'href="{DOMAIN}/') self.content.replace('href="/', f'href="{DOMAIN}/')
.replace('src="/', f'src="{DOMAIN}/') .replace('src="/', f'src="{DOMAIN}/')
.replace('href="#', f'href="{self.full_url}#') .replace('href="#', f'href="{self.full_url}#')
+ f"<nav><p>{tag_links}</p></nav>"
+ '<hr/><p><a href="mailto:david@larlet.fr">Réagir ?</a></p>' + '<hr/><p><a href="mailto:david@larlet.fr">Réagir ?</a></p>'
) )
# Extract first paragraph. # Extract first paragraph.
self.extract = self.content.split("</p>", 1)[0] + "</p>" self.extract = self.content.split("</p>", 1)[0] + "</p>"


def __eq__(self, other):
return self.url == other.url

def __lt__(self, other: "Page"): def __lt__(self, other: "Page"):
if not isinstance(other, Page): if not isinstance(other, Page):
return NotImplemented return NotImplemented
title, content = result.split("</h1>", 1) title, content = result.split("</h1>", 1)
h1_opening_size = len("<h1>") h1_opening_size = len("<h1>")
title = title[h1_opening_size:] title = title[h1_opening_size:]
page = Page(title, content, file_name)
tags = {}
if "<nav><p>" in content:
# Extract the tags from the generated page.
content, tags_links = content.split("<nav><p>", 1)
nav_closing_size = len("</p></nav>\n")
tags_links = tags_links[:-nav_closing_size]
tags = {
tag.strip().split("#", 1)[1]
for tag in tags_links.split("</a>")
if tag.strip()
}
page = Page(title, content, tags, file_name)
pages_by_url[page.url] = page pages_by_url[page.url] = page
if not page.is_draft:
all_tags.update(tags)
for tag in tags:
if page not in pages_by_tags[tag]:
pages_by_tags[tag].append(page)
if only_published and page.is_draft: if only_published and page.is_draft:
continue continue
page_list.append(page) page_list.append(page)


@cli @cli
def pages(): def pages():
"""Build the agregations from fragments."""
"""Build article pages."""
root_path = DAVID / "2021" root_path = DAVID / "2021"
source_path = root_path / "sources" source_path = root_path / "sources"
for previous, page, next_ in neighborhood( for previous, page, next_ in neighborhood(
}, },
): ):
template = environment.get_template("article_2020.html") template = environment.get_template("article_2020.html")
content = template.render(
page=page,
prev=previous,
next=next_,
)
content = template.render(page=page, prev=previous, next=next_, slugify=slugify)
target_path = Path(page.url[1:]) target_path = Path(page.url[1:])
target_path.mkdir(parents=True, exist_ok=True) target_path.mkdir(parents=True, exist_ok=True)
open(target_path / "index.html", "w").write(content) open(target_path / "index.html", "w").write(content)
open(root_path / "index.html", "w").write(content) open(root_path / "index.html", "w").write(content)




@cli
def tags():
"""Build tags pages."""
root_path = DAVID / "2021"
source_path = root_path / "sources"
# Parse all pages to collect tags.
Page.all(source=source_path, only_published=True)
for tag in all_tags:
template = environment.get_template("tag_2021.html")
content = template.render(
page_list=pages_by_tags[tag],
tag_name=tag,
)
target_path = DAVID / "2021" / slugify(tag)
target_path.mkdir(parents=True, exist_ok=True)
open(target_path / "index.html", "w").write(content)


@cli @cli
def home(): def home():
"""Build the home page with last published items.""" """Build the home page with last published items."""
return item.date.strftime("%B %Y").title() return item.date.strftime("%B %Y").title()


template = environment.get_template("profil.html") template = environment.get_template("profil.html")
page_list = Page.all(source=DAVID / "2021" / "sources")
tags = sorted((slugify(tag), tag, len(pages_by_tags[tag])) for tag in all_tags)
content = template.render( content = template.render(
page_list=groupby(
Page.all(source=DAVID / "2021" / "sources"), key=group_by_month_year
),
page_list=groupby(page_list, key=group_by_month_year), tags=tags
) )
open(DAVID / "index.html", "w").write(content) open(DAVID / "index.html", "w").write(content)



Loading…
Cancel
Save