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

feat(theme): show unlisted/draft banners in dev mode #10376

Merged
merged 14 commits into from
Aug 8, 2024
22 changes: 21 additions & 1 deletion packages/docusaurus-theme-classic/src/theme-classic.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1602,14 +1602,34 @@ declare module '@theme/Tag' {
export default function Tag(props: Props): JSX.Element;
}

declare module '@theme/Unlisted' {
declare module '@theme/ContentVisibility' {
export interface Props {
readonly metadata: {
// the visibility metadata our 3 content plugins share in common
readonly unlisted: boolean;
readonly frontMatter: {draft?: boolean; unlisted?: boolean};
};
}

export default function ContentVisibility(props: Props): JSX.Element;
}

declare module '@theme/ContentVisibility/Unlisted' {
export interface Props {
className?: string;
}

export default function Unlisted(props: Props): JSX.Element;
}

declare module '@theme/ContentVisibility/Draft' {
export interface Props {
className?: string;
}

export default function Draft(props: Props): JSX.Element;
}

declare module '@theme/prism-include-languages' {
import type * as PrismNamespace from 'prismjs';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import BlogPostPaginator from '@theme/BlogPostPaginator';
import BlogPostPageMetadata from '@theme/BlogPostPage/Metadata';
import BlogPostPageStructuredData from '@theme/BlogPostPage/StructuredData';
import TOC from '@theme/TOC';
import ContentVisibility from '@theme/ContentVisibility';
import type {Props} from '@theme/BlogPostPage';
import Unlisted from '@theme/Unlisted';
import type {BlogSidebar} from '@docusaurus/plugin-content-blog';

function BlogPostPageContent({
Expand All @@ -30,7 +30,7 @@ function BlogPostPageContent({
children: ReactNode;
}): JSX.Element {
const {metadata, toc} = useBlogPost();
const {nextItem, prevItem, frontMatter, unlisted} = metadata;
const {nextItem, prevItem, frontMatter} = metadata;
const {
hide_table_of_contents: hideTableOfContents,
toc_min_heading_level: tocMinHeadingLevel,
Expand All @@ -48,7 +48,7 @@ function BlogPostPageContent({
/>
) : undefined
}>
{unlisted && <Unlisted />}
<ContentVisibility metadata={metadata} />

<BlogPostItem>{children}</BlogPostItem>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import BlogListPaginator from '@theme/BlogListPaginator';
import SearchMetadata from '@theme/SearchMetadata';
import type {Props} from '@theme/BlogTagsPostsPage';
import BlogPostItems from '@theme/BlogPostItems';
import Unlisted from '@theme/Unlisted';
import Unlisted from '@theme/ContentVisibility/Unlisted';
import Heading from '@theme/Heading';

function BlogTagsPostsPageMetadata({tag}: Props): JSX.Element {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* Copyright (c) Facebook, Inc. and its 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 {
ThemeClassNames,
DraftBannerTitle,
DraftBannerMessage,
} from '@docusaurus/theme-common';
import Admonition from '@theme/Admonition';
import type {Props} from '@theme/ContentVisibility/Draft';

export default function Draft({className}: Props): JSX.Element | null {
return (
<Admonition
type="caution"
title={<DraftBannerTitle />}
className={clsx(className, ThemeClassNames.common.draftBanner)}>
<DraftBannerMessage />
</Admonition>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
UnlistedMetadata,
} from '@docusaurus/theme-common';
import Admonition from '@theme/Admonition';
import type {Props} from '@theme/Unlisted';
import type {Props} from '@theme/ContentVisibility/Unlisted';

function UnlistedBanner({className}: Props) {
return (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* Copyright (c) Facebook, Inc. and its 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 type {Props} from '@theme/ContentVisibility';
import Draft from '@theme/ContentVisibility/Draft';
import Unlisted from '@theme/ContentVisibility/Unlisted';

export default function ContentVisibility({
metadata,
}: Props): JSX.Element | null {
const {unlisted, frontMatter} = metadata;
// Reading draft/unlisted status from frontMatter is useful to display
// the banners in dev mode (in dev, metadata.unlisted is always false)
// See https://github.com/facebook/docusaurus/issues/8285
return (
<>
{(unlisted || frontMatter.unlisted) && <Unlisted />}
{frontMatter.draft && <Draft />}
</>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import DocItemTOCMobile from '@theme/DocItem/TOC/Mobile';
import DocItemTOCDesktop from '@theme/DocItem/TOC/Desktop';
import DocItemContent from '@theme/DocItem/Content';
import DocBreadcrumbs from '@theme/DocBreadcrumbs';
import Unlisted from '@theme/Unlisted';
import ContentVisibility from '@theme/ContentVisibility';
import type {Props} from '@theme/DocItem/Layout';

import styles from './styles.module.css';
Expand Down Expand Up @@ -48,13 +48,11 @@ function useDocTOC() {

export default function DocItemLayout({children}: Props): JSX.Element {
const docTOC = useDocTOC();
const {
metadata: {unlisted},
} = useDoc();
const {metadata} = useDoc();
return (
<div className="row">
<div className={clsx('col', !docTOC.hidden && styles.docItemCol)}>
{unlisted && <Unlisted />}
<ContentVisibility metadata={metadata} />
<DocVersionBanner />
<div className={styles.docItemContainer}>
<article>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
import Translate, {translate} from '@docusaurus/Translate';
import SearchMetadata from '@theme/SearchMetadata';
import type {Props} from '@theme/DocTagDocListPage';
import Unlisted from '@theme/Unlisted';
import Unlisted from '@theme/ContentVisibility/Unlisted';
import Heading from '@theme/Heading';

// Very simple pluralization: probably good enough for now
Expand Down
23 changes: 10 additions & 13 deletions packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,23 @@ import {
import Layout from '@theme/Layout';
import MDXContent from '@theme/MDXContent';
import TOC from '@theme/TOC';
import Unlisted from '@theme/Unlisted';
import ContentVisibility from '@theme/ContentVisibility';
import type {Props} from '@theme/MDXPage';

import EditMetaRow from '@theme/EditMetaRow';
import styles from './styles.module.css';

export default function MDXPage(props: Props): JSX.Element {
const {content: MDXPageContent} = props;
const {metadata, assets} = MDXPageContent;
const {
metadata: {
title,
editUrl,
description,
frontMatter,
unlisted,
lastUpdatedBy,
lastUpdatedAt,
},
assets,
} = MDXPageContent;
title,
editUrl,
description,
frontMatter,
lastUpdatedBy,
lastUpdatedAt,
} = metadata;
const {
keywords,
wrapperClassName,
Expand All @@ -60,7 +57,7 @@ export default function MDXPage(props: Props): JSX.Element {
<main className="container container--fluid margin-vert--lg">
<div className={clsx('row', styles.mdxPageWrapper)}>
<div className={clsx('col', !hideTableOfContents && 'col--8')}>
{unlisted && <Unlisted />}
<ContentVisibility metadata={metadata} />
<article>
<MDXContent>
<MDXPageContent />
Expand Down
4 changes: 3 additions & 1 deletion packages/docusaurus-theme-common/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,9 @@ export {
UnlistedBannerTitle,
UnlistedBannerMessage,
UnlistedMetadata,
} from './utils/unlistedUtils';
DraftBannerTitle,
DraftBannerMessage,
} from './translations/contentVisibilityTranslations';

export {
ErrorBoundaryTryAgainButton,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import Head from '@docusaurus/Head';
export function UnlistedBannerTitle(): JSX.Element {
return (
<Translate
id="theme.unlistedContent.title"
id="theme.contentVisibility.unlistedBanner.title"
description="The unlisted content banner title">
Unlisted page
</Translate>
Expand All @@ -22,18 +22,41 @@ export function UnlistedBannerTitle(): JSX.Element {
export function UnlistedBannerMessage(): JSX.Element {
return (
<Translate
id="theme.unlistedContent.message"
id="theme.contentVisibility.unlistedBanner.message"
description="The unlisted content banner message">
This page is unlisted. Search engines will not index it, and only users
having a direct link can access it.
</Translate>
);
}

// TODO Docusaurus v4 breaking change (since it's v3 public theme-common API :/)
// Move this to theme/ContentVisibility/Unlisted
export function UnlistedMetadata(): JSX.Element {
return (
<Head>
<meta name="robots" content="noindex, nofollow" />
</Head>
);
}

export function DraftBannerTitle(): JSX.Element {
return (
<Translate
id="theme.contentVisibility.draftBanner.title"
description="The draft content banner title">
Draft page
</Translate>
);
}

export function DraftBannerMessage(): JSX.Element {
return (
<Translate
id="theme.contentVisibility.draftBanner.message"
description="The draft content banner message">
This page is a draft. It will only be visible in dev and be excluded from
the production build.
</Translate>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export const ThemeClassNames = {
codeBlock: 'theme-code-block',
admonition: 'theme-admonition',
unlistedBanner: 'theme-unlisted-banner',
draftBanner: 'theme-draft-banner',

admonitionType: (type: string) => `theme-admonition-${type}`,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
"theme.admonition.warning": "warning",
"theme.blog.archive.description": "أرشيف",
"theme.blog.archive.title": "أرشيف",
"theme.blog.author.pageTitle": "{authorName} - {nPosts}",
"theme.blog.authorsList.pageTitle": "Authors",
"theme.blog.authorsList.viewAll": "View All Authors",
"theme.blog.paginator.navAriaLabel": "التنقل في صفحة قائمة المدونة",
"theme.blog.paginator.newerEntries": "إدخالات أحدث",
"theme.blog.paginator.olderEntries": "إدخالات أقدم",
Expand All @@ -40,6 +43,10 @@
"theme.common.editThisPage": "تعديل هذه الصفحة",
"theme.common.headingLinkTitle": "ارتباط مباشر بالعنوان {heading}",
"theme.common.skipToMainContent": "انتقل إلى المحتوى الرئيسي",
"theme.contentVisibility.draftBanner.message": "This page is a draft. It will only be visible in dev and be excluded from the production build.",
"theme.contentVisibility.draftBanner.title": "Draft page",
"theme.contentVisibility.unlistedBanner.message": "This page is unlisted. Search engines will not index it, and only users having a direct link can access it.",
"theme.contentVisibility.unlistedBanner.title": "Unlisted page",
"theme.docs.DocCard.categoryDescription.plurals": "{count} مواد",
"theme.docs.breadcrumbs.home": "الرئيسية",
"theme.docs.breadcrumbs.navAriaLabel": "التنقل التفصيلي",
Expand Down Expand Up @@ -68,7 +75,5 @@
"theme.navbar.mobileVersionsDropdown.label": "إصدارات",
"theme.tags.tagsListLabel": "الوسوم:",
"theme.tags.tagsPageLink": "عرض كل الوسوم",
"theme.tags.tagsPageTitle": "الوسوم",
"theme.unlistedContent.message": "This page is unlisted. Search engines will not index it, and only users having a direct link can access it.",
"theme.unlistedContent.title": "Unlisted page"
"theme.tags.tagsPageTitle": "الوسوم"
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,16 @@
"theme.admonition.tip___DESCRIPTION": "The default label used for the Tip admonition (:::tip)",
"theme.admonition.warning": "warning",
"theme.admonition.warning___DESCRIPTION": "The default label used for the Warning admonition (:::warning)",
"theme.blog.authorsList.pageTitle": "Authors",
"theme.blog.authorsList.viewAll": "View All Authors",
"theme.blog.author.pageTitle": "{authorName} - {nPosts}",
"theme.blog.archive.description": "Archive",
"theme.blog.archive.description___DESCRIPTION": "The page & hero description of the blog archive page",
"theme.blog.archive.title": "Archive",
"theme.blog.archive.title___DESCRIPTION": "The page & hero title of the blog archive page",
"theme.blog.author.pageTitle": "{authorName} - {nPosts}",
"theme.blog.author.pageTitle___DESCRIPTION": "The title of the page for a blog author",
"theme.blog.authorsList.pageTitle": "Authors",
"theme.blog.authorsList.pageTitle___DESCRIPTION": "The title of the authors page",
"theme.blog.authorsList.viewAll": "View All Authors",
"theme.blog.authorsList.viewAll___DESCRIPTION": "The label of the link targeting the blog authors page",
"theme.blog.paginator.navAriaLabel": "Blog list page navigation",
"theme.blog.paginator.navAriaLabel___DESCRIPTION": "The ARIA label for the blog pagination",
"theme.blog.paginator.newerEntries": "Newer Entries",
Expand Down Expand Up @@ -84,6 +87,14 @@
"theme.common.headingLinkTitle___DESCRIPTION": "Title for link to heading",
"theme.common.skipToMainContent": "Skip to main content",
"theme.common.skipToMainContent___DESCRIPTION": "The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",
"theme.contentVisibility.draftBanner.message": "This page is a draft. It will only be visible in dev and be excluded from the production build.",
"theme.contentVisibility.draftBanner.message___DESCRIPTION": "The draft content banner message",
"theme.contentVisibility.draftBanner.title": "Draft page",
"theme.contentVisibility.draftBanner.title___DESCRIPTION": "The draft content banner title",
"theme.contentVisibility.unlistedBanner.message": "This page is unlisted. Search engines will not index it, and only users having a direct link can access it.",
"theme.contentVisibility.unlistedBanner.message___DESCRIPTION": "The unlisted content banner message",
"theme.contentVisibility.unlistedBanner.title": "Unlisted page",
"theme.contentVisibility.unlistedBanner.title___DESCRIPTION": "The unlisted content banner title",
"theme.docs.DocCard.categoryDescription.plurals": "1 item|{count} items",
"theme.docs.DocCard.categoryDescription.plurals___DESCRIPTION": "The default description for a category card in the generated index about how many items this category includes",
"theme.docs.breadcrumbs.home": "Home page",
Expand Down Expand Up @@ -140,9 +151,5 @@
"theme.tags.tagsPageLink": "View All Tags",
"theme.tags.tagsPageLink___DESCRIPTION": "The label of the link targeting the tag list page",
"theme.tags.tagsPageTitle": "Tags",
"theme.tags.tagsPageTitle___DESCRIPTION": "The title of the tag list page",
"theme.unlistedContent.message": "This page is unlisted. Search engines will not index it, and only users having a direct link can access it.",
"theme.unlistedContent.message___DESCRIPTION": "The unlisted content banner message",
"theme.unlistedContent.title": "Unlisted page",
"theme.unlistedContent.title___DESCRIPTION": "The unlisted content banner title"
"theme.tags.tagsPageTitle___DESCRIPTION": "The title of the tag list page"
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
"theme.admonition.warning": "Внимание",
"theme.blog.archive.description": "Архив",
"theme.blog.archive.title": "Архив",
"theme.blog.author.pageTitle": "{authorName} - {nPosts}",
"theme.blog.authorsList.pageTitle": "Authors",
"theme.blog.authorsList.viewAll": "View All Authors",
"theme.blog.paginator.navAriaLabel": "Навигация в страницата със списък на блогове",
"theme.blog.paginator.newerEntries": "По-нови записи",
"theme.blog.paginator.olderEntries": "По-стари записи",
Expand All @@ -40,6 +43,10 @@
"theme.common.editThisPage": "Редактирай тази страница",
"theme.common.headingLinkTitle": "Директна връзка към {heading}",
"theme.common.skipToMainContent": "Преминете към основното съдържание",
"theme.contentVisibility.draftBanner.message": "This page is a draft. It will only be visible in dev and be excluded from the production build.",
"theme.contentVisibility.draftBanner.title": "Draft page",
"theme.contentVisibility.unlistedBanner.message": "Тази страница е скрита. Търсачките няма да я индексират и само потребители с директна връзка имат достъп до него.",
"theme.contentVisibility.unlistedBanner.title": "Скрита страница",
"theme.docs.DocCard.categoryDescription.plurals": "един предмет|{count} предмета",
"theme.docs.breadcrumbs.home": "Начална страница",
"theme.docs.breadcrumbs.navAriaLabel": "Галета",
Expand Down Expand Up @@ -68,7 +75,5 @@
"theme.navbar.mobileVersionsDropdown.label": "Версии",
"theme.tags.tagsListLabel": "Етикети:",
"theme.tags.tagsPageLink": "Вижте всички етикети",
"theme.tags.tagsPageTitle": "Етикети",
"theme.unlistedContent.message": "Тази страница е скрита. Търсачките няма да я индексират и само потребители с директна връзка имат достъп до него.",
"theme.unlistedContent.title": "Скрита страница"
"theme.tags.tagsPageTitle": "Етикети"
}
Loading