mirror of
https://github.com/facebook/docusaurus.git
synced 2025-07-12 06:18:02 +02:00
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:
parent
1697f9cebb
commit
eedd4c481c
38 changed files with 529 additions and 202 deletions
|
@ -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: [
|
||||
{
|
||||
|
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
Loading…
Add table
Add a link
Reference in a new issue