Ajout carrousel articles avec miniatures auto-générées
- Créer composant React ArticleCarousel avec lecture auto et boucle infinie - Afficher 6 articles total : 3 articles blog et 3 pages docs, intercalés - Ajouter badges colorés : bleu pour blog, vert foncé pour docs - Implémenter plugin personnalisé pour récupérer et organiser articles - Remplacer section fonctionnalités page d'accueil par nouveau carrousel - Mettre à jour logo site et favicon avec logo vache (logo_vache.png) - Ajouter traductions anglaises pour chaînes UI carrousel
This commit is contained in:
parent
ba57296597
commit
461fc446ff
10 changed files with 911 additions and 55 deletions
96
plugins/docusaurus-plugin-recent-articles/index.js
Normal file
96
plugins/docusaurus-plugin-recent-articles/index.js
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/**
|
||||
* Docusaurus plugin to gather recent blog posts and documentation pages
|
||||
* for the ArticleCarousel component.
|
||||
*
|
||||
* This plugin creates a global data structure containing recent articles
|
||||
* from both blog posts and documentation pages, sorted by date.
|
||||
*/
|
||||
|
||||
module.exports = function pluginRecentArticles(context, options) {
|
||||
return {
|
||||
name: 'docusaurus-plugin-recent-articles',
|
||||
|
||||
async allContentLoaded({ actions, allContent }) {
|
||||
const { setGlobalData } = actions;
|
||||
|
||||
try {
|
||||
const blogArticles = [];
|
||||
const docArticles = [];
|
||||
|
||||
// Access blog plugin data
|
||||
const blogPlugin = allContent?.['docusaurus-plugin-content-blog'];
|
||||
const blogContent = blogPlugin?.default;
|
||||
|
||||
if (blogContent?.blogPosts) {
|
||||
blogContent.blogPosts.forEach((post) => {
|
||||
blogArticles.push({
|
||||
title: post.metadata.title,
|
||||
permalink: post.metadata.permalink,
|
||||
type: 'blog',
|
||||
date: post.metadata.date,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Access docs plugin data
|
||||
const docsPlugin = allContent?.['docusaurus-plugin-content-docs'];
|
||||
const docsContent = docsPlugin?.default;
|
||||
|
||||
if (docsContent?.loadedVersions) {
|
||||
docsContent.loadedVersions.forEach((version) => {
|
||||
if (version.docs) {
|
||||
version.docs.forEach((doc) => {
|
||||
// Skip index/category pages to focus on actual content
|
||||
if (!doc.id.endsWith('/index') && !doc.id.includes('category')) {
|
||||
docArticles.push({
|
||||
title: doc.title,
|
||||
permalink: doc.permalink,
|
||||
type: 'doc',
|
||||
// Docs don't have a publish date, use last updated time or current date
|
||||
date: doc.lastUpdatedAt
|
||||
? new Date(doc.lastUpdatedAt).toISOString()
|
||||
: new Date().toISOString(),
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Sort each type by date (most recent first)
|
||||
blogArticles.sort((a, b) => {
|
||||
const dateA = new Date(a.date || 0);
|
||||
const dateB = new Date(b.date || 0);
|
||||
return dateB - dateA;
|
||||
});
|
||||
|
||||
docArticles.sort((a, b) => {
|
||||
const dateA = new Date(a.date || 0);
|
||||
const dateB = new Date(b.date || 0);
|
||||
return dateB - dateA;
|
||||
});
|
||||
|
||||
// Take 3 most recent from each type
|
||||
const recentBlog = blogArticles.slice(0, 3);
|
||||
const recentDocs = docArticles.slice(0, 3);
|
||||
|
||||
// Intercalate blog and documentation articles: blog, doc, blog, doc, blog, doc
|
||||
const articles = [];
|
||||
for (let i = 0; i < Math.max(recentBlog.length, recentDocs.length); i++) {
|
||||
if (i < recentBlog.length) {
|
||||
articles.push(recentBlog[i]);
|
||||
}
|
||||
if (i < recentDocs.length) {
|
||||
articles.push(recentDocs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Store globally for use in React components
|
||||
setGlobalData({ articles });
|
||||
} catch (error) {
|
||||
console.error('Error loading recent articles:', error);
|
||||
setGlobalData({ articles: [] });
|
||||
}
|
||||
},
|
||||
};
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue