Skip to content

Commit

Permalink
Merge pull request #73 from abelljs/next
Browse files Browse the repository at this point in the history
Expose beforeHTMLWrite function for plugins
  • Loading branch information
saurabhdaware authored Aug 26, 2020
2 parents 4f7451c + 39eea72 commit 70e4637
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 23 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## v0.5.0

- Plugins can now export `beforeHTMLWrite` function

## 0.4.1

- Abell now looks for other ports when 5000 is taken
Expand Down
31 changes: 30 additions & 1 deletion examples/with-plugin/plugins/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,40 @@ function beforeBuild(programInfo, { createContent }) {
}
}

/**
* Executes before HTML string is written into .html file.
* @param {string} htmlTemplate HTML String before writing into .html
* @param {ProgramInfo} programInfo
* @return {string}
*/
function beforeHTMLWrite(htmlTemplate, programInfo) {
const cssToAdd = `
<style>
body {
background-color: green;
}
</style>
`;

const headEndIndex = htmlTemplate.indexOf('</head>');
if (headEndIndex < 0) {
// if the text does not have </head>
return '<head>' + cssToAdd + '</head>' + htmlTemplate;
}

const newHTMLTemplate =
htmlTemplate.slice(0, headEndIndex) +
cssToAdd +
htmlTemplate.slice(headEndIndex);

return newHTMLTemplate;
}

/**
* Runs after build of abell
*/
function afterBuild() {
console.log('After build working!');
}

module.exports = { beforeBuild, afterBuild };
module.exports = { beforeBuild, beforeHTMLWrite, afterBuild };
8 changes: 8 additions & 0 deletions examples/with-plugin/with-plugin.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ describe('examples/with-plugin', () => {
);
});

it('should add additional css from beforeWriteHTML plugin', () => {
expect(
$.index('head > style')
.html()
.replace(/\n|\r|\s/g, '')
).to.equal('body{background-color:green;}');
});

it('should render all the slugs of blog', () => {
const expectedTitles = [
'my-first-blog',
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "abell",
"version": "0.4.1",
"version": "0.5.0",
"description": "Abell is a static blog generator that generates blog in Vanilla JavaScript",
"funding": {
"type": "patreon",
Expand Down
2 changes: 1 addition & 1 deletion src/commands/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ async function build() {

try {
// Build site here
generateSite(programInfo);
await generateSite(programInfo);
} catch (err) {
console.log('\n>>');
console.log(err);
Expand Down
20 changes: 10 additions & 10 deletions src/commands/serve.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const { getFirstLine } = require('../utils/abell-fs');
*/
async function runDevServer(programInfo) {
// Runs Dev server with all the watchers etc.
generateSite({ ...programInfo, logs: 'complete' });
await generateSite({ ...programInfo, logs: 'complete' });
console.log('Starting abell-dev-server 🤠...');

const adsResult = await ads.create({
Expand Down Expand Up @@ -63,13 +63,13 @@ async function runDevServer(programInfo) {
* Trigger on abell.config.js changed
* @param {String} filePath
*/
const onAbellConfigChanged = (filePath) => {
const onAbellConfigChanged = async (filePath) => {
// Read New abell.config.js
// set globalMeta to programInfo
console.log('\n⚙️ Abell Config Changed');
const newAbellConfig = getAbellConfig();
programInfo.abellConfig.globalMeta = newAbellConfig.globalMeta;
generateSite(programInfo);
await generateSite(programInfo);
ads.reload();
console.log(colors.boldGreen('>') + ' Site Rebuilt');
};
Expand Down Expand Up @@ -99,7 +99,7 @@ async function runDevServer(programInfo) {
);
}

generateSite(programInfo);
await generateSite(programInfo);
ads.reload();
console.log(colors.boldGreen('>') + ' Files Rebuilt');
};
Expand All @@ -112,7 +112,7 @@ async function runDevServer(programInfo) {
* @param {Event} event
* @param {String} filePath
*/
const onContentChanged = (event, filePath) => {
const onContentChanged = async (event, filePath) => {
// build content tree again on add/remove
console.log(
`\n📄 Event '${event}' in ${path.relative(process.cwd(), filePath)}`
Expand All @@ -134,7 +134,7 @@ async function runDevServer(programInfo) {
}
);

generateSite(programInfo);
await generateSite(programInfo);
ads.reload();
console.log(colors.boldGreen('>') + ' Files Rebuilt');
} else if (filePath.endsWith('.md')) {
Expand All @@ -148,13 +148,13 @@ async function runDevServer(programInfo) {

if (!content) {
// This block is for *idk what happened but lets rebuild whole thing anyway*
generateSite(programInfo);
await generateSite(programInfo);
console.log(colors.boldGreen('>') + ' Files Rebuilt');
} else if (Object.keys(content).length < 1) {
// if the content does not have values,
// it means something is wrong. So we fallback to full website build
// This will usually happen when index.md is in root of 'content/' directory
generateSite(programInfo);
await generateSite(programInfo);
console.log(colors.boldGreen('>') + ' Files Rebuilt');
} else {
// if file is markdown content
Expand All @@ -165,7 +165,7 @@ async function runDevServer(programInfo) {

clearBundleCache({ ofBundle: content.$path });
for (const template of loopableTemplates) {
createHTMLFile(template, programInfo, {
await createHTMLFile(template, programInfo, {
isContent: true,
content
});
Expand All @@ -176,7 +176,7 @@ async function runDevServer(programInfo) {

ads.reload();
} else {
generateSite(programInfo);
await generateSite(programInfo);
ads.reload();
console.log(colors.boldGreen('>') + ' Files Rebuilt');
}
Expand Down
42 changes: 36 additions & 6 deletions src/utils/general-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,11 @@ const { rmdirRecursiveSync } = require('./abell-fs.js');
*/
async function executeBeforeBuildPlugins(programInfo, { createContent }) {
/** Before Build plugins */
console.log('\n>> Executing beforeBuild plugins');
for (const pluginPath of programInfo.abellConfig.plugins) {
const currentPlugin = require(pluginPath);
if (currentPlugin.beforeBuild) {
console.log(
'>> Plugin BeforeBuild: Executing ' +
path.relative(process.cwd(), pluginPath)
);
console.log('> Plugin ' + path.relative(process.cwd(), pluginPath));

await currentPlugin.beforeBuild(programInfo, { createContent });
}
Expand All @@ -26,18 +24,49 @@ async function executeBeforeBuildPlugins(programInfo, { createContent }) {
*/
async function executeAfterBuildPlugins(programInfo) {
/** After Build plugins */
console.log('\n>> Executing afterBuild plugins');
for (const pluginPath of programInfo.abellConfig.plugins) {
const currentPlugin = require(pluginPath);
if (currentPlugin.afterBuild) {
if (programInfo.logs === 'complete') {
console.log('> Plugin ' + path.relative(process.cwd(), pluginPath));
}
await currentPlugin.afterBuild(programInfo);
}
}
}

/**
* executes beforeHTMLWrite plugins
* @param {string} htmlOutput HTML code in string
* @param {ProgramInfo} programInfo
*/
async function executeBeforeHTMLWritePlugins(htmlOutput, programInfo) {
for (const pluginPath of programInfo.abellConfig.plugins) {
const currentPlugin = require(pluginPath);
if (currentPlugin.beforeHTMLWrite) {
if (programInfo.logs === 'complete') {
console.log(
'>> Plugin AfterBuild: Executing ' +
'> Executing beforeHTMLWrite of ' +
path.relative(process.cwd(), pluginPath)
);
}
await currentPlugin.afterBuild(programInfo);

try {
htmlOutput = await currentPlugin.beforeHTMLWrite(
htmlOutput,
programInfo
);

if (!htmlOutput) throw new Error(`Plugin returned ${htmlOutput}`);
} catch (err) {
console.log(`ERROR in ${path.relative(process.cwd(), pluginPath)}`);
console.log(err);
}
}
}

return htmlOutput;
}

/**
Expand Down Expand Up @@ -176,6 +205,7 @@ const colors = {
module.exports = {
executeBeforeBuildPlugins,
executeAfterBuildPlugins,
executeBeforeHTMLWritePlugins,
clearLocalRequireCache,
exitHandler,
execRegexOnAll,
Expand Down
15 changes: 11 additions & 4 deletions src/utils/generate-site.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const {
const { renderMarkdown, md } = require('./build-utils.js');

const { createBundles, clearBundleCache } = require('./abell-bundler.js');
const { executeBeforeHTMLWritePlugins } = require('./general-helpers.js');

/**
* Hashmap of template content for memoization
Expand All @@ -27,7 +28,7 @@ const templateHashmap = {};
* @param {Boolean} options.isContent
* @param {MetaInfo} options.content
*/
function createHTMLFile(templateObj, programInfo, options) {
async function createHTMLFile(templateObj, programInfo, options) {
// Creates HTML File
/**
* 1. Read .abell template
Expand Down Expand Up @@ -149,6 +150,9 @@ function createHTMLFile(templateObj, programInfo, options) {
});
}

// Execute beforeHTMLWrite plugins
htmlOut = await executeBeforeHTMLWritePlugins(htmlOut, programInfo);

// Write into .html file
fs.writeFileSync(outPath, htmlOut);
if (programInfo.logs === 'complete') {
Expand Down Expand Up @@ -180,7 +184,7 @@ function createHTMLFile(templateObj, programInfo, options) {
* Builds site
* @param {ProgramInfo} programInfo
*/
function generateSite(programInfo) {
async function generateSite(programInfo) {
// Builds site from given program information
if (programInfo.logs == 'complete') console.log('\n>> Abell Build Started\n');

Expand All @@ -194,12 +198,15 @@ function generateSite(programInfo) {
if (template.shouldLoop) {
for (const content of Object.values(programInfo.contentMap)) {
// loop over content
createHTMLFile(template, programInfo, { isContent: true, content });
await createHTMLFile(template, programInfo, {
isContent: true,
content
});
}
continue;
}

createHTMLFile(template, programInfo, {});
await createHTMLFile(template, programInfo, {});
}

// We have to ignore all the files that are require()d inside .abell file
Expand Down

0 comments on commit 70e4637

Please sign in to comment.