-
-
Notifications
You must be signed in to change notification settings - Fork 9.5k
Description
Have you read the Contributing Guidelines on issues?
- I have read the Contributing Guidelines on issues.
Description
As discussed in issue #3230, people use the blog plugin for non-blog use cases for which showing the date is not appropriate.
This feature would add a "showDate" boolean field in docusaurus.config.js, similar to "showReadingTime", that would let users easily turn it on or off.
Has this been requested on Canny?
No response
Motivation
There are currently other ways of achieving this, but the ways I have thought of so far are not convenient for multi-instance blogs where we would like to show the date in one blog instance and hide it in another:
- using CSS, as suggested here would apply to all instances (as far as I can tell)
- swizzling the BlogPostItem/Header/Info component makes it possible to customize the behavior based on metadata or other context info, but it is definitely more complicated than switching a boolean in docusaurus.config.js
API design
The API would be the same as for "showReadingTime": a boolean in docusaurus.config.js.
We could also add and advanced option "formatDateFn", similar to the "readingTime" option that allows users to configure the reading time calculation. It would allow users to customize the date formatting and to hide or show the date on a per-post basis.
Have you tried building it?
I have implemented it on my site by swizzling the BlogPostItem/Header/Info, but it's inconvenient:
- I cannot simply add a "showDate" in the config alongside the "showReadingTime": I have to use "customFields"
presets: [
[
'classic',
/** @type {import('@docusaurus/preset-classic').Options} */
({
docs: { sidebarPath: './sidebars.js' },
blog: { showReadingTime: true },
theme: { customCss: './src/css/custom.css' },
}),
],
],
plugins: [
['@docusaurus/plugin-content-blog',
{
id: 'examples',
routeBasePath: 'examples',
path: './examples',
showReadingTime: false,
},
],
],
customFields: {
blogCustomOptionsByBlogId: {
blog: { showDate: true },
examples: { showDate: false },
},
},
And then my swizzled component looks like this:
export default function BlogPostItemHeaderInfo({ className }) {
const { metadata } = useBlogPost();
const { date, readingTime } = metadata;
const dateTimeFormat = useDateTimeFormat({
day: 'numeric',
month: 'long',
year: 'numeric',
timeZone: 'UTC',
});
const formatDate = (blogDate) => dateTimeFormat.format(new Date(blogDate));
const { blogCustomOptionsByBlogId } = useDocusaurusContext().siteConfig.customFields;
const { id: blogId } = useRouteContext().plugin;
const { showDate = true } = blogCustomOptionsByBlogId[blogId] ?? { };
const showReadingTime = readingTime !== undefined;
const Spacer = () => {
if (showReadingTime && showDate) return <>{' · '}</>;
return false;
};
return (
<div className={clsx(styles.container, 'margin-vert--md', className)}>
{showDate && (<DateTime date={date} formattedDate={formatDate(date)} />)}
<Spacer />
{showReadingTime && (<ReadingTime readingTime={readingTime} />)}
</div>
);
}
This works but it is not ideal.
I woud like to implement it by adding "real" options to docusaurus config but then there are a few things that would need to be discussed.
The way "showReadingTime" currently works is that it is checked in the processBlogSourceFile function of blogUtils, and if it is false, the reading time is set to undefined in the blog post metadata.
We could do exactly the same for the date but I'm a bit worried that the date might be used for other purposes than being displayed (maybe sorting the posts ?).
In any case, I think it would be better if the "showing or not showing decision" was made later, in the component, rather than completely obliterating the metadata. That is actually true also for the reading time: somebody could want to hide the reading time from the blog post header, but still want to access it to do something else. (the only example I can think of is to launch a timer, and show and alert that says "you are a slow reader" to people who are still on the page when the time has elapsed - it is probably not a good idea, but who am I to judge what people want to do with their data ?)
It would be fairly easy to decide wether or not to show the data in the component if there was a "usePluginOptions" hook that we could call in the component, but I don't know how hard it would be to create such a hook.
In theory, as we see in my example, the useRouteContext
hook gives us the plugin id, and the useDocusaurusContext
gives us the config for all plugins, but work would need to be done to normalize this config as a "pluginConfigByPluginId" (some of it is in presets, some of it in litteral plugin config) and to resolve the default options. This work is certainly already done somewhere else, but I'm not sure where and how.
I'd be happy to work on a pull request, but I'd love to have some guidance on what you think is the best way to implement this.
Self-service
- I'd be willing to contribute this feature to Docusaurus myself.