Last active
November 5, 2016 22:18
-
-
Save 0gust1/10752096 to your computer and use it in GitHub Desktop.
metalsmith static website build, with livreload
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var extname = require('path').extname; | |
var Metalsmith = require('metalsmith'); | |
var myth = require('myth'); | |
var http = require('http'); | |
var templates = require('metalsmith-templates'); | |
var markdown = require('metalsmith-markdown'); | |
var watch = require('metalsmith-watch'); | |
/** | |
* Live reload server | |
*/ | |
var tinylr = require('tiny-lr-fork'); | |
// standard LiveReload port | |
var port = 35729; | |
// tinylr(opts) => new tinylr.Server(opts); | |
tinylr().listen(port, function(err) { | |
if(err) { | |
// deal with err | |
return; | |
} | |
console.log('... Tinylr (tiny-lr-fork), listening on port %s ...', port); | |
}) | |
/** | |
* Local server, tied with livereload | |
*/ | |
var connect = require('connect'); | |
var app= connect(); | |
app.use(require('connect-livereload')({ | |
port: 35729 | |
})); | |
app.use(connect.static(__dirname+'/build')); | |
http.createServer(app).listen(8080); | |
/** | |
* Build. | |
*/ | |
var metalsmith = Metalsmith(__dirname) | |
.source('content') | |
.use(watch) | |
.use(markdown({ | |
smartypants: true, | |
gfm: true, | |
tables: true | |
})) | |
.use(templates({ | |
engine: 'swig', | |
directory: 'templates', | |
autoescape:false | |
})) | |
.use(mythify) | |
.build(function(err){ | |
if (err) throw err; | |
}); | |
/** | |
* mythify plugin. | |
* | |
* @param {Object} files | |
* @param {Metalsmith} metalsmith | |
* @param {Function} done | |
*/ | |
function mythify(files, metalsmith, done){ | |
var css = ''; | |
for (var file in files) { | |
if ('.css' != extname(file)) continue; | |
css += files[file].contents.toString(); | |
delete files[file]; | |
} | |
css = myth(css); | |
files['persoo.css'] = { | |
contents: new Buffer(css) | |
}; | |
done(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
var relative = require('path').relative; | |
var fs = require('fs'); | |
var path = require('path'); | |
var utf8 = require('is-utf8'); | |
var front = require('front-matter'); | |
var Gaze = require('gaze').Gaze; | |
var chalk = require('chalk'); | |
var request = require('request'); | |
var watching = {}; | |
/** | |
* Metalsmith isn't expsing its file reading method, | |
* so we need to reimplement it here. I hope in the | |
* future metalsmith will provide an interface for this. | |
* | |
* @param {Object} metalsmith a metalsmith instance. | |
* @return {Function} | |
*/ | |
var rebuilder = function ( metalsmith ) { | |
return function(filepath, name){ | |
// metalsmith isn't exposing the `read()` function | |
// reimplement it on our own. | |
fs.readFile(filepath, function(err, buffer){ | |
var files = {}; | |
files[name] = { contents : buffer }; | |
if ( utf8(buffer) ){ | |
var parsed = front(buffer.toString()); | |
files[name] = parsed.attributes; | |
files[name].contents = new Buffer(parsed.body); | |
} | |
// Rerun the plugin-chain only for this one file. | |
metalsmith.ware.run(files, metalsmith, function(err){ | |
if ( err ) { throw err; } | |
// metalsmith deletes the output directory when writing files, so we | |
// need to write the file outselves | |
for( var file in files ) { | |
var data = files[file]; | |
var out = path.join(metalsmith.destination(), file); | |
return fs.writeFile(out, data.contents, function(err) { | |
if ( err ) { throw err; } | |
console.log ( chalk.green( '...rebuild' )); | |
//tell the livereload server which file have changed | |
request.get("http://localhost:35729/changed?files="+file); | |
}); | |
} | |
}); | |
}); | |
}; | |
}; | |
/** | |
* | |
* | |
* | |
* @param {String} source The source directory | |
* @param {String} patterns The relative globing parameter | |
* @param {Function} rebuild metasmith rebuild function | |
* @param {Function} done metalsmith done callback. | |
*/ | |
var startWatching = function ( source, patterns, rebuild, done) { | |
console.log ( chalk.green('Started watching ') + chalk.cyan(patterns)); | |
var gaze = new Gaze(patterns); | |
gaze.on('ready', function(){ | |
done(); | |
}); | |
gaze.on('all', function ( event, filepath ) { | |
var name = relative(source, filepath); | |
fs.lstat(filepath, function(err, stats){ | |
// Ignore errors and directorys | |
if ( err || stats.isDirectory() === true ) { return; } | |
console.log ( chalk.cyan( name ) + ' was ' + chalk.green( event ) ); | |
// rebuild the current file `filepath` | |
// using the metalsmith rebuilder. | |
rebuild(filepath, name); | |
}); | |
}); | |
}; | |
/** | |
* Metalsmith watch plugin. | |
* This function is bind to an option object to allow | |
* it do have different options. | |
*/ | |
var watch = function ( files, metalsmith, done ) { | |
/*jshint validthis:true */ | |
var source = metalsmith.source(); | |
var globbingSrc = source + '/' + this.pattern; | |
if ( watching[globbingSrc] === undefined ) { | |
watching[globbingSrc] = true; | |
startWatching (source, relative(metalsmith.dir, globbingSrc), rebuilder(metalsmith), done); | |
} else { | |
done(); | |
} | |
}; | |
// Default pattern | |
var defaults = { | |
pattern : '**/*' | |
}; | |
// Expose | |
module.exports = function ( pattern ) { | |
if ( arguments.length === 3){ | |
// direct usage like `.use(watch)` | |
watch.apply(defaults, [].slice.call(arguments)); | |
} else { | |
// usage with pattern like `.use(watch('**'))` | |
var options = {}; | |
if ( !!pattern ) { | |
options.pattern = pattern; | |
} else { | |
options.pattern = defaults.pattern; | |
} | |
return watch.bind(options); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hey, great work with the patched watcher (You should do a pull request). I'll try it this week with my Metalsmith template. Thanks.