facebook / docusaurus

Easy to maintain open source documentation websites.
https://docusaurus.io
MIT License
55.7k stars 8.34k forks source link

Show profile of all contributors to a doc page #6218

Open pranay01 opened 2 years ago

pranay01 commented 2 years ago

Have you read the Contributing Guidelines on issues?

Description

More details here https://github.com/facebook/docusaurus/discussions/6194#discussion-3765566

Has this been requested on Canny?

No response

Motivation

We want to show the picture of contributors to our docs so that users get more motivation to contribute to the doc

API design

No response

Have you tried building it?

No

Self-service

Josh-Cena commented 2 years ago

So I think displaying the pictures of all contributors is going to be too opinionated. However, we can do this:

Josh-Cena commented 2 years ago

@slorber Let's talk about how the API will look like. Our DocMetadata type has the shape:

type DocMetadataBase = LastUpdateData & {
  id: string;
  version: VersionName;
  title: string;
  //...
};

Should we add another field

type NewDocMetadataBase = DocMetadataBase & {
  updateHistory: Array<{author: string, time: number, formattedTime: string}>
}

to the metadata but preserve the existing lastUpdatedAt and lastUpdatedBy metadata (make it safe for existing swizzled components & works well with existing options showLastUpdate*), or should we release this as a breaking change, change LastUpdateData to a generic UpdateHistory field, and move the determination of what to display to the theme side?

slorber commented 2 years ago

I'd rather have an updateHistory breaking change instead of duplicating fields

Note it seems looking up for the git history might have performance implications, we can try this on our own site first maybe and see, eventually providing an option to control how much we look back into the history. Is it worth it to include all history entries? Probably not, as that would lead to multiple times the same author, so it's not really an history anymore but rather the last unique users that updated a doc.

Also the git author is a string, and it does not necessarily match your github username (in your case it's author: "Joshua Chen" => I guess GitHub is matching on the email too, so we probably want to include the user email in this author type.

Josh-Cena commented 2 years ago

Yes, we need to figure out how GitHub matches git usernames with users. For a while I used username Josh-Cena, and my avatars etc. are still loaded correctly, so I think email also plays a part.

About duplicated authors, I don't know if the full history is useful to keep, but in any case we can first go with filtering out unique author names

slorber commented 2 years ago

This command does not seem too slow to run locally: git log --format=%ct,%an,%ae 🤷‍♂️ but it's hard to tell for a lot of files.

Maybe we should first write a way to log lifecycle execution duration of all plugins to be able to measure the impact?

About duplicated authors, I don't know if the full history is useful to keep, but in any case we can first go with filtering out unique author names

That would also be a lot of data to send to the frontend for each file, probably not worth it or at least not something to do by default

Josh-Cena commented 2 years ago

Isn't this data tree-shakable if unused?

slorber commented 2 years ago

Isn't this data tree-shakable if unused?

If this is imported/required it won't be tree-shaked even if it's not rendered

IE if it's part of docs metadata it will add weight, so you'd rather find a way to limit the json size.

It's also possible to pass the component an optional json module as props, but that's quite similar in terms of tradeoffs anyway

Josh-Cena commented 2 years ago

From #3592, the following would be helpful:

  • ability to specify maximum number of last contributors from 1 to 5 (hardcoded: 1)
  • ability to specify the handle by which user is represented (hardcoded: name + surname)
    • as possible value it would be nice to have GitHub username, email or one of names used alone
  • ability to display user avatar or profile picture from GitHub (or Gravatar) with a nice fallback
TheCatLady commented 2 years ago

Yes, we need to figure out how GitHub matches git usernames with users. For a while I used username Josh-Cena, and my avatars etc. are still loaded correctly, so I think email also plays a part.

GitHub doesn't match on username at all, only email address (of which a GitHub user can have multiple associated with their account): https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-user-account/managing-email-preferences/setting-your-commit-email-address

osamajandali commented 2 years ago

I've mocked that in a UI design.. image We can get the last 3-7 contributor and have the others on request when clicking on "N contributors"

tobiasbueschel commented 1 year ago

I've mocked that in a UI design..

Love the mockup, great work @osamajandali 👏 Are you thinking that the pop-up window would also indicate who was the original creator of the page and timestamps when contributions were made?

I also wanted to ask if anyone has already started implementing this? And whether it would become part of core docusaurus or a standalone module instead?

atar-axis commented 11 months ago

Is this still under development? We would love that too!

milldr commented 8 months ago

👍 also interested in this feature

hanarotg commented 7 months ago

any updates? I'm looking forward to this feature

slorber commented 7 months ago

Technically this can now be implemented in userland thanks to the v3.1 parseFrontMatter hook: https://docusaurus.io/blog/releases/3.1#parsefrontmatter-hook

It notably allows you to automatically add a frontMatter.authors field to your docs (in case defining the list of authors manually is not an option)

async function getAuthors(filePath: string) {
  // Do whatever you want here to create a list of authors for each file
  // you can read Git history if you want, or any other source
  return [
    {name: "Seb",picture: "https://github.com/slorber.png"},
    {name: "Joshua",picture: "https://github.com/Josh-Cena.png"}
  ]
} 

const config: Config = {
  markdown: {
    parseFrontMatter: async (params) => {
      const result = await params.defaultParseFrontMatter(params);
      const authors = await getAuthors(params.filePath);
      return {
        ...result,
        frontMatter: {
          ...result.frontMatter,
          authors,
        }
      }
    }
  },
};

export default config;

Then you can swizzle the doc component you want and render that front matter:

yarn docusaurus swizzle @docusaurus/theme-classic DocItem/Footer --wrap --typescript

import React from 'react';
import Footer from '@theme-original/DocItem/Footer';
import type FooterType from '@theme/DocItem/Footer';
import type { WrapperProps } from '@docusaurus/types';
import { useDoc } from '@docusaurus/theme-common/internal';

type Props = WrapperProps<typeof FooterType>;

export default function FooterWrapper(props: Props): JSX.Element {
  const doc = useDoc();

  const authors = (doc.frontMatter as any).authors as {
    name: string;
    picture: string;
  }[];

  return (
    <>
      <div style={{marginTop: 20, marginBottom: 20}}>
        Authors:
        <ul>
          {authors.map((author, i) => (
            <li key={i} style={{display: "flex",flexDirection: "row", alignItems: "center", padding: 5}}>
              <img
                src={author.picture}
                style={{ width: 40, height: 40, borderRadius: 40,  marginRight: 10}}
              />
              <span>{author.name}</span>
            </li>
          ))}
        </ul>

      </div>
      <Footer {...props} />
    </>
  );
}

Result:

CleanShot 2024-02-13 at 11 43 58

Runnable sandbox: https://stackblitz.com/edit/github-revkph?file=src%2Ftheme%2FDocItem%2FFooter%2Findex.tsx,docusaurus.config.ts


Considering it is possible to implement in userland thanks to existing Docusaurus primitives, if we ever add this feature to Docusaurus core, this would only be an "opinionated shortcut" to the above solution.

By opinionated I mean: limited to reading history on Git (and not other VCS), and displaying the authors in some predefined place such as the footer. This also means our opinions won't please everyone.

For this reason, there's no reason to rush implementing this feature officially. I'd rather see a few successful userland implementations first, so that we understand the common denominator of the solutions, which would help us craft a good opinionated solution that please a maximum number of users.


This is also related to https://github.com/facebook/docusaurus/issues/8657 which asks us to render some extra metadata in the blog post footer. Similarly parseFrontMatter can be used.