Flow-based reimplementation of the Jekyll static site generator. This provides several advantages for Node.js and especially NoFlo developers:
- Pure JavaScript, no need for Ruby or other runtimes in your environment. Especially handy if you're using Grunt for site generation
- Other data sources, in NoFlo everything is just a flow of data. You could easily plug in other data sources than the file system. For example, database query results
- Different converters, don't want to use Markdown? Just plug in your own mark-up processor component
- Different template engines, don't want to use Liquid? Just plug in your own template processor component
- Use as library or executable, this Jekyll implementation is just a NoFlo graph. You can use it in other NoFlo applications, as a Node.js module, or as a command-line executable
However, as with any reimplementation of a application being actively developed, there are also some potential caveats to observe.
NoFlo Jekyll has been implemented as a NoFlo graph. Most of the logic is handled by various existing NoFlo components, but there are also some places where implementing things as a custom component made sense. Over 85% of the codebase is completely reusable, however.
Here is how the main flow looks like when visualized using NoFlo UI:
You can find the main flow and the different subgraphs from the graphs folder.
If you want to use this as a command-line executable, then the easiest option is to install it globally with:
$ npm install -g noflo-jekyll
If you want to use it as a library inside a bigger application, then just install it as a dependency by:
$ npm install noflo-jekyll --save
Since this project aims for feature parity with Jekyll, the command-line usage is similar. To generate a site, run:
$ noflo-jekyll source_dir target_dir
The site generation graph can also be used as a library in Node.js applications.
var Jekyll, generator;
Jekyll = require('noflo-jekyll').Jekyll;
// Prepare the site generator
generator = new Jekyll('source_dir', 'target_dir');
// Event handling
generator.on('start', function () {
console.log("Build started");
});
generator.on('error', console.error);
generator.on('end', function (end) {
var seconds = end.uptime / 1000;
console.log("Build finished in " + seconds);
});
// Start the process
generator.run();
The main site generation flow is exposed as the jekyll/Jekyll
graph. Here is a simple example of using it in another graph:
# Directory setup
'/some/source/directory' -> SOURCE Generator(jekyll/Jekyll)
'/some/target/directory' -> DESTINATION Generator()
# Outputs
Generator() GENERATED -> IN Drop(Drop)
Generator() ERRORS -> IN Display(Output)
The Liquid Templating library we use, liquid-node does not cover 100% of the Liquid spec, so some template parameters that work with Jekyll might not yet work.
We're working with the liquid-node developers to improve the coverage, and this is something you can also help with. Please report an issue if you are using something that doesn't work!
When this project was started, Jekyll was still in the pre-1.0 stage, and its development had stopped. Since then, its development resumed, and 1.0 added features that we don't yet provide. These include:
- Draft posts
- Timezones
- Baseurl
Please report any issues you encounter with these or other Jekyll features.
The Ruby Jekyll includes a rudimentary web server for testing purposes. As that is outside of the scope of static site generation, this feature was not included into the NoFlo Jekyll implementation. You can serve the generated pages in many ways, including grunt-contrib-connect, simple-server, or NoFlo webserver.
Pull requests are welcome for any missing Jekyll features or other issues! If you want to work with the repository, it is best to be able to test it locally.
Our main body of tests consists of a Jekyll website source in test/fixtures/source
that we have generated to a static site with the Ruby Jekyll. We run NoFlo Jekyll against the same sources, and check that the results are identical (save for some whitespace differences).
If you find things NoFlo Jekyll doesn't handle correctly, add them to that Jekyll site source, and then run Ruby Jekyll fixture regeneration with:
$ grunt jekyll
After this you should be able to run the tests with:
$ grunt test