Skip to content

Commit fc3e117

Browse files
authored
The old blog is the new new (#35)
* feat: swizzle blogs * feat: settings for blogs
1 parent f5782fb commit fc3e117

File tree

16 files changed

+547
-45
lines changed

16 files changed

+547
-45
lines changed

docusaurus.config.ts

Lines changed: 51 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -35,33 +35,43 @@ const config: Config = {
3535
format: "detect",
3636
},
3737

38-
plugins: [[require.resolve('./blogPluginEnhanced'), {
39-
showReadingTime: true,
40-
blogSidebarTitle: 'All posts',
41-
blogSidebarCount: 'ALL',
42-
feedOptions: {
43-
type: "all",
44-
//copyright: `Copyright © ${new Date().getFullYear()} metal-stack`,
45-
createFeedItems: async (params) => {
46-
const { blogPosts, defaultCreateFeedItems, ...rest } = params;
47-
return await defaultCreateFeedItems({
48-
// keep only the 10 most recent blog posts in the feed
49-
blogPosts: blogPosts.filter((item, index) => index < 30),
50-
...rest,
51-
});
38+
plugins: [
39+
[
40+
require.resolve("./blogPluginEnhanced"),
41+
{
42+
showReadingTime: true,
43+
blogSidebarTitle: "All posts",
44+
blogSidebarCount: 0,
45+
postsPerPage: 12,
46+
feedOptions: {
47+
type: "all",
48+
//copyright: `Copyright © ${new Date().getFullYear()} metal-stack`,
49+
createFeedItems: async (params) => {
50+
const { blogPosts, defaultCreateFeedItems, ...rest } = params;
51+
return await defaultCreateFeedItems({
52+
// keep only the 10 most recent blog posts in the feed
53+
blogPosts: blogPosts.filter((item, index) => index < 30),
54+
...rest,
55+
});
56+
},
57+
},
58+
// Please change this to your repo.
59+
// Remove this to remove the "edit this page" links.
60+
editUrl: "https://github.com/metal-stack/docs-new/tree/main/",
61+
// Useful options to enforce blogging best practices
62+
onInlineTags: "warn",
63+
onInlineAuthors: "ignore",
64+
onUntruncatedBlogPosts: "warn",
5265
},
53-
},
54-
// Please change this to your repo.
55-
// Remove this to remove the "edit this page" links.
56-
editUrl: "https://github.com/metal-stack/docs-new/tree/main/",
57-
// Useful options to enforce blogging best practices
58-
onInlineTags: "warn",
59-
onInlineAuthors: "ignore",
60-
onUntruncatedBlogPosts: "warn",
61-
}], ["./src/plugins/tailwind-config.js", {}],
62-
[require.resolve('docusaurus-lunr-search'), {
63-
languages: ['en']
64-
}]],
66+
],
67+
["./src/plugins/tailwind-config.js", {}],
68+
[
69+
require.resolve("docusaurus-lunr-search"),
70+
{
71+
languages: ["en"],
72+
},
73+
],
74+
],
6575

6676
presets: [
6777
[
@@ -71,8 +81,7 @@ const config: Config = {
7181
sidebarPath: "./sidebars.ts",
7282
// Please change this to your repo.
7383
// Remove this to remove the "edit this page" links.
74-
editUrl:
75-
"https://github.com/metal-stack/docs-new/tree/main/",
84+
editUrl: "https://github.com/metal-stack/docs-new/tree/main/",
7685
},
7786
blog: false,
7887
theme: {
@@ -95,18 +104,20 @@ const config: Config = {
95104
src: "img/metal-stack.png",
96105
},
97106
items: [
98-
{ type: "docsVersionDropdown", dropdownItemsAfter: [
99-
{
100-
type: 'html',
101-
value: '<hr class="dropdown-separator">',
102-
},
103-
{
104-
label: "Archived: v0.1 - v0.21.8",
105-
//! TODO: change to archived dns
106-
href: "https://docs.metal-stack.io/stable/"
107-
}
108-
],
109-
},
107+
{
108+
type: "docsVersionDropdown",
109+
dropdownItemsAfter: [
110+
{
111+
type: "html",
112+
value: '<hr class="dropdown-separator">',
113+
},
114+
{
115+
label: "Archived: v0.1 - v0.21.8",
116+
//! TODO: change to archived dns
117+
href: "https://docs.metal-stack.io/stable/",
118+
},
119+
],
120+
},
110121
{
111122
type: "doc",
112123
label: "Docs",

src/components/ArticleTeaser.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ export default function ArticleTeaser(props: ArticleTeaserProps) {
1313
<p className="mt-5 line-clamp-3 text-sm leading-6">{props.description}</p>
1414
</div>
1515
<div className="relative mt-8 flex items-center gap-x-4">
16-
<img
17-
src={props.firstAuthor.url}
18-
alt="Author image"
19-
className="h-10 w-10 rounded-full bg-neutral-50"
20-
/>
16+
{ props.firstAuthor.url &&
17+
<img
18+
src={props.firstAuthor.url}
19+
alt="Author image"
20+
className="h-10 w-10 rounded-full bg-neutral-50"
21+
/> }
2122
<div className="text-sm leading-tight">
2223
<p className="font-semibold text-black dark:text-white mb-0">
2324
<span className="absolute inset-0"></span>

src/theme/BlogLayout/index.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import React, {type ReactNode} from 'react';
2+
import clsx from 'clsx';
3+
import Layout from '@theme/Layout';
4+
import BlogSidebar from '@theme/BlogSidebar';
5+
6+
import type {Props} from '@theme/BlogLayout';
7+
8+
export default function BlogLayout(props: Props): ReactNode {
9+
const {sidebar, toc, children, ...layoutProps} = props;
10+
const hasSidebar = sidebar && sidebar.items.length > 0;
11+
12+
return (
13+
<Layout {...layoutProps}>
14+
<div className="container margin-vert--lg">
15+
<div className="row">
16+
<main
17+
className={clsx('col', {
18+
'col--7': hasSidebar && toc,
19+
'col--9 col--offset-1': !hasSidebar && toc,
20+
'col--9': hasSidebar && !toc,
21+
'col--12': !hasSidebar && !toc,
22+
})}>
23+
{children}
24+
</main>
25+
{toc && <div className="col col--2">{toc}</div>}
26+
</div>
27+
</div>
28+
</Layout>
29+
);
30+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import React, {type ReactNode} from 'react';
2+
import type {Props} from '@theme/BlogPostItem/Container';
3+
4+
export default function BlogPostItemContainer({
5+
children,
6+
className,
7+
}: Props): ReactNode {
8+
return <article className={className}>{children}</article>;
9+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import React, {type ReactNode} from 'react';
2+
import clsx from 'clsx';
3+
import {blogPostContainerID} from '@docusaurus/utils-common';
4+
import {useBlogPost} from '@docusaurus/plugin-content-blog/client';
5+
import MDXContent from '@theme/MDXContent';
6+
import type {Props} from '@theme/BlogPostItem/Content';
7+
8+
export default function BlogPostItemContent({
9+
children,
10+
className,
11+
}: Props): ReactNode {
12+
const {isBlogPostPage} = useBlogPost();
13+
return (
14+
<div
15+
// This ID is used for the feed generation to locate the main content
16+
id={isBlogPostPage ? blogPostContainerID : undefined}
17+
className={clsx('markdown', className)}>
18+
<MDXContent>{children}</MDXContent>
19+
</div>
20+
);
21+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import React, {type ReactNode} from 'react';
2+
import Translate, {translate} from '@docusaurus/Translate';
3+
import Link from '@docusaurus/Link';
4+
import type {Props} from '@theme/BlogPostItem/Footer/ReadMoreLink';
5+
6+
function ReadMoreLabel() {
7+
return (
8+
<b>
9+
<Translate
10+
id="theme.blog.post.readMore"
11+
description="The label used in blog post item excerpts to link to full blog posts">
12+
Read more
13+
</Translate>
14+
</b>
15+
);
16+
}
17+
18+
export default function BlogPostItemFooterReadMoreLink(
19+
props: Props,
20+
): ReactNode {
21+
const {blogPostTitle, ...linkProps} = props;
22+
return (
23+
<Link
24+
aria-label={translate(
25+
{
26+
message: 'Read more about {title}',
27+
id: 'theme.blog.post.readMoreLabel',
28+
description:
29+
'The ARIA label for the link to full blog posts from excerpts',
30+
},
31+
{title: blogPostTitle},
32+
)}
33+
{...linkProps}>
34+
<ReadMoreLabel />
35+
</Link>
36+
);
37+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import React, {type ReactNode} from 'react';
2+
import clsx from 'clsx';
3+
import {useBlogPost} from '@docusaurus/plugin-content-blog/client';
4+
import {ThemeClassNames} from '@docusaurus/theme-common';
5+
import TagsListInline from '@theme/TagsListInline';
6+
import ReadMoreLink from '@theme/BlogPostItem/Footer/ReadMoreLink';
7+
8+
export default function BlogPostItemFooter(): ReactNode {
9+
const {metadata, isBlogPostPage} = useBlogPost();
10+
const {
11+
tags,
12+
title,
13+
editUrl,
14+
hasTruncateMarker,
15+
} = metadata;
16+
17+
// A post is truncated if it's in the "list view" and it has a truncate marker
18+
const truncatedPost = !isBlogPostPage && hasTruncateMarker;
19+
20+
const tagsExists = tags.length > 0;
21+
22+
const renderFooter = tagsExists || truncatedPost || editUrl;
23+
24+
if (!renderFooter) {
25+
return null;
26+
}
27+
28+
// BlogPost footer - details view
29+
if (isBlogPostPage) {
30+
return (
31+
<footer className="docusaurus-mt-lg">
32+
{tagsExists && (
33+
<div
34+
className={clsx(
35+
'row',
36+
'margin-top--sm',
37+
ThemeClassNames.blog.blogFooterEditMetaRow,
38+
)}>
39+
<div className="col">
40+
<TagsListInline tags={tags} />
41+
</div>
42+
</div>
43+
)}
44+
</footer>
45+
);
46+
}
47+
// BlogPost footer - list view
48+
else {
49+
return (
50+
<footer className="row docusaurus-mt-lg">
51+
{tagsExists && (
52+
<div className={clsx('col', {'col--9': truncatedPost})}>
53+
<TagsListInline tags={tags} />
54+
</div>
55+
)}
56+
{truncatedPost && (
57+
<div
58+
className={clsx('col text--right', {
59+
'col--3': tagsExists,
60+
})}>
61+
<ReadMoreLink blogPostTitle={title} to={metadata.permalink} />
62+
</div>
63+
)}
64+
</footer>
65+
);
66+
}
67+
}

0 commit comments

Comments
 (0)