new_website/src/theme/BlogPostItem/index.js (162 lines of code) (raw):

/** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import React from 'react'; import clsx from 'clsx'; import {MDXProvider} from '@mdx-js/react'; import Translate, {translate} from '@docusaurus/Translate'; import Link from '@docusaurus/Link'; import {usePluralForm} from '@docusaurus/theme-common'; import MDXComponents from '@theme/MDXComponents'; import Seo from '@theme/Seo'; import EditThisPage from '@theme/EditThisPage'; import styles from './styles.module.css'; // Very simple pluralization: probably good enough for now function useReadingTimePlural() { const {selectMessage} = usePluralForm(); return (readingTimeFloat) => { const readingTime = Math.ceil(readingTimeFloat); return selectMessage( readingTime, translate( { id: 'theme.blog.post.readingTime.plurals', description: 'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)', message: 'One min read|{readingTime} min read', }, { readingTime, }, ), ); }; } function BlogPostItem(props) { const readingTimePlural = useReadingTimePlural(); const { children, frontMatter, metadata, truncated, isBlogPostPage = false, } = props; const { date, formattedDate, permalink, tags, readingTime, title, editUrl, } = metadata; const {author, image, keywords} = frontMatter; const mediumLink = frontMatter['medium-link']; const authorURL = frontMatter.author_url || frontMatter.authorURL; const authorTitle = frontMatter.author_title || frontMatter.authorTitle; const authorImageURL = frontMatter.author_image_url || frontMatter.authorImageURL; const renderPostHeader = () => { const TitleHeading = isBlogPostPage ? 'h1' : 'h2'; return ( <header> <TitleHeading className={styles.blogPostTitle}> {isBlogPostPage ? title : <Link to={mediumLink || permalink}>{title}</Link>} </TitleHeading> <div className={clsx(styles.blogPostData, 'margin-vert--md')}> <time dateTime={date}>{formattedDate}</time> {readingTime && ( <> {' · '} {readingTimePlural(readingTime)} </> )} </div> <div className="avatar margin-vert--md"> {authorImageURL && ( <Link className="avatar__photo-link avatar__photo" href={authorURL}> <img src={authorImageURL} alt={author} /> </Link> )} <div className="avatar__intro"> {author && ( <> <div className="avatar__name"> <Link href={authorURL}>{author}</Link> </div> <small className="avatar__subtitle">{authorTitle}</small> </> )} </div> </div> </header> ); }; return ( <> <Seo {...{ keywords, image, }} /> <article className={!isBlogPostPage ? 'margin-bottom--xl' : undefined}> {renderPostHeader()} <div className="markdown"> <MDXProvider components={MDXComponents}>{children}</MDXProvider> </div> {(tags.length > 0 || truncated || mediumLink) && ( <footer className={clsx('row docusaurus-mt-lg', { [styles.blogPostDetailsFull]: isBlogPostPage, })}> {tags.length > 0 && ( <div className="col"> <b> <Translate id="theme.tags.tagsListLabel" description="The label alongside a tag list"> Tags: </Translate> </b> {tags.map(({label, permalink: tagPermalink}) => ( <Link key={tagPermalink} className="margin-horiz--sm" to={tagPermalink}> {label} </Link> ))} </div> )} {isBlogPostPage && editUrl && ( <div className="col margin-top--sm"> <EditThisPage editUrl={editUrl} /> </div> )} {!isBlogPostPage && truncated && ( <div className="col text--right"> <Link to={metadata.permalink} aria-label={`Read more about ${title}`}> <b> <Translate id="theme.blog.post.readMore" description="The label used in blog post item excerpts to link to full blog posts"> Read More </Translate> </b> </Link> </div> )} {mediumLink && ( <div className="col text--left"> <Link to={mediumLink} aria-label={`Read more about ${title}`}> <b> Read More on Medium </b> </Link> </div> )} </footer> )} </article> </> ); } export default BlogPostItem;