From 10ad9f7184a3a98c7a4fb54be700d9887f6aacb0 Mon Sep 17 00:00:00 2001
From: Shivank Anchal
Date: Tue, 6 Aug 2024 23:08:38 +0530
Subject: [PATCH] Add recent blog posts on homepage
- Implemented custom plugin to generate `blog-posts-metadata.json`
- Integrated `blog-posts-metadata.json` data into RecentBlogPosts component
- Added `recentBlogPostsOnHomePage` parameter in `customFields` in `docusaurus.config.js`
Signed-off-by: Shivank Anchal
---
docusaurus.config.js | 26 ++++++++++++-------
plugins/blog-plugin.js | 33 ++++++++++++++++++++++++
src/components/RecentBlogPost/index.jsx | 27 +++++++++++++++++++
src/components/RecentBlogPosts/index.jsx | 24 +++++++++++++++++
src/pages/index.jsx | 7 +++++
5 files changed, 108 insertions(+), 9 deletions(-)
create mode 100644 plugins/blog-plugin.js
create mode 100644 src/components/RecentBlogPost/index.jsx
create mode 100644 src/components/RecentBlogPosts/index.jsx
diff --git a/docusaurus.config.js b/docusaurus.config.js
index 916f8ea..ce3eb2f 100644
--- a/docusaurus.config.js
+++ b/docusaurus.config.js
@@ -32,6 +32,7 @@ const config = {
description: 'An open-source framework for building practical distributed replication mechanisms.',
gitHubUrl: gitHubUrl,
siteLicense: siteLicense,
+ recentBlogPostsOnHomePage: 5
},
// GitHub pages deployment config.
@@ -49,6 +50,21 @@ const config = {
clientModules: ['/js/unscrambleEmail.js'],
+ plugins:[
+ [
+ './plugins/blog-plugin',
+ {
+ blogTitle: 'Replica_IO Blog',
+ blogDescription: 'Blog of the Replica_IO project - an open-source framework for building practical distributed replication mechanisms.',
+ showReadingTime: true,
+ showLastUpdateTime: true,
+ showLastUpdateAuthor: true,
+ // Remove this to remove the "edit this page" links.
+ editUrl: `${siteGitHubUrl}/edit/main/`,
+ },
+ ]
+ ],
+
presets: [
[
'classic',
@@ -59,15 +75,7 @@ const config = {
// Remove this to remove the "edit this page" links.
editUrl: `${siteGitHubUrl}/edit/main/`,
},
- blog: {
- blogTitle: 'Replica_IO Blog',
- blogDescription: 'Blog of the Replica_IO project - an open-source framework for building practical distributed replication mechanisms.',
- showReadingTime: true,
- showLastUpdateTime: true,
- showLastUpdateAuthor: true,
- // Remove this to remove the "edit this page" links.
- editUrl: `${siteGitHubUrl}/edit/main/`,
- },
+ blog: false,
theme: {
customCss: ['./src/css/custom.css'],
},
diff --git a/plugins/blog-plugin.js b/plugins/blog-plugin.js
new file mode 100644
index 0000000..88afef1
--- /dev/null
+++ b/plugins/blog-plugin.js
@@ -0,0 +1,33 @@
+import { shouldBeListed } from '@docusaurus/plugin-content-blog/src/blogUtils';
+const blogPluginExports = require('@docusaurus/plugin-content-blog');
+
+const defaultBlogPlugin = blogPluginExports.default;
+
+async function blogPluginExtended(...pluginArgs) {
+ const blogPluginInstance = await defaultBlogPlugin(...pluginArgs);
+
+ return {
+ // Add all properties of the default blog plugin so existing functionality is preserved
+ ...blogPluginInstance,
+
+ /**
+ * Override the default `contentLoaded` hook to access blog posts data
+ */
+ contentLoaded: async function (params) {
+ const { content, actions } = params;
+
+ const posts = content.blogPosts
+ .filter(shouldBeListed)
+ .map(({ content: _, ...post }) => post);
+ actions.createData('blog-posts-metadata.json', posts);
+
+ // Call the default overridden `contentLoaded` implementation
+ return blogPluginInstance.contentLoaded(params);
+ },
+ };
+}
+
+module.exports = {
+ ...blogPluginExports,
+ default: blogPluginExtended,
+};
diff --git a/src/components/RecentBlogPost/index.jsx b/src/components/RecentBlogPost/index.jsx
new file mode 100644
index 0000000..4bacc8e
--- /dev/null
+++ b/src/components/RecentBlogPost/index.jsx
@@ -0,0 +1,27 @@
+import React from 'react';
+
+const RecentBlogPost = ({ post }) => {
+ const { metadata } = post;
+ const formattedDate = new Date(metadata.date).toLocaleDateString('en-US', {
+ year: 'numeric',
+ month: 'long',
+ day: 'numeric',
+ });
+ const readingTime = Math.round(metadata.readingTime);
+
+ return (
+
+
+
{metadata.title}
+
+
+
{metadata.description}
+
+
+
{formattedDate} ยท {readingTime} min read
+
+
+ );
+};
+
+export default RecentBlogPost;
diff --git a/src/components/RecentBlogPosts/index.jsx b/src/components/RecentBlogPosts/index.jsx
new file mode 100644
index 0000000..cebd9ed
--- /dev/null
+++ b/src/components/RecentBlogPosts/index.jsx
@@ -0,0 +1,24 @@
+import React from 'react';
+import posts from '@site/.docusaurus/docusaurus-plugin-content-blog/default/blog-posts-metadata.json';
+import RecentBlogPost from '../RecentBlogPost';
+
+const RecentBlogPosts = ({ nrPosts }) => {
+ const recentPosts = posts.slice(0, nrPosts);
+
+ if (recentPosts.length === 0) {
+ return null;
+ }
+
+ return (
+
+
Recent Blog Posts
+
+ {recentPosts.map((post, index) => (
+
+ ))}
+
+
+ );
+};
+
+export default RecentBlogPosts;
diff --git a/src/pages/index.jsx b/src/pages/index.jsx
index 037a10a..5cdd5dd 100644
--- a/src/pages/index.jsx
+++ b/src/pages/index.jsx
@@ -6,6 +6,8 @@ import clsx from 'clsx';
import Heading from '@theme/Heading';
import styles from './index.module.css';
+import RecentBlogPosts from '../components/RecentBlogPosts';
+
function HomepageHeader() {
const { siteConfig } = useDocusaurusContext();
@@ -39,6 +41,8 @@ export default function Home() {
useBrokenLinks().collectAnchor('#contact-email');
+ const nrRecentBlogPosts = siteConfig.customFields.recentBlogPostsOnHomePage;
+
return (
@@ -115,6 +119,9 @@ export default function Home() {
+
+
+
);