mirror of
https://forge.chapril.org/tykayn/orgmode-to-gemini-blog
synced 2025-06-20 09:04:42 +02:00
generate tags pages with jinja template
This commit is contained in:
parent
8e32423dce
commit
367c7754c6
8 changed files with 178 additions and 42 deletions
|
@ -2,22 +2,24 @@ import argparse
|
||||||
import json
|
import json
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
|
from jinja2 import Environment, FileSystemLoader
|
||||||
|
import json
|
||||||
from utils import *
|
from utils import *
|
||||||
from website_config import *
|
from website_config import *
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description="Générer un site Web à partir de fichiers HTML.")
|
parser = argparse.ArgumentParser(description="Générer un site Web à partir de fichiers HTML.")
|
||||||
parser.add_argument("blog_name", help="Le chemin vers le dossier contenant les fichiers HTML.")
|
parser.add_argument("blog", help="Le chemin vers le dossier contenant les fichiers HTML.")
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
blog_folder = args.blog_name
|
blog_folder = args.blog
|
||||||
directory_base = f'sources/{blog_folder}' # Remplacez par le chemin de votre dossier
|
directory_base = f'sources/{blog_folder}' # Remplacez par le chemin de votre dossier
|
||||||
directory_fr = f'{directory_base}/lang_fr' # Remplacez par le chemin de votre dossier
|
directory_fr = f'{directory_base}/lang_fr' # Remplacez par le chemin de votre dossier
|
||||||
output_file = f'sources/{blog_folder}/converted/tags.json' # Fichier de sortie
|
output_file = f'sources/{blog_folder}/converted/tags.json' # Fichier de sortie
|
||||||
html_output_folder = f'html-websites/{blog_folder}/tag' # Dossier de sortie pour les fichiers HTML
|
html_output_folder = f'html-websites/{blog_folder}/tag' # Dossier de sortie pour les fichiers HTML
|
||||||
html_output_folder_index = f'html-websites/{blog_folder}/tags' # Dossier de sortie pour les fichiers HTML
|
html_output_folder_index = f'html-websites/{blog_folder}/tags' # Dossier de sortie pour les fichiers HTML
|
||||||
excluded_tags = {'PROPERTIES', 'CREATED', 'ID', 'END'}
|
excluded_tags = {'PROPERTIES', 'CREATED', 'ID', 'END', 'CUSTOM_ID'}
|
||||||
automatic_tagging_enabled = global_config['automatic_tagging_enabled']
|
automatic_tagging_enabled = global_config['automatic_tagging_enabled']
|
||||||
|
|
||||||
count_not_tagged_files = 0
|
count_not_tagged_files = 0
|
||||||
|
@ -100,31 +102,34 @@ def generate_html_pages_for_all_tags(tag_to_files, html_output_folder):
|
||||||
|
|
||||||
|
|
||||||
def generate_index_page(tag_to_files, html_output_folder):
|
def generate_index_page(tag_to_files, html_output_folder):
|
||||||
index_content = f"""
|
|
||||||
<body>
|
|
||||||
<div id="tags_page">
|
|
||||||
<h1>Index des tags</h1>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
"""
|
template_content = configs_sites[args.blog]
|
||||||
|
|
||||||
|
# Charger le template Jinja2
|
||||||
|
env = Environment(loader=FileSystemLoader('.'))
|
||||||
|
template = env.get_template('templates/html/tag.html.jinja')
|
||||||
sorted_tags = sorted(tag_to_files.items())
|
sorted_tags = sorted(tag_to_files.items())
|
||||||
print(f" generate tags pages and index : {len(sorted_tags)}")
|
|
||||||
|
|
||||||
for tag, files in sorted_tags:
|
tags_count = {tag: len(files) for tag, files in sorted_tags}
|
||||||
file_count = len(files)
|
|
||||||
index_content += f" <li><a href='/tag/{tag}.html'>{tag}</a> ({file_count})</li>\n"
|
|
||||||
|
|
||||||
index_content += """
|
print(tags_count)
|
||||||
</ul>
|
|
||||||
</div>
|
# Préparer les données pour le template
|
||||||
</body>
|
data = {
|
||||||
"""
|
'tags': tags_count,
|
||||||
|
'template_content' : template_content,
|
||||||
|
'html_output_folder': html_output_folder
|
||||||
|
}
|
||||||
|
|
||||||
|
# Rendre le template avec les données
|
||||||
|
output_html = template.render(data)
|
||||||
|
|
||||||
os.makedirs(os.path.dirname(html_output_folder_index), exist_ok=True)
|
os.makedirs(os.path.dirname(html_output_folder_index), exist_ok=True)
|
||||||
|
|
||||||
index_file_path = os.path.join(html_output_folder_index, "index.html")
|
index_file_path = os.path.join(html_output_folder_index, "index.html")
|
||||||
with open(index_file_path, 'w', encoding='utf-8') as index_file:
|
with open(index_file_path, 'w', encoding='utf-8') as index_file:
|
||||||
index_file.write(index_content)
|
index_file.write(output_html)
|
||||||
|
|
||||||
print(f"Page d'index générée dans {index_file_path}")
|
print(f"Page d'index générée dans {index_file_path}")
|
||||||
|
|
||||||
|
@ -140,4 +145,4 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
print(f"Tags et fichiers associés ont été enregistrés dans {output_file}")
|
print(f"Tags et fichiers associés ont été enregistrés dans {output_file}")
|
||||||
print(f"Pages HTML générées dans {html_output_folder}")
|
print(f"Pages HTML générées dans {html_output_folder}")
|
||||||
# print(f"Pages non tagguées: {count_not_tagged_files}") # TODO
|
print(f"Pages non tagguées: {count_not_tagged_files}")
|
||||||
|
|
|
@ -576,18 +576,18 @@ href="https://medium.com/tag/fukushima?source=post_page-----f82c1d15ed58--------
|
||||||
|
|
||||||
<a href="/tags/"></a>
|
<a href="/tags/"></a>
|
||||||
|
|
||||||
<a href="/tags/logiciel">logiciel</a>
|
<a href="/tags/art">art</a>
|
||||||
|
|
||||||
<a href="/tags/entreprise">entreprise</a>
|
<a href="/tags/entreprise">entreprise</a>
|
||||||
|
|
||||||
<a href="/tags/AI">AI</a>
|
|
||||||
|
|
||||||
<a href="/tags/art">art</a>
|
|
||||||
|
|
||||||
<a href="/tags/bd">bd</a>
|
<a href="/tags/bd">bd</a>
|
||||||
|
|
||||||
<a href="/tags/cours">cours</a>
|
<a href="/tags/cours">cours</a>
|
||||||
|
|
||||||
|
<a href="/tags/AI">AI</a>
|
||||||
|
|
||||||
|
<a href="/tags/logiciel">logiciel</a>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
|
@ -603,7 +603,7 @@ href="https://medium.com/tag/fukushima?source=post_page-----f82c1d15ed58--------
|
||||||
|
|
||||||
|
|
||||||
<a href="" class="next-article">Article suivant:
|
<a href="" class="next-article">Article suivant:
|
||||||
<div class="next-acticle-title"><built-in method title of str object at 0x7fc37c4c3f00></div>
|
<div class="next-acticle-title"><built-in method title of str object at 0x7f7ac531a4c0></div>
|
||||||
|
|
||||||
</a>
|
</a>
|
||||||
<!-- // TODO corriger les précédents et suivants, ajouter le titre -->
|
<!-- // TODO corriger les précédents et suivants, ajouter le titre -->
|
||||||
|
|
|
@ -83,7 +83,7 @@
|
||||||
|
|
||||||
<div class="first-picture-container">
|
<div class="first-picture-container">
|
||||||
<a href="2025/pouet-pouet-hop">
|
<a href="2025/pouet-pouet-hop">
|
||||||
<img class="first-picture" src="https://placehold.co/600x400/png" />
|
<img class="first-picture" src="https://miro.medium.com/v2/resize:fit:490/0*R7R5WF5O-tznduZZ.jpg" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -97,10 +97,11 @@
|
||||||
29 January 2025 à 14:35:36
|
29 January 2025 à 14:35:36
|
||||||
</div>
|
</div>
|
||||||
<div><h1 id="pouet-pouet-hop-1">pouet pouet hop</h1>
|
<div><h1 id="pouet-pouet-hop-1">pouet pouet hop</h1>
|
||||||
<p><a
|
|
||||||
href="https://placehold.co/600x400/png">https://placehold.co/600x400/png</a></p>
|
|
||||||
<p>coin coin <img
|
<p>coin coin <img
|
||||||
src="https://miro.medium.com/v2/resize:fit:490/0*R7R5WF5O-tznduZZ.jpg" /></p>
|
src="https://miro.medium.com/v2/resize:fit:490/0*R7R5WF5O-tznduZZ.jpg" /></p>
|
||||||
|
<p><a
|
||||||
|
href="https://placehold.co/600x400/png">https://placehold.co/600x400/png</a></p>
|
||||||
|
<p>lorem bla bla</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="article-tags">
|
<div class="article-tags">
|
||||||
|
|
||||||
|
|
|
@ -58,10 +58,15 @@ for file_name in os.listdir(directory):
|
||||||
if isinstance(tags, set):
|
if isinstance(tags, set):
|
||||||
tags = list(tags)
|
tags = list(tags)
|
||||||
boom = basename.split('__')
|
boom = basename.split('__')
|
||||||
|
# Convertir le contenu Org en HTML
|
||||||
title = find_first_level1_title(content)
|
title = find_first_level1_title(content)
|
||||||
|
|
||||||
# Convertir le contenu Org en HTML
|
# Désactiver les warning d'identifiant dupliqué dans la conversion pandoc
|
||||||
html_content = pypandoc.convert_text(content, 'html', format='org')
|
content_without_h1 = re.sub(r'^\*.*?$', '', content, count=1, flags=re.MULTILINE)
|
||||||
|
|
||||||
|
html_content = pypandoc.convert_text(content_without_h1, 'html', format='org')
|
||||||
|
|
||||||
|
# html_content = pypandoc.convert_text(content, 'html', format='org')
|
||||||
|
|
||||||
files_dict[f"{annee}/{slug}"] = {
|
files_dict[f"{annee}/{slug}"] = {
|
||||||
'path': file_path,
|
'path': file_path,
|
||||||
|
@ -186,8 +191,6 @@ def generate_article_pages(json_file, template_file, output_dir):
|
||||||
with open(output_file, 'w', encoding='utf-8') as f:
|
with open(output_file, 'w', encoding='utf-8') as f:
|
||||||
f.write(output_html)
|
f.write(output_html)
|
||||||
|
|
||||||
# print(f"Page générée pour l'article {article['title']} dans {output_file}")
|
|
||||||
|
|
||||||
# Appel de la fonction pour générer les pages des articles
|
# Appel de la fonction pour générer les pages des articles
|
||||||
generate_article_pages(destination_json + '/articles_info.json', 'templates/html/article.html.jinja', destination_html)
|
generate_article_pages(destination_json + '/articles_info.json', 'templates/html/article.html.jinja', destination_html)
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,11 @@
|
||||||
* pouet pouet hop
|
* pouet pouet hop
|
||||||
#+CAPTION: This is the caption for the next figure
|
#+CAPTION: This is the caption for the next figure
|
||||||
#+NAME: fig:placeland
|
#+NAME: fig:placeland
|
||||||
[[https://placehold.co/600x400/png]]
|
|
||||||
|
|
||||||
coin coin
|
coin coin
|
||||||
[[https://miro.medium.com/v2/resize:fit:490/0*R7R5WF5O-tznduZZ.jpg]]
|
[[https://miro.medium.com/v2/resize:fit:490/0*R7R5WF5O-tznduZZ.jpg]]
|
||||||
|
|
||||||
|
|
||||||
|
[[https://placehold.co/600x400/png]]
|
||||||
|
|
||||||
|
lorem bla bla
|
|
@ -28,8 +28,8 @@
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="page" class="page__{{template_content[" PAGE_SLUG"]}}">
|
<div id="page" class="page_article page__{{template_content['PAGE_SLUG']}} ">
|
||||||
<header id="masthead" class="site-header">
|
<header id=" masthead" class="site-header">
|
||||||
<div class="header-image" style="background-image: url('{{template_content[" BANNIERE_ENTETE"]}}');
|
<div class="header-image" style="background-image: url('{{template_content[" BANNIERE_ENTETE"]}}');
|
||||||
background-repeat: no-repeat; background-size: cover;">
|
background-repeat: no-repeat; background-size: cover;">
|
||||||
<a href="/">
|
<a href="/">
|
||||||
|
@ -73,7 +73,9 @@
|
||||||
<main class="body-wrap boxed-container">
|
<main class="body-wrap boxed-container">
|
||||||
|
|
||||||
<article class="content">
|
<article class="content">
|
||||||
|
<h1 class="article-title">
|
||||||
|
{{ article.title }}
|
||||||
|
</h1>
|
||||||
<div class="article-main-content">{{ article.html_content | safe }}</div>
|
<div class="article-main-content">{{ article.html_content | safe }}</div>
|
||||||
<div class="article-date">
|
<div class="article-date">
|
||||||
{{article.date_formattee}}
|
{{article.date_formattee}}
|
||||||
|
@ -83,7 +85,7 @@
|
||||||
{% if article.tags %}
|
{% if article.tags %}
|
||||||
Tags:
|
Tags:
|
||||||
{% for tag in article.tags %}
|
{% for tag in article.tags %}
|
||||||
<a href="/tags/{{ tag }}">{{ tag }}</a>
|
<a href="/tag/{{ tag }}">{{ tag }}</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
118
templates/html/tag.html.jinja
Normal file
118
templates/html/tag.html.jinja
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta property="og:image" content="{{template_content['SITE_ICON']}}">
|
||||||
|
<meta property="og:locale" content="{{template_content['LOCALE']}}">
|
||||||
|
<meta property="og:description" content="{{template_content['BLOG_SUBTITLE']}}">
|
||||||
|
<meta property="og:url" content="{{template_content['NDD']}}">
|
||||||
|
<meta property="og:site_name" content="{{template_content['TITLE']}}">
|
||||||
|
<link rel="alternate" type="application/atom+xml" title="Cipher Bliss » Flux"
|
||||||
|
href="{{template_content['NDD']}}/feed/">
|
||||||
|
<link href="/style.css" rel="stylesheet">
|
||||||
|
<script src="main_script.js"></script>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>{{template_content['TITLE']}}</title>
|
||||||
|
<meta name="author" content="{{template_content['AUTHOR']}}">
|
||||||
|
<link rel="alternate" type="application/rss+xml" title="{{template_content['BLOG_TITLE']}} » Flux"
|
||||||
|
href="{{template_content['NDD']}}/feed/">
|
||||||
|
<meta property="og:title" content="{{template_content['PAGE_TITLE']}}">
|
||||||
|
<meta property="og:locale" content="{{template_content['LOCALE']}}">
|
||||||
|
<!-- Description de la page -->
|
||||||
|
<meta name="description" content="{{template_content['PAGE_TITLE']}}">
|
||||||
|
<meta name="reply-to" content="{{template_content['EMAIL']}}">
|
||||||
|
<link rel="icon" type="{{template_content['SITE_ICON_TYPE']}}" href="{{template_content['SITE_ICON']}}">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="page" class="page_article page__{{template_content['PAGE_SLUG']}} ">
|
||||||
|
<header id=" masthead" class="site-header">
|
||||||
|
<div class="header-image" style="background-image: url('{{template_content[" BANNIERE_ENTETE"]}}');
|
||||||
|
background-repeat: no-repeat; background-size: cover;">
|
||||||
|
<a href="/">
|
||||||
|
<img src="{{template_content['SITE_ICON']}}" class="site-icon img">
|
||||||
|
</a>
|
||||||
|
<h1 class="blog-title">Index des tags - {{template_content['BLOG_TITLE']}}
|
||||||
|
|
||||||
|
</h1>
|
||||||
|
<p class="blog-subtitle">{{template_content['BLOG_SUBTITLE']}}</p>
|
||||||
|
<div class="template-header">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<nav class="navbar is-fixed-top is-dark" role="navigation" aria-label="main navigation">
|
||||||
|
<div class="navbar-brand">
|
||||||
|
<a class="navbar-item" href="{{template_content['NDD']}}">
|
||||||
|
{{template_content['NDD']}}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="navbarBasicExample" class="navbar-menu">
|
||||||
|
<div class="navbar-start">
|
||||||
|
<a class="logo" href="{{template_content['NDD']}}">
|
||||||
|
<img src="{{template_content['SITE_ICON']}}" class="img-fluid">
|
||||||
|
</a>
|
||||||
|
{{template_content['NAVIGATION']}}
|
||||||
|
</div>
|
||||||
|
<div class="navbar-end">
|
||||||
|
<div class="navbar-item">
|
||||||
|
<form role="search" method="get" class="search-form" action="/" id="recherche">
|
||||||
|
<label>
|
||||||
|
<input class="search-field" placeholder="Recherche" value="" name="s" type="search">
|
||||||
|
</label>
|
||||||
|
<input class="is-hidden search-submit" value="Rechercher" type="submit">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
<main class="body-wrap boxed-container">
|
||||||
|
|
||||||
|
<article class="content">
|
||||||
|
<h1 class="article-title">
|
||||||
|
Tags
|
||||||
|
</h1>
|
||||||
|
<!-- <div class="article-main-content">
|
||||||
|
|
||||||
|
</div> -->
|
||||||
|
<div class="article-tags">
|
||||||
|
<ul>
|
||||||
|
{% for tag_key, file_count in tags.items() %}
|
||||||
|
|
||||||
|
{% if tag_key %}
|
||||||
|
<li><a href='/tag/{{tag_key}}.html'>{{tag_key}}</a> ({{file_count}})</li>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<div class="retour-accueil">
|
||||||
|
<a href="/">Retour à l'accueil</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
<footer class="site-footer has-top-divider">
|
||||||
|
<div class="container">
|
||||||
|
<div class="site-footer-inner">
|
||||||
|
<div class="site-foot">
|
||||||
|
</div>
|
||||||
|
<nav class="footer-nav">
|
||||||
|
{{template_content['NAVIGATION']}}
|
||||||
|
<a href="/tags/">Tags</a>
|
||||||
|
<a href="{{template_content['NDD']}}/feed/">Flux Atom</a>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
<!-- généré avec orgmode-to-gemini-blog par Tykayn -->
|
||||||
|
|
||||||
|
</html>
|
10
utils.py
10
utils.py
|
@ -192,9 +192,13 @@ def add_tags_from_content(tags=None, file_content="", words_to_check=None):
|
||||||
# Parcourir chaque mot à vérifier
|
# Parcourir chaque mot à vérifier
|
||||||
for word in words_to_check:
|
for word in words_to_check:
|
||||||
# Vérifier si le mot est présent dans le contenu du fichier
|
# Vérifier si le mot est présent dans le contenu du fichier
|
||||||
if word.lower() in file_content_lower:
|
# Chercher une correspondance sans mettre en lowercase si le tag est en majuscule, c'est sans doute un acronyme/sigle.
|
||||||
# Ajouter le tag correspondant à l'ensemble de tags
|
if word.isupper():
|
||||||
tags.add(word)
|
if word in file_content:
|
||||||
|
tags.add(word)
|
||||||
|
else:
|
||||||
|
if word.lower() in file_content_lower:
|
||||||
|
tags.add(word)
|
||||||
|
|
||||||
return tags
|
return tags
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue