diff --git a/index.js b/index.js
index de1208f..aeb535b 100644
--- a/index.js
+++ b/index.js
@@ -6,6 +6,7 @@ var path = require('path')
module.exports.geddyPath = geddyPath;
module.exports.template = require('./lib/template');
module.exports.jake = require('./lib/jake');
+module.exports.bower = require('./lib/bower');
/**
* Checks if a command line flag is set
diff --git a/lib/bower.js b/lib/bower.js
new file mode 100644
index 0000000..34372bc
--- /dev/null
+++ b/lib/bower.js
@@ -0,0 +1,27 @@
+var exec = require('child_process').exec;
+
+/**
+ * Installs bower components
+ * @param deps {Array}
+ * @param cb {Function(error)} - Called when all components installed
+ */
+function install(deps, cb)
+{
+ var p = exec('bower install ' + deps.join(' ') + ' --save', cb);
+ p.stdout.pipe(process.stdout);
+ p.stderr.pipe(process.stderr);
+}
+module.exports.install = install;
+
+/**
+ * Uninstalls bower components
+ * @param deps {Array}
+ * @param cb {Function(error)} - Called when all components uninstalled
+ */
+function uninstall(deps, cb)
+{
+ var p = exec('bower uninstall ' + deps.join(' ') + ' --save', cb);
+ p.stdout.pipe(process.stdout);
+ p.stderr.pipe(process.stderr);
+}
+module.exports.uninstall = uninstall;
\ No newline at end of file
diff --git a/lib/template.js b/lib/template.js
index 874bdcf..8732ed8 100644
--- a/lib/template.js
+++ b/lib/template.js
@@ -41,7 +41,32 @@ function write(src, dest, data, transform) {
, supported = ['.ejs', '.jade', '.ms', '.swig', '.hbs'];
if (!extToEngine[ext]) {
- fail('Unsuported template engine. Try one of these instead: ' + supported.join(', '));
+ throw new Error('Unsuported template engine. Try one of these instead: ' + supported.join(', '));
+ return;
+ }
+
+ // Write file
+ fs.writeFileSync(dest, render(src, getEngineFromExt(ext), data, transform), 'utf8');
+
+ console.log('[Added] ' + dest);
+}
+module.exports.write = write;
+
+/**
+ * Renders a template file
+ *
+ * @param src {String}
+ * @param engine {String} - Template engine
+ * @param data {Object}
+ * @param transform {Function(content, data)} - (optional) if set this function can transform the rendered template before it gets written to the file
+ * @returns {String}
+ */
+function render(src, engine, data, transform)
+{
+ var supported = Object.keys(engineToExt);
+
+ if (!engineToExt[engine]) {
+ throw new Error('Unsuported template engine. Try one of these instead: ' + supported.join(' '));
return;
}
@@ -50,28 +75,178 @@ function write(src, dest, data, transform) {
, templContent;
// render with the correct adapter
- adapter = new Adapter({engine: getEngineFromExt(ext), template: text});
+ adapter = new Adapter({engine: engine, template: text});
templContent = adapter.render(data);
if (typeof transform === 'function') {
templContent = transform(templContent, data);
}
- // Write file
- fs.writeFileSync(dest, templContent, 'utf8');
-
- console.log('[Added] ' + dest);
+ return templContent;
}
-module.exports.write = write;
+module.exports.render = render;
+/**
+ * Returns template engine for a file extension
+ * @param ext {String}
+ * @returns {String}
+ */
function getEngineFromExt(ext)
{
return extToEngine[ext] || defaultEngine;
}
module.exports.getEngineFromExt = getEngineFromExt;
+/**
+ * Returns file extension for a template engine
+ * @param engine {String}
+ * @returns {String}
+ */
function getExtFromEngine(engine)
{
return engineToExt[engine] || defaultExt;
}
-module.exports.getExtFromEngine = getExtFromEngine;
\ No newline at end of file
+module.exports.getExtFromEngine = getExtFromEngine;
+
+/**
+ * Returns an engine specific script include
+ * @param src {String}
+ * @param engine {String}
+ * @returns {string}
+ */
+function script(src, engine) {
+ switch(engine) {
+ case 'ejs':
+ return "<@- scriptLink('" + src + "', {type:'text/javascript'}) @>";
+ break;
+ case 'jade':
+ return "!= scriptLink('" + src + "', {type:'text/javascript'})";
+ break;
+ case 'swig':
+ return "{{ scriptLink('" + src + "', {type:'text/javascript'}) }}";
+ break;
+ case 'handlebars':
+ case 'mustache':
+ default:
+ return '';
+ }
+}
+module.exports.script = script;
+
+/**
+ * Returns an engine specific stylesheet include
+ * @param src {String}
+ * @param engine {String}
+ * @returns {string}
+ */
+function stylesheet(src, engine) {
+ switch(engine) {
+ case 'ejs':
+ return "<@- styleLink('" + src + "', {rel:'stylesheet'}) @>";
+ break;
+ case 'jade':
+ return "!= styleLink('" + src + "', {rel:'stylesheet'})";
+ break;
+ case 'swig':
+ return "{{ styleLink('" + src + "', {rel:'stylesheet'}) }}";
+ break;
+ case 'handlebars':
+ case 'mustache':
+ default:
+ return '';
+ }
+}
+module.exports.stylesheet = stylesheet;
+
+/**
+ * Returns an engine specific partial include
+ * @param src {String}
+ * @param data {String} - (optional)
+ * @param engine {String}
+ * @returns {string}
+ */
+function partial(/*src, [data], engine*/) {
+ var args = Array.prototype.slice.call(arguments);
+ var src = args.shift();
+ var engine = args.pop();
+ var data = args.pop() || null;
+ if (data) {
+ data = ', ' + data;
+ }
+ else data = '';
+
+ switch(engine) {
+ case 'ejs':
+ return "<@- partial('" + src + "'" + data + ") @>";
+ break;
+ case 'jade':
+ return "!= partial('" + src + "'" + data + ")";
+ break;
+ case 'swig':
+ return "{{ partial('" + src + "'" + data + ") }}";
+ break;
+ case 'handlebars':
+ case 'mustache':
+ return "{{{partial('" + src + "'" + data + ")}}}";
+ break;
+ default:
+ return "";
+ }
+}
+module.exports.partial = partial;
+
+/**
+ * Returns engine specific unescaped content
+ * @param content {String}
+ * @param engine {String}
+ * @returns {String}
+ */
+function unescaped(content, engine)
+{
+ switch(engine) {
+ case 'ejs':
+ return "<@- " + content + " @>";
+ break;
+ case 'jade':
+ return "!= " + content;
+ break;
+ case 'swig':
+ return "{{ " + content + " }}";
+ break;
+ case 'handlebars':
+ case 'mustache':
+ return "{{{" + content + "}}}";
+ break;
+ default:
+ return '';
+ }
+}
+module.exports.unescaped = unescaped;
+
+/**
+ * Returns engine specific escaped content
+ * @param content {String}
+ * @param engine {String}
+ * @returns {String}
+ */
+function escaped(content, engine)
+{
+ switch(engine) {
+ case 'ejs':
+ return "<@= " + content + " @>";
+ break;
+ case 'jade':
+ return "!= " + content;
+ break;
+ case 'swig':
+ return "{{ " + content + " }}";
+ break;
+ case 'handlebars':
+ case 'mustache':
+ return "{{{" + content + "}}}";
+ break;
+ default:
+ return '';
+ }
+}
+module.exports.escaped = escaped;
\ No newline at end of file