refactor(glossaire): centralize aside and home data
All checks were successful
SMOKE / smoke (push) Successful in 5s
CI / build-and-anchors (push) Successful in 48s
CI / build-and-anchors (pull_request) Successful in 43s

This commit is contained in:
2026-03-25 16:48:43 +01:00
parent f7756be59e
commit ee42e391e3
4 changed files with 606 additions and 444 deletions

View File

@@ -2,6 +2,53 @@ import type { CollectionEntry } from "astro:content";
export type GlossaryEntry = CollectionEntry<"glossaire">;
export type GlossaryPortalLink = {
href: string;
label: string;
};
export type GlossaryRelationSection = {
title: string;
items: GlossaryEntry[];
};
export type GlossaryRelationBlock = GlossaryRelationSection & {
className: string;
};
export type GlossaryHomeStats = {
totalEntries: number;
paradigmesCount: number;
doctrinesCount: number;
metaRegimesCount: number;
};
export type GlossaryEntryAsideData = {
displayFamily: string;
displayDomain: string;
displayLevel: string;
showNoyau: boolean;
showSameFamily: boolean;
fondamentaux: GlossaryEntry[];
sameFamilyTitle: string;
sameFamilyEntries: GlossaryEntry[];
relationSections: GlossaryRelationSection[];
contextualTheory: GlossaryEntry[];
};
export type GlossaryHomeData = {
fondamentaux: GlossaryEntry[];
scenes: GlossaryEntry[];
dynamiques: GlossaryEntry[];
metaRegimes: GlossaryEntry[];
metaRegimesPreview: GlossaryEntry[];
arcalite?: GlossaryEntry;
cratialite?: GlossaryEntry;
tension?: GlossaryEntry;
sceneDepreuve?: GlossaryEntry;
archicration?: GlossaryEntry;
};
export const GLOSSARY_COLLATOR = new Intl.Collator("fr", {
sensitivity: "base",
numeric: true,
@@ -75,6 +122,34 @@ export const FAMILY_SECTION_TITLES: Record<string, string> = {
epistemologie: "Outillage épistémologique",
};
const PREFERRED_PARADIGME_SLUGS = [
"gouvernementalite",
"gouvernementalite-algorithmique",
"cybernetique",
"biopolitique",
"domination-legale-rationnelle",
"democratie-deliberative",
"gouvernance-des-communs",
"agencement-machinique",
"pharmacologie-technique",
"preemption-algorithmique",
"dissensus-politique",
"lieu-vide-du-pouvoir",
"habitus-et-violence-symbolique",
"theorie-de-la-resonance",
"conatus-et-multitude",
"configuration-et-interdependance",
"technodiversite-et-cosmotechnie",
"grammatisation-et-proletarisation-cognitive",
] as const;
const PREFERRED_DOCTRINE_SLUGS = [
"contractualisme-hobbesien",
"droit-naturel-et-propriete",
"volonte-generale",
"decisionnisme-souverain",
] as const;
export function normalizeGlossarySlug(value: unknown): string {
return String(value ?? "")
.trim()
@@ -99,9 +174,7 @@ export function hrefOfGlossaryEntry(
export function buildGlossaryBySlug(
entries: GlossaryEntry[] = [],
): Map<string, GlossaryEntry> {
return new Map(
entries.map((entry) => [slugOfGlossaryEntry(entry), entry]),
);
return new Map(entries.map((entry) => [slugOfGlossaryEntry(entry), entry]));
}
export function sortGlossaryEntries(
@@ -151,12 +224,12 @@ export function resolveGlossaryEntriesInSourceOrder(
}
export function resolveGlossaryEntries(
slugs: string[] = [],
allEntries: GlossaryEntry[] = [],
): GlossaryEntry[] {
return sortGlossaryEntries(
resolveGlossaryEntriesInSourceOrder(slugs, allEntries),
);
slugs: string[] = [],
allEntries: GlossaryEntry[] = [],
): GlossaryEntry[] {
return sortGlossaryEntries(
resolveGlossaryEntriesInSourceOrder(slugs, allEntries),
);
}
export function rawFamilyOf(
@@ -188,7 +261,11 @@ export function familyOf(
if (slug === "autarchicratie") return "pathologie";
if (slug === "obliteration-archicratique") return "dynamique";
if (FONDAMENTAUX_WANTED.includes(slug as (typeof FONDAMENTAUX_WANTED)[number])) {
if (
FONDAMENTAUX_WANTED.includes(
slug as (typeof FONDAMENTAUX_WANTED)[number],
)
) {
return "concept-fondamental";
}
@@ -259,6 +336,47 @@ export function countGlossaryEntriesByFamily(
return entries.filter((entry) => familyOf(entry) === familyKey).length;
}
export function getGlossaryPortalLinks(): GlossaryPortalLink[] {
return [
{ href: "/glossaire/", label: "Accueil du glossaire" },
{ href: "/glossaire/concepts-fondamentaux/", label: "Concepts fondamentaux" },
{ href: "/glossaire/index-complet/", label: "Index complet" },
{
href: "/glossaire/paradigme-archicratique/",
label: "Paradigme archicratique",
},
{
href: "/glossaire/scenes-archicratiques/",
label: "Scènes archicratiques",
},
{
href: "/glossaire/dynamiques-archicratiques/",
label: "Dynamiques archicratiques",
},
{
href: "/glossaire/tensions-irreductibles/",
label: "Tensions irréductibles",
},
{
href: "/glossaire/archicrations/",
label: "Méta-régimes archicratiques",
},
{ href: "/glossaire/paradigmes/", label: "Paradigmes et doctrines" },
{ href: "/glossaire/verbes-de-la-scene/", label: "Verbes de la scène" },
];
}
export function getGlossaryHomeStats(
allEntries: GlossaryEntry[] = [],
): GlossaryHomeStats {
return {
totalEntries: allEntries.length,
paradigmesCount: countGlossaryEntriesByKind(allEntries, "paradigme"),
doctrinesCount: countGlossaryEntriesByKind(allEntries, "doctrine"),
metaRegimesCount: countGlossaryEntriesByFamily(allEntries, "meta-regime"),
};
}
export function getEntriesOfSameFamily(
entry: GlossaryEntry,
allEntries: GlossaryEntry[] = [],
@@ -279,56 +397,50 @@ export function getSameFamilyTitle(
return FAMILY_SECTION_TITLES[familyOf(entry)] ?? "Même famille";
}
export type GlossaryRelationBlock = {
title: string;
items: GlossaryEntry[];
className: string;
};
export function getRelationBlocks(
entry: GlossaryEntry,
allEntries: GlossaryEntry[] = [],
): GlossaryRelationBlock[] {
const currentSlug = slugOfGlossaryEntry(entry);
const relatedEntries = resolveGlossaryEntriesInSourceOrder(
entry.data.related ?? [],
allEntries,
).filter((item) => slugOfGlossaryEntry(item) !== currentSlug);
const opposedEntries = resolveGlossaryEntriesInSourceOrder(
entry.data.opposedTo ?? [],
allEntries,
).filter((item) => slugOfGlossaryEntry(item) !== currentSlug);
const seeAlsoEntries = resolveGlossaryEntriesInSourceOrder(
entry.data.seeAlso ?? [],
allEntries,
).filter((item) => slugOfGlossaryEntry(item) !== currentSlug);
return [
{
title: "Concepts liés",
items: relatedEntries,
className: "is-related",
},
{
title: "En tension avec",
items: opposedEntries,
className: "is-opposed",
},
{
title: "Voir aussi",
items: seeAlsoEntries,
className: "is-see-also",
},
].filter((block) => block.items.length > 0);
}
entry: GlossaryEntry,
allEntries: GlossaryEntry[] = [],
): GlossaryRelationBlock[] {
const currentSlug = slugOfGlossaryEntry(entry);
const relatedEntries = resolveGlossaryEntriesInSourceOrder(
entry.data.related ?? [],
allEntries,
).filter((item) => slugOfGlossaryEntry(item) !== currentSlug);
const opposedEntries = resolveGlossaryEntriesInSourceOrder(
entry.data.opposedTo ?? [],
allEntries,
).filter((item) => slugOfGlossaryEntry(item) !== currentSlug);
const seeAlsoEntries = resolveGlossaryEntriesInSourceOrder(
entry.data.seeAlso ?? [],
allEntries,
).filter((item) => slugOfGlossaryEntry(item) !== currentSlug);
return [
{
title: "Concepts liés",
items: relatedEntries,
className: "is-related",
},
{
title: "En tension avec",
items: opposedEntries,
className: "is-opposed",
},
{
title: "Voir aussi",
items: seeAlsoEntries,
className: "is-see-also",
},
].filter((block) => block.items.length > 0);
}
export function getRelationSections(
entry: GlossaryEntry,
allEntries: GlossaryEntry[] = [],
): Array<{ title: string; items: GlossaryEntry[] }> {
): GlossaryRelationSection[] {
return getRelationBlocks(entry, allEntries).map(({ title, items }) => ({
title,
items,
@@ -347,34 +459,6 @@ function isTheoryEntry(entry: GlossaryEntry): boolean {
);
}
const PREFERRED_PARADIGME_SLUGS = [
"gouvernementalite",
"gouvernementalite-algorithmique",
"cybernetique",
"biopolitique",
"domination-legale-rationnelle",
"democratie-deliberative",
"gouvernance-des-communs",
"agencement-machinique",
"pharmacologie-technique",
"preemption-algorithmique",
"dissensus-politique",
"lieu-vide-du-pouvoir",
"habitus-et-violence-symbolique",
"theorie-de-la-resonance",
"conatus-et-multitude",
"configuration-et-interdependance",
"technodiversite-et-cosmotechnie",
"grammatisation-et-proletarisation-cognitive",
] as const;
const PREFERRED_DOCTRINE_SLUGS = [
"contractualisme-hobbesien",
"droit-naturel-et-propriete",
"volonte-generale",
"decisionnisme-souverain",
] as const;
export function getContextualTheory(
entry: GlossaryEntry,
allEntries: GlossaryEntry[] = [],
@@ -383,15 +467,15 @@ export function getContextualTheory(
const bySlug = buildGlossaryBySlug(allEntries);
const fromRelations = uniqueGlossaryEntries([
...resolveGlossaryEntries(entry.data.related ?? [], allEntries),
...resolveGlossaryEntries(entry.data.seeAlso ?? [], allEntries),
...resolveGlossaryEntries(entry.data.opposedTo ?? [], allEntries),
...resolveGlossaryEntriesInSourceOrder(entry.data.related ?? [], allEntries),
...resolveGlossaryEntriesInSourceOrder(entry.data.seeAlso ?? [], allEntries),
...resolveGlossaryEntriesInSourceOrder(entry.data.opposedTo ?? [], allEntries),
])
.filter((item) => slugOfGlossaryEntry(item) !== currentSlug)
.filter((item) => isTheoryEntry(item));
if (fromRelations.length > 0) {
return sortGlossaryEntries(fromRelations).slice(0, 6);
return fromRelations.slice(0, 6);
}
if (familyOf(entry) === "paradigme") {
@@ -413,4 +497,65 @@ export function getContextualTheory(
}
return [];
}
}
export function getGlossaryEntryAsideData(
currentEntry: GlossaryEntry,
allEntries: GlossaryEntry[] = [],
): GlossaryEntryAsideData {
const currentFamily = familyOf(currentEntry);
const fondamentaux = getFondamentaux(allEntries);
const sameFamilyEntries = getEntriesOfSameFamily(currentEntry, allEntries);
const sameFamilyTitle = getSameFamilyTitle(currentEntry);
const relationSections = getRelationSections(currentEntry, allEntries);
const contextualTheory = getContextualTheory(currentEntry, allEntries);
const showNoyau =
currentFamily !== "concept-fondamental" &&
fondamentaux.length > 0;
const showSameFamily =
currentFamily !== "concept-fondamental" &&
sameFamilyEntries.length > 0;
return {
displayFamily: getDisplayFamily(currentEntry),
displayDomain: getDisplayDomain(currentEntry),
displayLevel: getDisplayLevel(currentEntry),
showNoyau,
showSameFamily,
fondamentaux,
sameFamilyTitle,
sameFamilyEntries: showSameFamily ? sameFamilyEntries : [],
relationSections,
contextualTheory,
};
}
export function getGlossaryHomeData(
entries: GlossaryEntry[] = [],
): GlossaryHomeData {
const bySlug = buildGlossaryBySlug(entries);
const fondamentaux = getGlossaryEntriesByFamily(entries, "concept-fondamental");
const scenes = getGlossaryEntriesByFamily(entries, "scene");
const dynamiques = sortGlossaryEntries(
entries.filter((entry) =>
["dynamique", "pathologie"].includes(familyOf(entry)),
),
);
const metaRegimes = getGlossaryEntriesByFamily(entries, "meta-regime");
return {
fondamentaux,
scenes,
dynamiques,
metaRegimes,
metaRegimesPreview: metaRegimes.slice(0, 6),
arcalite: bySlug.get("arcalite"),
cratialite: bySlug.get("cratialite"),
tension: bySlug.get("tension"),
sceneDepreuve: bySlug.get("scene-depreuve"),
archicration: bySlug.get("archicration"),
};
}