const path = require('path') const slugify = require('slugify') const merge = require('lodash.merge') const nunjucks = require('nunjucks') const assign = require('assign-deep') const fs = require('fs') const Media = require('./../factories/media.js') const parseMarkdownFile = require('./../parsers/markdown.js') const configStore = require('./../config.js') /** * Page - building from markdown file * * * @author Björn Hase * @license http://opensource.org/licenses/MIT The MIT License * @link https://gitea.node001.net/HerrHase/siteomat-webpack-plugin.git * */ class Page { /** * * * @param {object} file * @param {string} parent * @param {string} fileString * @param {object} [blocks=null] * */ constructor(file, parent, fileString, blocks = {}) { // getting dirPath for files for page this._dirPath = this._resolvePath(parent) // parse file const result = parseMarkdownFile(fileString, this._dirPath) // fields merge by default values this._fields = merge({ view: 'page.njk', extensions: 'html', meta: { robots: 'index' }, hidden: false }, result.fields) // adding filename for html as pathname and relative path in structure this._filename = this._resolveFilename(file) this._slug = this._resolveSlug(this._filename) this._permalink = this._dirPath if (this._slug) { this._permalink = this._dirPath + '/' + this._slug } // check if page is in subdirectory if (fs.existsSync(configStore.get('source') + this._permalink) && this._slug) { this._dirPath += '/' + this._slug this._filename = 'index' } this._filename += '.' + this._fields.extensions this._content = result.content this._blocks = blocks // check for fields and resolve media if (this._fields) { this._fields = this._resolveMedia(this._fields, this._dirPath) } // check for fields and resolve media if (this._blocks) { for (const key of Object.keys(this._blocks)) { if (Array.isArray(this._blocks[key])) { this._blocks[key].forEach((fields, index) => { this._blocks[key][index] = this._resolveMedia(fields, this._dirPath + '/_blocks') }) } else { this._blocks[key] = this._resolveMedia(this._blocks[key], this._dirPath + '/_blocks') } } } } /** * create Page Object * * * @return {object} * */ get() { return assign({ 'content' : this._content, 'blocks' : this._blocks, 'dirPath' : this._dirPath, 'path' : this._dirPath + '/' + this._filename, 'permalink' : this._permalink, 'filename' : this._filename }, this._fields) } /** * * */ _resolveMedia(fields, dirPath) { for (const key of Object.keys(fields)) { if (key === 'src') { fields[key] = this._resolveMediaSrc(fields[key], dirPath) } if (toString.call(fields[key]) === '[object Object]') { fields[key] = this._resolveMedia(fields[key], dirPath) } } return fields } /** * * */ _resolveMediaSrc(field, dirPath) { const media = new Media(dirPath) if (typeof field === 'string' || field instanceof String) { field = media.resolve(field) } if (typeof field === 'object' || field instanceof Object) { if (field.options) { field = media.resolve(field.src, field.sizes, field.options) } else { field = media.resolve(field.src, field.sizes) } } return field } /** * * */ _resolveSlug(filename) { let slug = filename if (slug === 'index') { slug = '' } return slug } /** * create html-filename = filename * * @param {string} file * @return {string} * */ _resolveFilename(file) { let filename = file.name if (filename === 'index.md') { filename = 'index' } else { if (path.extname(filename) === '.md') { filename = filename.replace('.md', '') } filename = slugify(filename) } return filename } /** * pathname = parent * * @param {string} parent * @return {string} * */ _resolvePath(parent, slug) { let path = parent if (parent === '/') { path = '' } return path } } module.exports = Page