diff --git a/src/components/GlossaryRelationCards.astro b/src/components/GlossaryRelationCards.astro new file mode 100644 index 0000000..0f800ea --- /dev/null +++ b/src/components/GlossaryRelationCards.astro @@ -0,0 +1,32 @@ +--- +import type { GlossaryRelationBlock } from "../lib/glossary"; +import { hrefOfGlossaryEntry } from "../lib/glossary"; + +interface Props { + relationBlocks: GlossaryRelationBlock[]; +} + +const { relationBlocks = [] } = Astro.props; +--- + +{relationBlocks.length > 0 && ( + + Relations conceptuelles + + + {relationBlocks.map((block) => ( + + {block.title} + + {block.items.map((item) => ( + + {item.data.term} + — {item.data.definitionShort} + + ))} + + + ))} + + +)} diff --git a/src/lib/glossary.ts b/src/lib/glossary.ts index 8d969ea..1280217 100644 --- a/src/lib/glossary.ts +++ b/src/lib/glossary.ts @@ -128,17 +128,35 @@ export function uniqueGlossaryEntries( return out; } -export function resolveGlossaryEntries( +export function resolveGlossaryEntriesInSourceOrder( slugs: string[] = [], allEntries: GlossaryEntry[] = [], ): GlossaryEntry[] { const bySlug = buildGlossaryBySlug(allEntries); + const seen = new Set(); + const resolved: GlossaryEntry[] = []; - const resolved = slugs - .map((slug) => bySlug.get(normalizeGlossarySlug(slug))) - .filter(Boolean) as GlossaryEntry[]; + for (const rawSlug of slugs) { + const slug = normalizeGlossarySlug(rawSlug); + if (!slug || seen.has(slug)) continue; - return sortGlossaryEntries(uniqueGlossaryEntries(resolved)); + const entry = bySlug.get(slug); + if (!entry) continue; + + seen.add(slug); + resolved.push(entry); + } + + return resolved; +} + +export function resolveGlossaryEntries( + slugs: string[] = [], + allEntries: GlossaryEntry[] = [], + ): GlossaryEntry[] { + return sortGlossaryEntries( + resolveGlossaryEntriesInSourceOrder(slugs, allEntries), + ); } export function rawFamilyOf( @@ -268,31 +286,44 @@ export type GlossaryRelationBlock = { }; export function getRelationBlocks( - entry: GlossaryEntry, - allEntries: GlossaryEntry[] = [], -): GlossaryRelationBlock[] { - const relatedEntries = resolveGlossaryEntries(entry.data.related ?? [], allEntries); - const opposedEntries = resolveGlossaryEntries(entry.data.opposedTo ?? [], allEntries); - const seeAlsoEntries = resolveGlossaryEntries(entry.data.seeAlso ?? [], allEntries); - - 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, diff --git a/src/pages/glossaire/[...slug].astro b/src/pages/glossaire/[...slug].astro index 489496d..4f86787 100644 --- a/src/pages/glossaire/[...slug].astro +++ b/src/pages/glossaire/[...slug].astro @@ -1,13 +1,13 @@ --- import GlossaryLayout from "../../layouts/GlossaryLayout.astro"; import GlossaryAside from "../../components/GlossaryAside.astro"; +import GlossaryRelationCards from "../../components/GlossaryRelationCards.astro"; import { getCollection, render } from "astro:content"; import { getDisplayDomain, getDisplayFamily, getDisplayLevel, getRelationBlocks, - hrefOfGlossaryEntry, normalizeGlossarySlug, } from "../../lib/glossary"; @@ -133,27 +133,7 @@ const hasScholarlyMeta = - {relationBlocks.length > 0 && ( - - Relations conceptuelles - - - {relationBlocks.map((block) => ( - - {block.title} - - {block.items.map((item) => ( - - {item.data.term} - — {item.data.definitionShort} - - ))} - - - ))} - - - )} +