RandomChad/website/modules/publish-pug.js
2021-10-16 13:20:49 +02:00

107 lines
3.8 KiB
JavaScript

const getAllPugfiles = require( __dirname + '/parse-pugfiles' )
const getContent = require( __dirname + '/parse-locales' )
const pfs = require( __dirname + '/parse-fs' )
const pug = require( 'pug' )
const { inlinecss } = require( './publish-css' )
const { minify } = require( 'html-minifier' )
const { SitemapStream, streamToPromise } = require( 'sitemap' )
const site = require( __dirname + '/config' )
// Compile pug to html
// Return a resolved promise with the file data
const compilepug = ( path, filename, css, content ) => Promise.resolve( {
path: path,
filename: filename,
baseSlug: content.slug,
lang: content.lang,
// Compile the pug file with the site config as a local variable
html: minify( pug.renderFile( path + filename, { site: site, css: css, content: content, basedir: path } ), {
html5: true,
minifyCSS: true,
minifyJS: true,
collapseWhitespace: true,
conservativeCollapse: true,
processScripts: [ 'application/ld+json' ]
} )
} )
// Construct links
const makeLinks = ( pugfiles, content ) => {
// Paths of files and thus the urls
const paths = pugfiles.map( page => page.filename )
// Structure the URLs for the sitemap package
const structuredUrls = paths.map( path => ( {
url: `${ site.system.url }${ path.split( '.' )[ 0 ] }.html`,
links: content.map( lang => ( {
lang: lang.lang,
// Remove trailing slash freom system ur
url: `${ site.system.url.replace(/\/$/, "") }${ lang.slug }${ path.split( '.' )[ 0 ] }.html`
} ) )
} ) )
return structuredUrls
}
// Make sitemap
const makeSitemap = links => {
const stream = new SitemapStream( { hostname: site.system.url } )
links.map( link => stream.write( link ) )
stream.end()
return streamToPromise( stream ).then( data => data.toString() )
}
// Run a promise for every content item
const makeAllPugs = ( pugstrings, css, contents ) => Promise.all( contents.map( content => {
// For every json declaration, make all pages
return pugstrings.map( pug => compilepug( site.system.source, pug.filename, css, content ) )
// Flatten the array of arrays to just be an array of promises
} ).flat() )
// Write html to disk
// Use the safe write feature of the psf module
const writehtml = async ( site, page ) => {
const folder = site.system.public + page.baseSlug + page.filename.split( '.' )[ 0 ]
await pfs.mkdir( folder )
return Promise.all( [
pfs.swrite( site.system.public + page.baseSlug, `${ page.filename.split( '.' )[ 0 ] }.html`, page.html ),
pfs.swrite( site.system.public + page.baseSlug + page.filename.split( '.' )[ 0 ] + '/', `index.html`, page.html )
] )
}
const writeSitemap = ( site, sitemap ) => pfs.swrite( site.system.public, 'sitemap.xml', sitemap.toString() )
// Combine the above two and the parse-pugfiles module to read, compile and write all pug files
// Make the public directory
const publishfiles = async ( site, filter ) => {
await pfs.mkdir( site.system.public )
// Grab the pug data from disk
const [ pugfiles, css, content ] = await Promise.all( [
getAllPugfiles( site.system.source ),
inlinecss( site, `${ site.system.source }css/essential-above-the-fold.sass` ),
getContent( `${ site.system.source }content` )
] )
// Parse pug into html
// Pugfiles have .filename and .data
// If fitler applied, only build pug htmls but include all links into the links for sitemap
const filteredPugfiles = filter ? pugfiles.filter( ( { filename } ) => filename.includes( filter ) ) : pugfiles
const [ htmls, links ] = await Promise.all( [
makeAllPugs( filteredPugfiles, css, content ),
makeLinks( pugfiles, content )
] )
// Write html files to disk
// Html ( page ) has .path, .filename .baseSlug and .html
return Promise.all( [
Promise.all( htmls.map( page => writehtml( site, page ) ) ),
writeSitemap( site, await makeSitemap( links ) )
] )
}
module.exports = publishfiles