Skip to content

Commit

Permalink
feat(v2): blog tags
Browse files Browse the repository at this point in the history
  • Loading branch information
yangshun committed May 13, 2019
1 parent 7f5492b commit ff9f008
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 17 deletions.
69 changes: 56 additions & 13 deletions packages/docusaurus-plugin-content-blog/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ const DEFAULT_OPTIONS = {
postsPerPage: 10, // How many posts per page.
blogListComponent: '@theme/BlogListPage',
blogPostComponent: '@theme/BlogPostPage',
blogTagsComponent: '@theme/BlogTagsPage',
blogTagsListComponent: '@theme/BlogTagsListPage',
blogTagsPostsComponent: '@theme/BlogTagsPostsPage',
};

class DocusaurusPluginContentBlog {
Expand Down Expand Up @@ -88,6 +89,7 @@ class DocusaurusPluginContentBlog {
source,
description: frontMatter.description || excerpt,
date,
tags: frontMatter.tags,
title: frontMatter.title || blogFileName,
},
});
Expand Down Expand Up @@ -129,7 +131,7 @@ class DocusaurusPluginContentBlog {

const blogTags = {};
blogPosts.forEach(blogPost => {
const {tags} = blogPost.frontMatter;
const {tags} = blogPost.metadata;
if (!tags || tags.length === 0) {
return;
}
Expand All @@ -154,7 +156,8 @@ class DocusaurusPluginContentBlog {
const {
blogListComponent,
blogPostComponent,
blogTagsComponent,
blogTagsListComponent,
blogTagsPostsComponent,
} = this.options;

const {addRoute, createData} = actions;
Expand Down Expand Up @@ -244,26 +247,66 @@ class DocusaurusPluginContentBlog {
} = this.context;

const basePageUrl = normalizeUrl([baseUrl, routeBasePath]);

const tagsPath = normalizeUrl([basePageUrl, 'tags']);
const tagsModule = {};
Object.keys(blogTags).forEach(tag => {
tagsModule[tag] = {
count: blogTags[tag].length,
permalink: normalizeUrl([tagsPath, tag]),
};
});
const tagsCountPath = await createData(

await Promise.all(
Object.keys(blogTags).map(async tag => {
const permalink = normalizeUrl([tagsPath, tag]);
const postIDs = blogTags[tag];
tagsModule[tag] = {
count: postIDs.length,
permalink,
};

const tagsMetadataPath = await createData(
`${docuHash(permalink)}.json`,
JSON.stringify(
{
tag,
},
null,
2,
),
);

addRoute({
path: permalink,
component: blogTagsPostsComponent,
exact: true,
modules: {
items: postIDs.map(postID => {
const {metadata: postMetadata, metadataPath} = blogItemsToModules[
postID
];
return {
content: {
__import: true,
path: postMetadata.source,
query: {
truncated: true,
},
},
metadata: metadataPath,
};
}),
metadata: tagsMetadataPath,
},
});
}),
);

const tagsListPath = await createData(
`${docuHash(`${tagsPath}-tags`)}.json`,
JSON.stringify(tagsModule, null, 2),
);

addRoute({
path: tagsPath,
component: blogTagsComponent,
component: blogTagsListComponent,
exact: true,
modules: {
tags: tagsCountPath,
tags: tagsListPath,
},
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ import Link from '@docusaurus/Link';
const CHARS_IN_ALPHABET = 26;
const ASCII_LOWERCASE_A = 97;

function BlogTagsPage(props) {
function BlogTagsListPage(props) {
const {tags} = props;

const tagsList = Array(CHARS_IN_ALPHABET)
.fill(null)
.map(_ => []);
.map(() => []);
const allTags = Object.keys(tags).sort();

allTags.forEach(tag => {
Expand Down Expand Up @@ -58,12 +58,12 @@ function BlogTagsPage(props) {
<div className="row">
<div className="col col--8 col--offset-2">
<h1>Tags</h1>
{tagsSection}
<div className="margin-vert--lg">{tagsSection}</div>
</div>
</div>
</div>
</Layout>
);
}

export default BlogTagsPage;
export default BlogTagsListPage;
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
*
* 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 Layout from '@theme/Layout'; // eslint-disable-line
import BlogPostItem from '@theme/BlogPostItem';

function BlogTagsPostPage(props) {
const {metadata, items} = props;
const {tag} = metadata;

return (
<Layout title={`Blog | Tagged ${tag}`} description={`Blog | Tagged ${tag}`}>
<div className="container margin-vert--xl">
<div className="row">
<div className="col col--8 col--offset-2">
<h1>
{items.length} post(s) tagged with &quot;{tag}&quot;
</h1>
<div className="margin-vert--lg">
{items.map(
({content: BlogPostContent, metadata: blogPostMetadata}) => (
<div key={blogPostMetadata.permalink}>
<BlogPostItem
frontMatter={BlogPostContent.frontMatter}
metadata={blogPostMetadata}
truncated>
<BlogPostContent />
</BlogPostItem>
</div>
),
)}
</div>
</div>
</div>
</div>
</Layout>
);
}

export default BlogTagsPostPage;

0 comments on commit ff9f008

Please sign in to comment.