diff --git a/src/containers/MainContainer.js b/src/containers/MainContainer.js index 7c20399..3d7c226 100644 --- a/src/containers/MainContainer.js +++ b/src/containers/MainContainer.js @@ -18,6 +18,8 @@ export default class MainContainer extends Component { data = props.staticContext.data } + console.log(data) + this.state = { isLoadingBlog: !data.posts, isLoadingAbout: !data.about, diff --git a/src/containers/PostContainer.js b/src/containers/PostContainer.js index eca6be0..64096e6 100644 --- a/src/containers/PostContainer.js +++ b/src/containers/PostContainer.js @@ -4,15 +4,24 @@ import { Post, Wrapper, NotFoundPage } from '../components' export default class PostContainer extends Component { static propTypes = { - data: PropTypes.object.isRequired + staticContext: PropTypes.object.isRequired } - constructor () { - super() + constructor (props) { + super(props) + + let post + if (__isBrowser__) { + post = window.__INITIAL_DATA__ + delete window.__INITIAL_DATA__ + } else { + post = props.staticContext.data + } this.state = { - isLoading: true, - error: false + isLoading: !post, + error: false, + post: post } } diff --git a/src/server.js b/src/server.js index 52143dc..a9dfc3b 100644 --- a/src/server.js +++ b/src/server.js @@ -1,10 +1,12 @@ import express from 'express' import { serverRender } from './utils/serverRender' -require('./utils/scanner')() +import Scanner from './scanner' const port = process.env.PORT || 3000 const app = express() +Scanner.scan() + app.use('/static', express.static('public/static')) app.get('/favicon.ico', (req, res) => { diff --git a/src/utils/api.js b/src/utils/api.js index 1fe02de..65aeedb 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -8,13 +8,13 @@ export function getData (reqPath = '') { return readData(config.dataPath) } else { const fileName = path.join(process.cwd(), 'renders/', reqPath + '.html') - return readFile(fileName) + return readFile(fileName, 'utf8') } }; -function readFile (fileName, type) { +function readFile (fileName, options) { return new Promise(function (resolve, reject) { - fs.readFile(fileName, (err, data) => { + fs.readFile(fileName, options, (err, data) => { err ? reject(err) : resolve(data) }) }) diff --git a/src/utils/compiler.js b/src/utils/compiler.js deleted file mode 100644 index 4aab93c..0000000 --- a/src/utils/compiler.js +++ /dev/null @@ -1,135 +0,0 @@ -const MarkdownIt = require('markdown-it') -const fs = require('fs') -const path = require('path') -const moment = require('moment') -const jsonfile = require('jsonfile') -const async = require('async') -const fm = require('front-matter') -const config = require('../../config.json') - -/** - * Renders file using MarkdownIt - */ -function render (file) { - const md = new MarkdownIt({ html: true }) - return md.render(file) -} - -/** - * Extracts file metadata such as parent directory - */ -function fileMetadata (filepath) { - const paths = filepath.split('/') - const basename = path.basename(filepath) - - const metadata = { - basename, - filename: basename.substr(0, basename.lastIndexOf('.')), - parrent: paths[paths.length - 2], - dirname: path.dirname(filepath) - } - - return metadata -} - -/** - * Compiles file that is a blog post - */ -function compilePost (filepath, data, fileData, callback) { - const frontMatter = fm(fileData) - const rendered = render(frontMatter.body) - const metadata = fileMetadata(filepath) - - if (frontMatter.attributes.draft) { - callback(null, null) - return - } - - let published - if (frontMatter.attributes.date) { - published = moment(frontMatter.attributes.date) - } else { - published = moment() - } - - const post = { - published: published.format('MMMM DD, YYYY'), - filename: metadata.filename, - title: frontMatter.attributes.title, - link: '/post/' + metadata.filename - } - - const renderedpath = path.join(process.cwd(), config.renderPath, `${metadata.filename}.html`) - - fs.writeFile(renderedpath, rendered, (err) => { - if (err) callback(err) - else callback(null, post) - }) -} - -/** - * Compiles other types of files such as resumes, about me and so on. - */ -function compileOther (filepath, data, fileData, callback) { - const frontMatter = fm(fileData) - const rendered = render(frontMatter.body) - const metadata = fileMetadata(filepath) - - const post = { - filename: metadata.filename - } - - const renderedpath = path.join(process.cwd(), config.renderPath, `${metadata.filename}.html`) - - fs.writeFile(renderedpath, rendered, (err) => { - if (err) callback(err) - else callback(null, post) - }) -} - -function Compiler (data) { - this.data = data -} - -/** - * - */ -Compiler.prototype.addFile = function (filepath, isPost, callback) { - if (isPost) { - async.waterfall([ - fs.readFile.bind(fs, filepath, 'utf8'), - compilePost.bind(compilePost, filepath, this.data) - ], (err, result) => { - if (err) throw err - - if (result == null) { - callback() - } else { - this.data.posts.push(result) - console.log('[Compiler] File %s compiled', filepath) - callback() - } - }) - } else { - async.waterfall([ - fs.readFile.bind(fs, filepath, 'utf8'), - compileOther.bind(compileOther, filepath, this.data) - ], (err, result) => { - if (err) throw err - - this.data.other.push(result) - console.log('[Compiler] File %s compiled', filepath) - callback() - }) - } -} - -/** - * Writes updated data to the data file - */ -Compiler.prototype.writeData = function (callback) { - // console.log(this.data) - jsonfile.writeFile(config.dataPath, this.data, callback) -} - -module.exports = Compiler diff --git a/src/utils/scanner.js b/src/utils/scanner.js index cb2c381..3d436b5 100644 --- a/src/utils/scanner.js +++ b/src/utils/scanner.js @@ -1,62 +1,96 @@ -const fs = require('fs') -const path = require('path') -const async = require('async') -const Compiler = require('./compiler') -const config = require('../../config.json') -const jsonfile = require('jsonfile') +import fs from 'fs' +import async from 'async' +import path from 'path' +import config from '../../config.json' +import fm from 'front-matter' +import moment from 'moment' +import jsonfile from 'jsonfile' -module.exports = function () { - const data = jsonfile.readFileSync(config.dataPath) - var compiler = new Compiler(data) - - /** - * Reads the directory and returns it's content - */ - function readdir (callback) { +class Scanner { + readdir (callback) { fs.readdir(config.contentPath, callback) } - /** - * Calls compile on each file in the directory - */ - function compile (files, callback) { + processAll (files, callback) { console.log('[Scanner] Discovered files: ' + files) - async.each(files, compileFile, (err) => { + async.each(files, this.processFile, (err) => { if (err) throw err callback() }) } - /** - * Helper function which calls compile in the Compiler module - */ - function compileFile (file, callback) { + processFile (file, callback) { const filePath = path.join(process.cwd(), config.contentPath, file) + const metadata = this.fileMetadata(filePath) - // config.files contains list of file names which are not considered blog posts - if (config.files.indexOf(file) === -1) { - compiler.addFile(filePath, true, callback) - } else { - compiler.addFile(filePath, false, callback) + fs.readFile(filePath, 'utf8', (err, data) => { + if (err) throw err + + if (config.files.indexOf(file) === -1) { + const frontMatter = fm(data) + + if (frontMatter.attributes.draft) { + callback(null, null) + return + } + + let published + if (frontMatter.attributes.date) { + published = moment(frontMatter.attributes.date) + } else { + published = moment() + } + + const post = { + published: published.format('MMMM DD, YYYY'), + filename: metadata.filename, + title: frontMatter.attributes.title, + link: '/post/' + metadata.filename + } + + this.data.posts.push(post) + } else { + this.data.push({ + [metadata.filename]: data + }) + } + }) + } + + init (callback) { + jsonfile.readFile(config.dataPath, (err, data) => { + if (err) throw err + + this.data = data + }).bind(this) + } + + writeData (callback) { + jsonfile.writeFile(config.dataPath, this.data, callback) + } + + fileMetadata (filepath) { + const paths = filepath.split('/') + const basename = path.basename(filepath) + + const metadata = { + basename, + filename: basename.substr(0, basename.lastIndexOf('.')), + parrent: paths[paths.length - 2], + dirname: path.dirname(filepath) } + + return metadata } - /** - * Writes updated data into the data file - */ - function writeData (callback) { - compiler.writeData(callback) + scan () { + async.waterfall([ + this.init, + this.readdir, + this.processAll, + this.writeData + ], (err) => { + if (err) throw err + }) } - - /** - * Main function. Scans the directory for files and compiles them into html - * using the Compiler module - */ - async.waterfall([ - readdir, - compile, - writeData - ], (err) => { - if (err) throw err - }) }