Enable clean / extension-less url (#677)

This commit is contained in:
Endilie Yacop Sucipto 2018-06-07 04:37:49 +08:00 committed by Joel Marcey
parent aee255219b
commit 31f0c27f81
14 changed files with 124 additions and 50 deletions

View file

@ -11,6 +11,7 @@ const Container = require('./Container.js');
const MetadataBlog = require('./MetadataBlog.js');
const React = require('react');
const Site = require('./Site.js');
const utils = require('./utils.js');
// used to generate entire blog pages, i.e. collection of truncated blog posts
class BlogPageLayout extends React.Component {
@ -45,7 +46,10 @@ class BlogPageLayout extends React.Component {
post={post}
content={post.content}
truncate={true}
key={post.path + post.title}
key={
utils.getPath(post.path, this.props.config.cleanUrl) +
post.title
}
config={this.props.config}
/>
);

View file

@ -8,7 +8,7 @@
const MarkdownBlock = require('./MarkdownBlock.js');
const React = require('react');
const utils = require('./utils');
const utils = require('./utils.js');
// inner blog component for the article itself, without sidebar/header/footer
class BlogPost extends React.Component {
@ -24,7 +24,12 @@ class BlogPost extends React.Component {
<a
className="button"
href={
this.props.config.baseUrl + 'blog/' + this.props.post.path
this.props.config.baseUrl +
'blog/' +
utils.getPath(
this.props.post.path,
this.props.config.cleanUrl
)
}>
Read More
</a>
@ -73,7 +78,12 @@ class BlogPost extends React.Component {
const post = this.props.post;
return (
<h1>
<a href={this.props.config.baseUrl + 'blog/' + post.path}>
<a
href={
this.props.config.baseUrl +
'blog/' +
utils.getPath(post.path, this.props.config.cleanUrl)
}>
{post.title}
</a>
</h1>

View file

@ -10,11 +10,13 @@ const BlogPost = require('./BlogPost.js');
const BlogSidebar = require('./BlogSidebar.js');
const Container = require('./Container.js');
const Site = require('./Site.js');
const utils = require('./utils.js');
// used for entire blog posts, i.e., each written blog article with sidebar with site header/footer
class BlogPostLayout extends React.Component {
renderSocialButtons() {
const post = this.props.metadata;
let post = this.props.metadata;
post.path = utils.getPath(post.path, this.props.config.cleanUrl);
const fbComment = this.props.config.facebookAppId &&
this.props.config.facebookComments && (
@ -92,10 +94,12 @@ class BlogPostLayout extends React.Component {
}
render() {
let post = this.props.metadata;
post.path = utils.getPath(post.path, this.props.config.cleanUrl);
return (
<Site
className="sideNavVisible"
url={'blog/' + this.props.metadata.path}
url={'blog/' + post.path}
title={this.props.metadata.title}
language={'en'}
description={this.getDescription()}
@ -104,13 +108,13 @@ class BlogPostLayout extends React.Component {
<div className="docMainWrapper wrapper">
<BlogSidebar
language={'en'}
current={this.props.metadata}
current={post}
config={this.props.config}
/>
<Container className="mainContainer documentContainer postContainer blogContainer">
<div className="lonePost">
<BlogPost
post={this.props.metadata}
post={post}
content={this.props.children}
language={'en'}
config={this.props.config}

View file

@ -28,6 +28,7 @@ class DocsLayout extends React.Component {
this.props.metadata.localized_id
] || this.props.metadata.title
: this.props.metadata.title;
const extension = this.props.config.cleanUrl ? '' : '.html';
return (
<Site
config={this.props.config}
@ -54,7 +55,7 @@ class DocsLayout extends React.Component {
{metadata.previous_id && (
<a
className="docs-prev button"
href={metadata.previous_id + '.html'}>
href={metadata.previous_id + extension}>
{' '}
{i18n
? translation[this.props.metadata.language][
@ -70,7 +71,7 @@ class DocsLayout extends React.Component {
{metadata.next_id && (
<a
className="docs-next button"
href={metadata.next_id + '.html'}>
href={metadata.next_id + extension}>
{i18n
? translation[this.props.metadata.language][
'localized-strings'

View file

@ -20,6 +20,7 @@ const setLanguage = require('../../server/translate.js').setLanguage;
const readMetadata = require('../../server/readMetadata.js');
readMetadata.generateMetadataDocs();
const Metadata = require('../metadata.js');
const utils = require('../utils.js');
// language dropdown nav item for when translations are enabled
class LanguageDropDown extends React.Component {
@ -169,7 +170,9 @@ class HeaderNav extends React.Component {
}
throw new Error(errorStr);
}
href = this.props.config.baseUrl + Metadata[id].permalink;
href =
this.props.config.baseUrl +
utils.getPath(Metadata[id].permalink, this.props.config.cleanUrl);
const {id: currentID, sidebar} = this.props.current;
docItemActive = currentID && currentID === id;
@ -177,14 +180,15 @@ class HeaderNav extends React.Component {
} else if (link.page) {
// set link to page with current page's language if appropriate
const language = this.props.language || '';
const extension = siteConfig.cleanUrl ? '' : '.html';
if (fs.existsSync(CWD + '/pages/en/' + link.page + '.js')) {
href =
siteConfig.baseUrl +
(language ? language + '/' : '') +
link.page +
'.html';
extension;
} else {
href = siteConfig.baseUrl + link.page + '.html';
href = siteConfig.baseUrl + link.page + extension;
}
} else if (link.href) {
// set link to specified href

View file

@ -10,6 +10,7 @@ const classNames = require('classnames');
const siteConfig = require(process.cwd() + '/siteConfig.js');
const translation = require('../../server/translation.js');
const utils = require('../utils.js');
class SideNav extends React.Component {
render() {
@ -81,16 +82,22 @@ class SideNav extends React.Component {
}
return localizedString;
}
// return link to doc in sidebar
getLink(metadata) {
if (metadata.permalink) {
if (metadata.permalink.match(/^https?:/)) {
return metadata.permalink;
const targetLink = utils.getPath(metadata.permalink, siteConfig.cleanUrl);
if (targetLink.match(/^https?:/)) {
return targetLink;
}
return siteConfig.baseUrl + metadata.permalink;
return siteConfig.baseUrl + targetLink;
}
if (metadata.path) {
return siteConfig.baseUrl + 'blog/' + metadata.path;
return (
siteConfig.baseUrl +
'blog/' +
utils.getPath(metadata.path, siteConfig.cleanUrl)
);
}
return null;
}

View file

@ -20,8 +20,20 @@ function extractBlogPostSummary(content) {
return content.substring(0, BLOG_POST_SUMMARY_LENGTH);
}
function getPath(path, cleanUrl = false) {
if (cleanUrl) {
if (path.endsWith('/index.html')) {
return path.replace(/\/index.html$/, '');
} else {
return path.replace(/\.html$/, '');
}
}
return path;
}
module.exports = {
blogPostHasTruncateMarker,
extractBlogPostBeforeTruncate,
extractBlogPostSummary,
getPath,
};