Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: last updated time in docs #913

Merged
merged 10 commits into from
Aug 29, 2018
2 changes: 2 additions & 0 deletions docs/api-site-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ customDocsPath: 'website-docs';

`editUrl` - URL for editing docs, usage example: `editUrl + 'en/doc1.md'`. If this field is omitted, there will be no "Edit this Doc" button for each document.

`enableUpdateTime` - An option to enable the docs showing last update time. Set to `true` to show a line at the bottom right corner of each doc page as `Last Updated: dd/mm/yyyy hh:MM:ss Z`.

`facebookAppId` - If you want Facebook Like/Share buttons in the footer and at the bottom of your blog posts, provide a [Facebook application id](https://www.facebook.com/help/audiencenetwork/804209223039296).

`facebookComments` - Set this to `true` if you want to enable Facebook comments at the bottom of your blog post. `facebookAppId` has to be also set.
Expand Down
16 changes: 15 additions & 1 deletion lib/core/DocsLayout.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ const DocsSidebar = require('./DocsSidebar.js');
const OnPageNav = require('./nav/OnPageNav.js');
const Site = require('./Site.js');
const translation = require('../server/translation.js');
const {idx} = require('./utils.js');
const docs = require('../server/docs.js');
const {idx, getGitLastUpdated} = require('./utils.js');

// component used to generate whole webpage for docs, including sidebar/header/footer
class DocsLayout extends React.Component {
Expand All @@ -43,6 +44,12 @@ class DocsLayout extends React.Component {
if (this.props.Doc) {
DocComponent = this.props.Doc;
}
let updateTime;
if (this.props.config.enableUpdateTime) {
const filepath = docs.getFilePath(metadata);
updateTime = getGitLastUpdated(filepath);
}

const title =
idx(i18n, ['localized-strings', 'docs', id, 'title']) || defaultTitle;
const hasOnPageNav = this.props.config.onPageNav === 'separate';
Expand Down Expand Up @@ -100,6 +107,13 @@ class DocsLayout extends React.Component {
</a>
)}
</div>
{this.props.config.enableUpdateTime &&
updateTime && (
<p style={{fontSize: '12px', textAlign: 'right'}}>
<strong>Last updated: </strong>
{updateTime}
</p>
)}
</Container>
{hasOnPageNav && (
<nav className="onPageNav">
Expand Down
5 changes: 5 additions & 0 deletions lib/core/__tests__/__fixtures__/test.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
title: Don't edit this
---

Do not edit this file
25 changes: 25 additions & 0 deletions lib/core/__tests__/utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,29 @@ describe('utils', () => {
expect(utils.removeExtension('/docs/test')).toBe('/docs/test');
expect(utils.removeExtension('pages.js')).toBe('pages');
});

test('getGitLastUpdated', () => {
// existing test file in repository with git timestamp
const existingFilePath = path.join(__dirname, '__fixtures__', 'test.md');
const gitLastUpdated = utils.getGitLastUpdated(existingFilePath);
expect(typeof gitLastUpdated).toBe('string');
expect(Date.parse(gitLastUpdated)).not.toBeNaN();
expect(gitLastUpdated).not.toBeNull();

// non existing file
const nonExistingFilePath = path.join(
__dirname,
'__fixtures__',
'.nonExisting'
);
expect(utils.getGitLastUpdated(null)).toBeNull();
expect(utils.getGitLastUpdated(undefined)).toBeNull();
expect(utils.getGitLastUpdated(nonExistingFilePath)).toBeNull();

// temporary created file that has no git timestamp
const tempFilePath = path.join(__dirname, '__fixtures__', '.temp');
fs.writeFileSync(tempFilePath, 'Lorem ipsum :)');
expect(utils.getGitLastUpdated(tempFilePath)).toBeNull();
fs.unlinkSync(tempFilePath);
});
});
13 changes: 13 additions & 0 deletions lib/core/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
const spawn = require('cross-spawn');

const TRUNCATE_MARKER = /<!--\s*truncate\s*-->/;

Expand Down Expand Up @@ -32,9 +33,21 @@ function idx(target, path) {
return path.reduce((obj, key) => obj && obj[key], target);
}

function getGitLastUpdated(filepath) {
const timeSpan = spawn
.sync('git', ['log', '-1', '--format=%ct', filepath])
.stdout.toString('utf-8');
if (timeSpan) {
const date = new Date(parseInt(timeSpan, 10) * 1000);
return date.toLocaleString();
}
return null;
}

module.exports = {
blogPostHasTruncateMarker,
extractBlogPostBeforeTruncate,
getGitLastUpdated,
getPath,
removeExtension,
idx,
Expand Down
11 changes: 10 additions & 1 deletion lib/server/docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const readMetadata = require('./readMetadata.js');
const {insertTOC} = require('../core/toc.js');
const {getPath} = require('../core/utils.js');

function getFile(metadata) {
function getFilePath(metadata) {
if (!metadata) {
return null;
}
Expand All @@ -31,6 +31,14 @@ function getFile(metadata) {
} else {
file = join(CWD, '..', readMetadata.getDocsPath(), metadata.source);
}
return file;
}

function getFile(metadata) {
if (!metadata) {
return null;
}
const file = getFilePath(metadata);
if (!fs.existsSync(file)) {
return null;
}
Expand Down Expand Up @@ -123,6 +131,7 @@ function getRedirectMarkup(metadata) {
module.exports = {
getMarkup,
getFile,
getFilePath,
getRedirectMarkup,
mdToHtmlify,
replaceAssetsLink,
Expand Down
94 changes: 83 additions & 11 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
"classnames": "^2.2.6",
"color": "^2.0.1",
"commander": "^2.16.0",
"cross-spawn": "^6.0.5",
"crowdin-cli": "^0.3.0",
"cssnano": "^3.10.0",
"deepmerge": "^2.1.1",
Expand Down
1 change: 1 addition & 0 deletions website/siteConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ const siteConfig = {
scrollToTopOptions: {
zIndex: 100,
},
enableUpdateTime: true,
};

module.exports = siteConfig;
Loading