feat(glossaire): extend taxonomy and align Astro 6 content config
This commit is contained in:
@@ -3,19 +3,323 @@ import SiteLayout from "../../layouts/SiteLayout.astro";
|
||||
import { getCollection } from "astro:content";
|
||||
|
||||
const entries = await getCollection("glossaire");
|
||||
entries.sort((a, b) => a.data.term.localeCompare(b.data.term, "fr"));
|
||||
|
||||
const slugOf = (entry) => String(entry.id).replace(/\.(md|mdx)$/i, "");
|
||||
const hrefOf = (entry) => `/glossaire/${slugOf(entry)}/`;
|
||||
|
||||
const collator = new Intl.Collator("fr", { sensitivity: "base", numeric: true });
|
||||
|
||||
const sorted = [...entries].sort((a, b) => collator.compare(a.data.term, b.data.term));
|
||||
|
||||
function groupByInitial(list) {
|
||||
const map = new Map();
|
||||
|
||||
for (const entry of list) {
|
||||
const letter = (entry.data.term || "").trim().charAt(0).toUpperCase() || "#";
|
||||
if (!map.has(letter)) map.set(letter, []);
|
||||
map.get(letter).push(entry);
|
||||
}
|
||||
|
||||
return [...map.entries()].sort((a, b) => collator.compare(a[0], b[0]));
|
||||
}
|
||||
|
||||
const groupedAlpha = groupByInitial(sorted);
|
||||
|
||||
const byPredicate = (fn) => sorted.filter(fn);
|
||||
|
||||
const fondamentaux = byPredicate(
|
||||
(e) => e.data.kind === "concept" && e.data.level === "fondamental"
|
||||
);
|
||||
|
||||
const intermediaires = byPredicate(
|
||||
(e) => e.data.kind === "concept" && e.data.level === "intermediaire"
|
||||
);
|
||||
|
||||
const avances = byPredicate(
|
||||
(e) => e.data.kind === "concept" && e.data.level === "avance"
|
||||
);
|
||||
|
||||
const diagnostics = byPredicate((e) => e.data.kind === "diagnostic");
|
||||
const topologies = byPredicate((e) => e.data.kind === "topologie");
|
||||
const verbes = byPredicate((e) => e.data.kind === "verbe");
|
||||
const paradigmes = byPredicate((e) => e.data.kind === "paradigme");
|
||||
---
|
||||
|
||||
<SiteLayout title="Glossaire archicratique">
|
||||
<h1>Glossaire archicratique</h1>
|
||||
<ul>
|
||||
{entries.map((e) => (
|
||||
<li>
|
||||
<a href={`/glossaire/${String(e.id).replace(/\.(md|mdx)$/i, "")}/`}>
|
||||
{e.data.term}
|
||||
</a>{" "}
|
||||
— <em>{e.data.definitionShort}</em>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</SiteLayout>
|
||||
<section class="glossary-home">
|
||||
<header class="glossary-hero">
|
||||
<p class="glossary-kicker">Référentiel terminologique</p>
|
||||
<h1>Glossaire archicratique</h1>
|
||||
<p class="glossary-intro">
|
||||
Ce glossaire rassemble les concepts, diagnostics, topologies et verbes
|
||||
utiles à la lecture du paradigme archicratique. Son organisation repose
|
||||
sur les métadonnées de chaque entrée afin de maintenir une structure
|
||||
cohérente, extensible et lisible.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<nav class="glossary-toc" aria-label="Sommaire du glossaire">
|
||||
<a href="#reperes">Repères</a>
|
||||
<a href="#paradigmes">Paradigmes mobilisés</a>
|
||||
{paradigmes.length > 0 && (
|
||||
<section id="paradigmes" class="glossary-section">
|
||||
<h2>Paradigmes mobilisés</h2>
|
||||
<p class="glossary-intro">
|
||||
Ces entrées ne relèvent pas du noyau conceptuel archicratique au sens strict.
|
||||
Elles désignent les cadres théoriques, paradigmes ou traditions de pensée
|
||||
avec lesquels l’archicratie entre en dialogue, en déplacement ou en différenciation.
|
||||
</p>
|
||||
|
||||
<div class="glossary-cards">
|
||||
{paradigmes.map((e) => (
|
||||
<a class="glossary-card" href={hrefOf(e)}>
|
||||
<strong>{e.data.term}</strong>
|
||||
<span>{e.data.definitionShort}</span>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
<a href="#alphabetique">Index alphabétique</a>
|
||||
</nav>
|
||||
|
||||
<section id="reperes" class="glossary-section">
|
||||
<h2>Repères</h2>
|
||||
|
||||
{fondamentaux.length > 0 && (
|
||||
<section class="glossary-block">
|
||||
<h3>Repères fondamentaux</h3>
|
||||
<div class="glossary-cards">
|
||||
{fondamentaux.map((e) => (
|
||||
<a class="glossary-card" href={hrefOf(e)}>
|
||||
<strong>{e.data.term}</strong>
|
||||
<span>{e.data.definitionShort}</span>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{intermediaires.length > 0 && (
|
||||
<section class="glossary-block">
|
||||
<h3>Concepts intermédiaires</h3>
|
||||
<div class="glossary-cards">
|
||||
{intermediaires.map((e) => (
|
||||
<a class="glossary-card" href={hrefOf(e)}>
|
||||
<strong>{e.data.term}</strong>
|
||||
<span>{e.data.definitionShort}</span>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{avances.length > 0 && (
|
||||
<section class="glossary-block">
|
||||
<h3>Concepts avancés</h3>
|
||||
<div class="glossary-cards">
|
||||
{avances.map((e) => (
|
||||
<a class="glossary-card" href={hrefOf(e)}>
|
||||
<strong>{e.data.term}</strong>
|
||||
<span>{e.data.definitionShort}</span>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{diagnostics.length > 0 && (
|
||||
<section class="glossary-block">
|
||||
<h3>Diagnostics</h3>
|
||||
<div class="glossary-cards">
|
||||
{diagnostics.map((e) => (
|
||||
<a class="glossary-card" href={hrefOf(e)}>
|
||||
<strong>{e.data.term}</strong>
|
||||
<span>{e.data.definitionShort}</span>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{topologies.length > 0 && (
|
||||
<section class="glossary-block">
|
||||
<h3>Topologies</h3>
|
||||
<div class="glossary-cards">
|
||||
{topologies.map((e) => (
|
||||
<a class="glossary-card" href={hrefOf(e)}>
|
||||
<strong>{e.data.term}</strong>
|
||||
<span>{e.data.definitionShort}</span>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{verbes.length > 0 && (
|
||||
<section class="glossary-block">
|
||||
<h3>Verbes de la scène archicratique</h3>
|
||||
<div class="glossary-cards">
|
||||
{verbes.map((e) => (
|
||||
<a class="glossary-card" href={hrefOf(e)}>
|
||||
<strong>{e.data.term}</strong>
|
||||
<span>{e.data.definitionShort}</span>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
</section>
|
||||
|
||||
<section id="alphabetique" class="glossary-section">
|
||||
<h2>Index alphabétique</h2>
|
||||
|
||||
<nav class="glossary-alpha-nav" aria-label="Lettres du glossaire">
|
||||
{groupedAlpha.map(([letter]) => (
|
||||
<a href={`#letter-${letter}`}>{letter}</a>
|
||||
))}
|
||||
</nav>
|
||||
|
||||
<div class="glossary-alpha-groups">
|
||||
{groupedAlpha.map(([letter, items]) => (
|
||||
<section class="glossary-letter-group" id={`letter-${letter}`}>
|
||||
<h3>{letter}</h3>
|
||||
<ul class="glossary-list">
|
||||
{items.map((e) => (
|
||||
<li>
|
||||
<a href={hrefOf(e)}>{e.data.term}</a>
|
||||
<span> — {e.data.definitionShort}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
</SiteLayout>
|
||||
|
||||
<style>
|
||||
.glossary-home{
|
||||
padding: 8px 0 32px;
|
||||
}
|
||||
|
||||
.glossary-hero{
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.glossary-kicker{
|
||||
font-size: 12px;
|
||||
letter-spacing: .08em;
|
||||
text-transform: uppercase;
|
||||
opacity: .72;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.glossary-intro{
|
||||
max-width: 72ch;
|
||||
opacity: .92;
|
||||
}
|
||||
|
||||
.glossary-toc{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
margin: 18px 0 30px;
|
||||
}
|
||||
|
||||
.glossary-toc a{
|
||||
border: 1px solid rgba(127,127,127,0.28);
|
||||
border-radius: 999px;
|
||||
padding: 6px 12px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.glossary-section{
|
||||
margin-top: 34px;
|
||||
}
|
||||
|
||||
.glossary-block{
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
.glossary-cards{
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
||||
gap: 12px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.glossary-card{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
padding: 14px 16px;
|
||||
border: 1px solid rgba(127,127,127,0.22);
|
||||
border-radius: 16px;
|
||||
background: rgba(127,127,127,0.05);
|
||||
text-decoration: none;
|
||||
transition: transform 120ms ease, background 120ms ease;
|
||||
}
|
||||
|
||||
.glossary-card:hover{
|
||||
transform: translateY(-1px);
|
||||
background: rgba(127,127,127,0.08);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.glossary-card strong{
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.glossary-card span{
|
||||
font-size: 14px;
|
||||
line-height: 1.45;
|
||||
opacity: .92;
|
||||
}
|
||||
|
||||
.glossary-alpha-nav{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
margin: 12px 0 20px;
|
||||
}
|
||||
|
||||
.glossary-alpha-nav a{
|
||||
min-width: 32px;
|
||||
text-align: center;
|
||||
border: 1px solid rgba(127,127,127,0.22);
|
||||
border-radius: 10px;
|
||||
padding: 5px 8px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.glossary-alpha-groups{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.glossary-letter-group h3{
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.glossary-list{
|
||||
margin: 0;
|
||||
padding-left: 18px;
|
||||
}
|
||||
|
||||
.glossary-list li{
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark){
|
||||
.glossary-card{
|
||||
background: rgba(255,255,255,0.04);
|
||||
}
|
||||
|
||||
.glossary-card:hover{
|
||||
background: rgba(255,255,255,0.07);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user