Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Few improvements #4

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 26 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
Duster.js - Node script to watch & precompile directory of dustjs templates
==============

Based on the original script by Dan McGrady http://dmix.ca

A simple Node script <a href="#">Duster.js</a> to watch a directory of .dust templates and compile them into .js files which can be included into an HTML file.

Why? The dust.js documentation does not mentioned a clear way to work with dust templates in a purely client-side approach, instead focusing on server-side node.js applications.
Expand All @@ -10,33 +12,41 @@ For my backbone.js app, the only option was to include the dust-full.js file and
So I wrote a script to pre-compile dust.js files whenever they are modified in a folder.

## Install
Download duster.js to your project root folder and install dependencies:
Clone this repository

Run the installation
$ npm install

npm install dustjs-linkedin
npm install watch-tree
Get the growl app from the App Store (*not free) or from here https://bitbucket.org/pmetzger/growl/downloads

Be sure to install growlnotify plugin

## Usage
Create dust.js templates in ./src/dusts/ with the file extension .dust and create ./public/dusts directory where files will be compiled to, then run watcher script:
Create a file named .dusterjs in your home directory and add the input and output paths to it. The file is expected to be in YAML format

$ node duster.js
Example:

You can modify folder paths in the duster.js file
---
input_path: /Users/<username>/src.dust/
output_path: /Users/<username>/dust/

Create dust.js templates in the <input_path> dir with the file extension .dust and create <output_path> directory where files will be compiled to, then run watcher script:

$ node duster.js

## Example:
./src/dusts/tweet.dust
./src/dusts/user.dust
<input_path>/tweet.dust
<input_path>/user.dust

Compiles to:

./public/dusts/tweet.js
./public/dusts/user.js
<output_path>/tweet.js
<output_path>/user.js

Then you include them in the html:
## Changes by Suresh Jayanty

<script src="dust-core-1.0.0.min.js"></script>
<script src="tweet.js"></script>
<script src="user.js"></script>
* Added support for growl notifications

I then use Jammit to concatenate all the JS files before production deployment.
* Added support for settings file

by Dan McGrady http://dmix.ca
* Ignoring .swp files created when some one uses vim to edit the dust files
154 changes: 134 additions & 20 deletions duster.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,146 @@
// duster.js
// Watch directory of dust.js templates and automatically compile them
// by Dan McGrady http://dmix.ca
// slight modifications by Suresh Jayanty
var fs = require('fs'),
dust = require('dustjs-linkedin'),
watch = require('watch'),
yaml = require('js-yaml'),
colors = require('colors'),
childprocess = require('child_process'),
file_options = {
'input_path': './src.dust',
'output_path': './dust'
},
user_settings_file = process.env['HOME'] + '/.dusterjs',
svnRegex = /\.svn/,
swpRegex = /\.swp/,
gitRegex = /\.git/
dustRegex = /\.dust$/;

var input_path = "./dusts"; // directory of dust templates are stored with .dust file extension
var output_path = "./javascripts/dusts/"; // directory where the compiled .js files should be saved to

var fs = require('fs');
var dust = require('dustjs-linkedin');
var watch = require('watch');
function growl(message, sticky) {
var command = '/usr/local/bin/growlnotify -p 1 -m "' + message + '"',
growlnotice;
if (sticky) {
command += ' -s';
}

growlnotice = childprocess.exec(command, function(error, stdout, stderr) {});
growlnotice.on('exit', function(code) {});
}

function compile_dust(path, curr, prev) {
fs.readFile(path, function(err, data) {
if (err) throw err;
if (swpRegex.exec(path)) {
console.log(('Ignoring file: ' + path).red);
return;
}
if (svnRegex.exec(path)) {
console.log(('Ignoring file: ' + path).red);
return;
}
if (gitRegex.exec(path)) {
console.log(('Ignoring file: ' + path).red);
return;
}
fs.readFile(path, function(err, data) {
if (err) {

growl('Error: ' + err + ' : ' + path , true);
throw err;
}

var filename = path.split("/").reverse()[0].replace(".dust", "");
var filepath = file_options.output_path + '/' + filename + ".js";
var compiled = '';
try {
compiled = dust.compile(new String(data), filename);

var filename = path.split("/").reverse()[0].replace(".dust", "");
var filepath = output_path + filename + ".js";
var compiled = dust.compile(new String(data), filename);
fs.writeFile(filepath, compiled, function(err) {
if (err) {
growl('Error: ' + err, true);
throw err;
}
console.log('Saved ' + filepath);
growl('Saved ' + filepath);
});
} catch (err) {
growl('Error: ' + err, true);
}
});
}

function createMonitor() {
try {
watch.createMonitor(file_options.input_path, {
'ignoreDotFiles': true
}, function(monitor) {
console.log("Watching " + file_options.input_path);
monitor.files['*.dust', '*/*'];
monitor.on("created", compile_dust);
monitor.on("changed", compile_dust);
});
} catch (err) {
growl('Error: ' + err, true);
console.log(err);
}
}

fs.writeFile(filepath, compiled, function(err) {
if (err) throw err;
console.log('Saved ' + filepath);
function processCurrentFiles() {
fs.readdir(file_options.input_path, function(err, files) {
if(!err) {
files.forEach(function(filename) {
var dustFile;
if(!dustRegex.exec(filename)) {
return;
}
dustFile = filename.replace('.dust', '') + '.js';
fs.stat(file_options.output_path + '/' + dustFile, function(err, props) {
if(err) {
console.log('file not found: ' + file_options.output_path + '/' + dustFile);
compile_dust(file_options.input_path + '/' + filename);
}
});
});
}
});
});
}

watch.createMonitor(input_path, function (monitor) {
console.log("Watching " + input_path);
monitor.files['*.dust', '*/*'];
monitor.on("created", compile_dust);
monitor.on("changed", compile_dust);
})
function main() {
fs.exists(user_settings_file, function(exists) {
if (exists) {
fs.readFile(user_settings_file, 'utf8', function(err, data) {
if (err) {
return;
}

try {
yaml.loadAll(data, function(doc) {
if (doc.input_path) {
file_options.input_path = doc.input_path;
}
if (doc.output_path) {
file_options.output_path = doc.output_path;
}

growl('Watching ' + file_options.input_path + ' for changes');
growl('Saving compiled templates to ' + file_options.output_path);

processCurrentFiles();
createMonitor();
});
} catch (err) {
growl('Error: ' + err, true);
}
});
} else {
growl('Watching ' + file_options.input_path + ' for changes');
growl('Saving compiled templates to ' + file_options.output_path);

processCurrentFiles();
createMonitor();
}
});
}

main();
13 changes: 13 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "dusterjs",
"description": "Duster.js - Node script to watch & precompile directory of dustjs templates",
"version": "0.0.1",
"main": "duster.js",
"dependencies": {
"dustjs-linkedin": ">= 1.1.0",
"watch": ">= 0.5.1",
"watch-tree": ">= 0.1.1",
"js-yaml": ">= 1.0.2",
"colors": ">= 0.6.0-1"
}
}