docusaurus/packages/docusaurus-1.x/lib/core/DocsLayout.js
Yangshun Tay a690d34af0
feat(v1): allow specifying meta desc in front matter (#1859)
* feat(v1): allow specifying meta desc in front matter

* misc(v2): sync with v1
2019-10-20 11:17:10 -07:00

167 lines
5.3 KiB
JavaScript

/**
* 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.
*/
const classNames = require('classnames');
const path = require('path');
const React = require('react');
const url = require('url');
const Container = require('./Container.js');
const Doc = require('./Doc.js');
const DocsSidebar = require('./DocsSidebar.js');
const OnPageNav = require('./nav/OnPageNav.js');
const Site = require('./Site.js');
const translation = require('../server/translation.js');
const docs = require('../server/docs.js');
const {idx, getGitLastUpdatedTime, getGitLastUpdatedBy} = require('./utils.js');
// component used to generate whole webpage for docs, including sidebar/header/footer
class DocsLayout extends React.Component {
getRelativeURL = (from, to) => {
const extension = this.props.config.cleanUrl ? '' : '.html';
const relativeHref = path
.relative(`${from}.html`, `${to}.html`)
.replace('\\', '/')
.replace(/^\.\.\//, '')
.replace(/\.html$/, extension);
return url.resolve(
`${this.props.config.baseUrl}${this.props.metadata.permalink}`,
relativeHref,
);
};
render() {
const metadata = this.props.metadata;
const content = this.props.children;
const i18n = translation[metadata.language];
const id = metadata.localized_id;
const defaultTitle = metadata.title;
let DocComponent = Doc;
if (this.props.Doc) {
DocComponent = this.props.Doc;
}
const filepath = docs.getFilePath(metadata);
const updateTime = this.props.config.enableUpdateTime
? getGitLastUpdatedTime(filepath)
: null;
const updateAuthor = this.props.config.enableUpdateBy
? getGitLastUpdatedBy(filepath)
: null;
const title =
idx(i18n, ['localized-strings', 'docs', id, 'title']) || defaultTitle;
const hasOnPageNav = this.props.config.onPageNav === 'separate';
const previousTitle =
idx(i18n, [
'localized-strings',
'docs',
metadata.previous_id,
'sidebar_label',
]) ||
idx(i18n, ['localized-strings', 'docs', metadata.previous_id, 'title']) ||
idx(i18n, ['localized-strings', 'previous']) ||
metadata.previous_title ||
'Previous';
const nextTitle =
idx(i18n, [
'localized-strings',
'docs',
metadata.next_id,
'sidebar_label',
]) ||
idx(i18n, ['localized-strings', 'docs', metadata.next_id, 'title']) ||
idx(i18n, ['localized-strings', 'next']) ||
metadata.next_title ||
'Next';
return (
<Site
config={this.props.config}
className={classNames('sideNavVisible', {
separateOnPageNav: hasOnPageNav,
})}
title={title}
description={metadata.description || content.trim().split('\n')[0]}
language={metadata.language}
version={metadata.version}
metadata={metadata}>
<div className="docMainWrapper wrapper">
<DocsSidebar
collapsible={this.props.config.docsSideNavCollapsible}
metadata={metadata}
/>
<Container className="mainContainer">
<DocComponent
metadata={metadata}
content={content}
config={this.props.config}
source={metadata.source}
hideTitle={metadata.hide_title}
title={title}
version={metadata.version}
language={metadata.language}
/>
{(updateTime || updateAuthor) && (
<div className="docLastUpdate">
<em>
Last updated
{updateTime && ` on ${updateTime}`}
{updateAuthor && ` by ${updateAuthor}`}
</em>
</div>
)}
<div className="docs-prevnext">
{metadata.previous_id && (
<a
className="docs-prev button"
href={this.getRelativeURL(
metadata.localized_id,
metadata.previous_id,
)}>
<span className="arrow-prev"> </span>
<span
className={
previousTitle.match(/[a-z][A-Z]/) &&
'function-name-prevnext'
}>
{previousTitle}
</span>
</a>
)}
{metadata.next_id && (
<a
className="docs-next button"
href={this.getRelativeURL(
metadata.localized_id,
metadata.next_id,
)}>
<span
className={
nextTitle.match(/[a-z][A-Z]/) && 'function-name-prevnext'
}>
{nextTitle}
</span>
<span className="arrow-next"> </span>
</a>
)}
</div>
</Container>
{hasOnPageNav && (
<nav className="onPageNav">
<OnPageNav rawContent={content} />
</nav>
)}
</div>
</Site>
);
}
}
module.exports = DocsLayout;