Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fonctionnalité : ajoute une page listant les derniers articles #917

Draft
wants to merge 20 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/workflows/pr_checker_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,18 @@ jobs:
if: ${{ github.repository_owner == 'geotribu' }}

steps:
- name: Install French locale
id: locale-fr
shell: bash
run: |
sudo locale-gen fr_FR.UTF-8
sudo update-locale LANG=fr_FR.UTF-8

- name: Get source code
uses: actions/checkout@v4



- name: Set up Python
uses: actions/setup-python@v5
with:
Expand Down
1 change: 1 addition & 0 deletions content/articles/.pages
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
title: "📖 Articles"

nav:
- "Derniers articles": index.md
- "2024"
- "2023"
- "2022"
Expand Down
13 changes: 13 additions & 0 deletions content/articles/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
title: "Liste des derniers articles parus"
template: custom_templates/index_articles.html
# theme customizations
hide:
- footer
- navigation
- toc
search:
exclude: true
---

<!-- Page qui utilise un template personnalisé (cf clé "template" dans l'en-tête) -->
74 changes: 74 additions & 0 deletions content/theme/custom_templates/index_articles.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
{% extends "base.html" %}

{% block styles %}
{{ super() }}

<link rel=stylesheet href=../theme/assets/stylesheets/homepage.min.css>
{% endblock %}

<!-- Render hero under tabs -->
{% block tabs %}
{{ super() }}

<!-- Hero for landing page -->
<div class="tx-container">
<div class="md-grid md-typeset">
<div class="tx-hero">
<div class="tx-hero__title">
<h1 style="visibility: hidden">Geotribu</h1>
</div>
<div class="tx-hero__image">
<img src="https://cdn.geotribu.fr/img/internal/charte/geotribu_logo_rectangle_384x80.png"
alt="Bannière Geotribu" draggable="false" title="logo Geotribu">
</div>
<div class="tx-hero__content">
<p>Site collaboratif sur la géomatique <span class="em">libre</span> et <span class="em">ouverte</span>.</p>
</div>
</div>
</div>
</div>

<!-- Content -->
<div class="md-container secondary-section">
<div class="g">
{% if config.extra.latest %}{% for contenu in config.extra.latest.articles %}
<div class="section" id="articles">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

J'aurais tendance à proposer de baisser le padding vertical de la classe section, en version mobile je trouve qu'il y a beaucoup d'espace vide entre chaque article:

image

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clairement, c'est pas beau pour l'instant...

<div class="component-wrapper">
<div class="first-column">
<a class="toclink" href="/{{ contenu.url_rel | default('/') }}">
<h3>{{ contenu.title | default('Titre') }}</h3>
</a>

{% if contenu.subtitle %}<h4>{{ contenu.subtitle | default('Sous-titre') }}</h4>{%
endif
%}
{% for tag in contenu.tags %}
<a class="md-tag md-tag-icon" href="/tags/#tag:{{ tag | lower }}">{{ tag }}</a>{{ ", " if not loop.last else
"" }}
{% endfor %}
<h5>{{ "Publié le {}".format(contenu.date_txt_long) |
default('vendredi 9 août 1985') }} par {{ contenu.authors | default('Prénom NOM') | join(", ") }}</h5>
<p>{{ contenu.description | default('Description') }}</p>
<a href="/{{ contenu.url_rel | default('/') }}" class="md-button">Lire cet article...</a>
</div>
<div class="second-column">
<div class="image-wrapper">
<a href="/{{ contenu.url_rel | default('/') }}" hreflang="{{ contenu.language | default('fr') }}"
title="Lien vers le dernier article">
<img
src="{{ contenu.image | default('https://cdn.geotribu.fr/img/internal/charte/geotribu_logo_rectangle_384x80.png') }}"
alt="Illustration du dernier article publié" decoding="async" loading="lazy" draggable="false">
<div class="image-overlay">{{ contenu.title | default('Placeholder') }}, par {{
contenu.authors | default('Prénom NOM') | join(", ") }}</div>
</a>
</div>
</div>
</div>
</div>
{% endfor %}{% endif %}

</div>
</div>


{% endblock %}
16 changes: 14 additions & 2 deletions scripts/050_mkdocs_populate_latest.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

# 3rd party
import yaml
from babel.dates import format_date
from mkdocs.structure.pages import Page
from mkdocs.utils import yaml_load
from mkdocs.utils.meta import get_data
Expand Down Expand Up @@ -83,15 +84,26 @@ def get_latest_content(

page_meta = get_data(source)[1]

date_txt_long = format_date(
date=page_meta.get("date"), format="long", locale="fr_FR"
)

page_rel = str(content.relative_to("content/"))[:-3]

if page_meta.get("image") is None or page_meta.get("image") == "":
social_card_url = f"{social_card_image_base}{page_rel}.png"
output_contents_list.append(
get_data(source)[1] | {"url_rel": page_rel} | {"image": social_card_url}
get_data(source)[1]
| {"url_rel": page_rel}
| {"image": social_card_url}
| {"date_txt_long": date_txt_long}
)
else:
output_contents_list.append(get_data(source)[1] | {"url_rel": page_rel})
output_contents_list.append(
get_data(source)[1]
| {"url_rel": page_rel}
| {"date_txt_long": date_txt_long}
)

return output_contents_list

Expand Down
117 changes: 117 additions & 0 deletions scripts/mkdocs_populate_latest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#! python3 # noqa: E265

"""Script permettant de lister les derniers contenus avec leurs propriétés
dans un fichier YAML. Utilisé pour la page d'accueil et les pages
d'index des derniers contenus publiés.
"""

# ############################################################################
# ########## Libraries #############
# ##################################

# standard library
import locale
import logging
from datetime import datetime
from pathlib import Path
from typing import Literal
from zoneinfo import ZoneInfo

# 3rd party
import yaml
from mkdocs.structure.pages import Page
from mkdocs.utils.meta import get_data

# ###########################################################################
# ########## Global ################
# ##################################

# journalisation
logger = logging.getLogger("mkdocs")

# gestion des dates
config_tz = ZoneInfo("Europe/Paris")
locale.setlocale(locale.LC_TIME, "fr_FR.UTF-8")

# ###########################################################################
# ########## Functions #############
# ##################################


def format_datetime(in_datetime_string: str, out_format: str = "long") -> str:
"""Formatte un datetime au format textuel standard (isocalendar) en version textuelle.
Proche du fonctionnement de 'babel.format_date'.

:param str in_datetime_string: chaîne de caractères en entrée. Doit être au format ISO.
:param str out_format: format de sortie, defaults to "long"

:return str: chaîne de caractères formatée
"""
dt = datetime.fromisoformat(in_datetime_string).replace(tzinfo=config_tz)
if out_format == "long":
return dt.strftime("%A %d %B %Y")


def get_latest_content(
content_type: Literal["articles", "rdp"], count: int = 10
) -> list[dict]:
"""Liste les X (défini par 'count') derniers contenus d'un certain type
en retournant les métadonnées de chaque contenu, ainsi que quelques
attributs personnalisés.

:param Literal[&quot;articles&quot;, &quot;rdp&quot;] content_type: type de contenu à lister
:param int count: nombre de contenus à lister, defaults to 10

:return list[dict]: liste des contenus avec leurs attributs
"""
output_contents_list: list[Page] = []

if content_type == "articles":
glob_pattern = "202*/202*.md"
elif content_type == "rdp":
glob_pattern = "202*/rdp_202*.md"

for content in sorted(
Path(f"content/{content_type}/").glob(glob_pattern), reverse=True
)[:count]:
with content.open(encoding="utf-8-sig", errors="strict") as f:
source = f.read()
# markdown, meta = get_data(source)

# ajout attributs personnalisés
output_contents_list.append(
# ajout URL relative
get_data(source)[1]
| {"url_rel": str(content.relative_to("content/"))[:-3]}
# ajoute la date au format textuel
| {
"date_txt_full": format_datetime(
in_datetime_string=get_data(source)[1].get("date"),
out_format="long",
)
}
)

return output_contents_list


# ###########################################################################
# ########## Main ##################
# ##################################

output_dict = {"latest": {"articles": [], "rdp": []}}
# print(get_latest_content(content_type="articles"))
for k in output_dict.get("latest"):
output_dict["latest"][k] = get_latest_content(content_type=k)

# écrit le fichier final
with Path("config/extra_latest.yml").open("w", encoding="UTF-8") as out_file:
yaml.safe_dump(
output_dict,
out_file,
allow_unicode=True,
default_flow_style=False,
encoding="UTF8",
# indent=4,
sort_keys=True,
)
Loading