Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to not show the date on blog posts #10179

Closed
2 tasks done
gaelhameon opened this issue May 29, 2024 · 5 comments
Closed
2 tasks done

Add option to not show the date on blog posts #10179

gaelhameon opened this issue May 29, 2024 · 5 comments
Labels
feature This is not a bug or issue with Docusausus, per se. It is a feature request for the future.

Comments

@gaelhameon
Copy link

gaelhameon commented May 29, 2024

Have you 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.
@gaelhameon gaelhameon added feature This is not a bug or issue with Docusausus, per se. It is a feature request for the future. status: needs triage This issue has not been triaged by maintainers labels May 29, 2024
@slorber
Copy link
Collaborator

slorber commented May 30, 2024

Hey

I'm not sure why swizzling is not ideal for this case. Here's a demo achieved in like 3 lines of code changes:

https://stackblitz.com/edit/github-foqcnd?file=blog%2F2021-08-26-welcome%2Findex.md,src%2Ftheme%2FBlogPostItem%2FHeader%2FInfo%2Findex.tsx

custom front matter:

hide_blog_post_date: true

Displaying conditionally in the swizzled theme component, with ability to show/hide date on a per-blog-post basis but also on a per-view basis (we display posts on multiple pages, and you might want different things on each)

      {metadata.frontMatter.hide_blog_post_date ? (
        <div style={{ color: 'red' }}>DATE HIDDEN</div>
      ) : (
        <DateTime date={date} formattedDate={formatDate(date)} />
      )}

CleanShot 2024-05-30 at 10 59 50@2x

If you want to hide the date on every blog post, you can use parseFrontMatter to put your custom front matter on every blog post automatically, and a global config option is not really needed for that:

https://docusaurus.io/blog/releases/3.1#parsefrontmatter-hook


Some things to be aware of:

  • We compute readingTime on the node side because only once per blog post because it can be expensive
  • Formatting dates is not expensive and we do it on the React/browser side
  • We can't provide a config callback for the React/browser side
  • The same date is displayed differently on multiple views, that's also why we format it locally on a per-view basis
  • Example page where the date is formatted differently: https://docusaurus.io/blog/archive
  • Plugin options can't be accessed as-is in a React component through a hook. Not all plugin options can be serialized and transferred from the node side to the browser side (notably callbacks)
  • We use the date for various things, including the pagination order, the archive page, the RSS feed order. Not having a date means we still need a predictable way to order things by default

In my opinion, it's not really necessary to implement a first-class hide date feature because:

  • we already have flexible primitives, and the above solution is good enough to me
  • a first-class option would not "unlock" the use-case, and would only be a shortcut to achieve it more conveniently
  • it's a blog plugin after all, and it's normal if there's a little bit of friction if you want to build something that is not a blog with it
  • the way I see it is that we should only add such a shortcut if multiple users creating actual blogs (and not something else) want this feature, and are able to clearly justify why they want a blog without post dates

@slorber slorber removed the status: needs triage This issue has not been triaged by maintainers label May 30, 2024
@gaelhameon
Copy link
Author

Hi,

Thanks for your reply. I agree with you that the current situation makes it easy enough to hide the date on every blog post, or to hide it on a per-post basis.

My use case is really to be able to hide it on a "per-blog-instance" basis.

I have two instances on my site: one for an actual blog, where I want to show the date on every post, and one for an "examples" section.

What I really would love for this "examples" section is a mix between the blog plugin and the "showcase" page of the Docusaurus website. I see that there are discussions about revamping the showcase infrastructure #6882 and I follow that closely.

I agree that swizzling is not shocking for my use-case : I am probably going to make other customizations that will require swizzling anyways.

I would still have found it pretty neat to be able to simply switch a boolean in the docusaurus.config.js to decide which of my blog instances should show the date or not ... but that's probably overengineering it. In the end, I will never have more than two blog instances, and I will not change the showDate option every week.

I will use your parseFrontMatter suggestion and use the filePath to decide if I want to hide the date or not.

Thanks !

@slorber
Copy link
Collaborator

slorber commented May 30, 2024

Thanks for your reply. I agree with you that the current situation makes it easy enough to hide the date on every blog post, or to hide it on a per-post basis.

My use case is really to be able to hide it on a "per-blog-instance" basis.

👍

I have two instances on my site: one for an actual blog, where I want to show the date on every post, and one for an "examples" section.

What I really would love for this "examples" section is a mix between the blog plugin and the "showcase" page of the Docusaurus website. I see that there are discussions about revamping the showcase infrastructure #6882 and I follow that closely.

FYI we are in the process of creating a Showcase plugin, that we will use on our own website: #9967

However, we decided to keep it simple for now and the showcase items are just cards with external links. But if there's a need for it we could expand it so that each showcase item has its own MDX page.

I agree that swizzling is not shocking for my use-case : I am probably going to make other customizations that will require swizzling anyways.

I would still have found it pretty neat to be able to simply switch a boolean in the docusaurus.config.js

I understand, but if we add an option for every fancy use-case our users have we'd end up with tons of options that are only used by very few users. It is better to expose low-level but flexible primitives and let all users achieve their needs with a bit more wiring IMHO.

@davidmoltin
Copy link

A showcase plugin with MDX pages would be really beneficial. A different use case than the above, for me. The information you posted around dates is extremely useful for our use case.

@slorber
Copy link
Collaborator

slorber commented Jun 21, 2024

@davidmoltin can you expand, what's your use-case? What's the input data and what are the created pages/urls you expect (and their content).

To be honest I don't really see the relationship between showcase, the blog and blog dates. I need to clearly understand the use-case to be able to provide the best plugin design

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature This is not a bug or issue with Docusausus, per se. It is a feature request for the future.
Projects
None yet
Development

No branches or pull requests

3 participants