feat(v2): implement theme component overriding (#1435)

* feat(v2): implement component overriding

* siteDir theme overriding should work for > 1 level directory

* fallback for essential component like Loading

* rename default -> classic
This commit is contained in:
Yangshun Tay 2019-05-06 05:25:04 -07:00 committed by Endi
parent 1697f9cebb
commit eedd4c481c
38 changed files with 529 additions and 202 deletions

View file

@ -158,6 +158,22 @@ class DocusaurusPluginContentBlog {
configureWebpack(config, isServer, {getBabelLoader, getCacheLoader}) {
return {
resolve: {
alias: {
'@theme/BlogListPage': path.resolve(
__dirname,
'./theme/BlogListPage',
),
'@theme/BlogPostItem': path.resolve(
__dirname,
'./theme/BlogPostItem',
),
'@theme/BlogPostPage': path.resolve(
__dirname,
'./theme/BlogPostPage',
),
},
},
module: {
rules: [
{

View file

@ -0,0 +1,38 @@
/**
* 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 BlogListPage(props) {
const {
metadata: {posts = []},
entries: BlogPosts,
} = props;
return (
<Layout title="Blog">
<div className="container margin-vert--xl">
<div className="row">
<div className="col col--6 col--offset-3">
{BlogPosts.map((PostContent, index) => (
<div className="margin-bottom--xl" key={index}>
<BlogPostItem truncated metadata={posts[index]}>
<PostContent />
</BlogPostItem>
</div>
))}
</div>
</div>
</div>
</Layout>
);
}
export default BlogListPage;

View file

@ -0,0 +1,101 @@
/**
* 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 Link from '@docusaurus/Link';
function BlogPostItem(props) {
const {metadata, children, truncated} = props;
const renderPostHeader = () => {
if (!metadata) {
return null;
}
const {
date,
author,
authorURL,
authorTitle,
authorFBID,
permalink,
title,
} = metadata;
const blogPostDate = new Date(date);
const month = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
];
const authorImageURL = authorFBID
? `https://graph.facebook.com/${authorFBID}/picture/?height=200&width=200`
: metadata.authorImageURL;
return (
<header>
<h1>
<Link to={permalink}>{title}</Link>
</h1>
<div className="margin-bottom--sm">
{month[blogPostDate.getMonth()]} {blogPostDate.getDay()},{' '}
{blogPostDate.getFullYear()}
</div>
<div className="avatar margin-bottom--md">
{authorImageURL && (
<a
className="avatar__photo-link"
href={authorURL}
target="_blank"
rel="noreferrer noopener">
<img
className="avatar__photo"
src={authorImageURL}
alt={author}
/>
</a>
)}
<div className="avatar__intro">
{author && (
<>
<h4 className="avatar__name">
<a href={authorURL} target="_blank" rel="noreferrer noopener">
{author}
</a>
</h4>
<small className="avatar__subtitle">{authorTitle}</small>
</>
)}
</div>
</div>
</header>
);
};
return (
<div>
{renderPostHeader()}
<article className="markdown">{children}</article>
{truncated && (
<div className="text--right">
<Link className="button button--secondary" to={metadata.permalink}>
Read More
</Link>
</div>
)}
</div>
);
}
export default BlogPostItem;

View file

@ -0,0 +1,33 @@
/**
* 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 BlogPostPage(props) {
const {content: BlogPostContents, metadata} = props;
return (
<Layout title={metadata.title}>
{BlogPostContents && (
<div className="container margin-vert--xl">
<div className="row">
<div className="col col--6 col--offset-3">
<BlogPostItem metadata={metadata}>
<BlogPostContents />
</BlogPostItem>
</div>
</div>
</div>
)}
</Layout>
);
}
export default BlogPostPage;