From ae9c295ce15849f8a5eba66a6eea91d2f86ada28 Mon Sep 17 00:00:00 2001 From: devlinjd Date: Wed, 16 Dec 2015 20:13:27 -0500 Subject: [PATCH] Better Handlebars support. --- package.json | 2 +- src/core/theme.js | 17 ++++++++--- src/eng/handlebars-generator.js | 50 +++++++++++++++++++++++++++++++-- src/eng/underscore-generator.js | 2 +- src/gen/template-generator.js | 6 ++-- 5 files changed, 66 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 99afcc2..c41b1d3 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "dependencies": { "fresca": "~0.2.1", "colors": "^1.1.2", - "fluent-themes": "~0.6.1-beta", + "fluent-themes": "~0.6.2-beta", "fs-extra": "^0.24.0", "handlebars": "^4.0.5", "html": "0.0.10", diff --git a/src/core/theme.js b/src/core/theme.js index 3d971a0..cbdc548 100644 --- a/src/core/theme.js +++ b/src/core/theme.js @@ -99,9 +99,18 @@ Abstract theme representation. var outFmt = '', isMajor = false; var portion = pathInfo.dir.replace(tplFolder,''); if( portion && portion.trim() ) { - var reg = /^(?:\/|\\)(html|latex|doc|pdf)(?:\/|\\)?/ig; + var reg = /^(?:\/|\\)(html|latex|doc|pdf|partials)(?:\/|\\)?/ig; var res = reg.exec( portion ); - res && (outFmt = res[1]); + if( res ) { + if( res[1] !== 'partials' ) { + outFmt = res[1]; + } + else { + that.partials = that.partials || []; + that.partials.push( { name: pathInfo.name, path: absPath } ); + return null; + } + } } // Otherwise, the output format is inferred from the filename, as in @@ -138,7 +147,7 @@ Abstract theme representation. }); // Now, get all the CSS files... - (this.cssFiles = fmts.filter(function( fmt ){ return fmt.ext === 'css'; })) + (this.cssFiles = fmts.filter(function( fmt ){ return fmt && (fmt.ext === 'css'); })) .forEach(function( cssf ) { // For each CSS file, get its corresponding HTML file var idx = _.findIndex(fmts, function( fmt ) { @@ -151,7 +160,7 @@ Abstract theme representation. // Remove CSS files from the formats array fmts = fmts.filter( function( fmt) { - return fmt.ext !== 'css'; + return fmt && (fmt.ext !== 'css'); }); return formatsHash; diff --git a/src/eng/handlebars-generator.js b/src/eng/handlebars-generator.js index 4d04a2a..fba7bd0 100644 --- a/src/eng/handlebars-generator.js +++ b/src/eng/handlebars-generator.js @@ -7,11 +7,57 @@ Handlebars template generate for FluentCV. var _ = require('underscore'); var HANDLEBARS = require('handlebars'); + var FS = require('fs'); + var moment = require('moment'); - module.exports = function( json, jst, format, cssInfo, opts ) { + module.exports = function( json, jst, format, cssInfo, opts, theme ) { + + _.each( theme.partials, function( el ) { + var tplData = FS.readFileSync( el.path, 'utf8' ); + var compiledTemplate = HANDLEBARS.compile( tplData ); + HANDLEBARS.registerPartial( el.name, compiledTemplate ); + }); + + HANDLEBARS.registerHelper("formatDate", function(datetime, format) { + if( moment ) { + return moment( datetime ).format( format ); + } + else { + return datetime; + } + }); + + // http://doginthehat.com.au/2012/02/comparison-block-helper-for-handlebars-templates/ + HANDLEBARS.registerHelper('compare', function(lvalue, rvalue, options) { + + if (arguments.length < 3) + throw new Error("Handlerbars Helper 'compare' needs 2 parameters"); + + var operator = options.hash.operator || "=="; + var operators = { + '==': function(l,r) { return l == r; }, + '===': function(l,r) { return l === r; }, + '!=': function(l,r) { return l != r; }, + '<': function(l,r) { return l < r; }, + '>': function(l,r) { return l > r; }, + '<=': function(l,r) { return l <= r; }, + '>=': function(l,r) { return l >= r; }, + 'typeof': function(l,r) { return typeof l == r; } + }; + + if (!operators[operator]) + throw new Error("Handlerbars Helper 'compare' doesn't know the operator "+operator); + var result = operators[operator](lvalue,rvalue); + return result ? options.fn(this) : options.inverse(this); + }); var template = HANDLEBARS.compile(jst); - return template( { r: json, filt: opts.filters, cssInfo: cssInfo, headFragment: opts.headFragment || '' } ); + return template({ + r: json, + filt: opts.filters, + cssInfo: cssInfo, + headFragment: opts.headFragment || '' + }); }; diff --git a/src/eng/underscore-generator.js b/src/eng/underscore-generator.js index 54be147..341021c 100644 --- a/src/eng/underscore-generator.js +++ b/src/eng/underscore-generator.js @@ -7,7 +7,7 @@ Underscore template generate for FluentCV. var _ = require('underscore'); - module.exports = function( json, jst, format, cssInfo, opts ) { + module.exports = function( json, jst, format, cssInfo, opts, theme ) { // Tweak underscore's default template delimeters var delims = (opts.themeObj && opts.themeObj.delimeters) || opts.template; diff --git a/src/gen/template-generator.js b/src/gen/template-generator.js index 8c9696c..26859b4 100644 --- a/src/gen/template-generator.js +++ b/src/gen/template-generator.js @@ -139,11 +139,11 @@ Template-based resume generator base for FluentCV. @param cssInfo Needs to be refactored. @param opts Options and passthrough data. */ - single: function( json, jst, format, cssInfo, opts ) { + single: function( json, jst, format, cssInfo, opts, theme ) { this.opts.freezeBreaks && ( jst = freeze(jst) ); var eng = require( '../eng/' + ((opts.themeObj && opts.themeObj.engine) || opts.engine) + '-generator' ); - var result = eng( json, jst, format, cssInfo, opts ); + var result = eng( json, jst, format, cssInfo, opts, theme ); this.opts.freezeBreaks && ( result = unfreeze(result) ); return result; } @@ -193,7 +193,7 @@ Template-based resume generator base for FluentCV. */ function transform( rez, f, tplInfo, theme, outFolder ) { var cssInfo = { file: tplInfo.css ? tplInfo.cssPath : null, data: tplInfo.css || null }; - var mk = this.single( rez, tplInfo.data, this.format, cssInfo, this.opts ); + var mk = this.single( rez, tplInfo.data, this.format, cssInfo, this.opts, theme ); this.onBeforeSave && (mk = this.onBeforeSave( { mk: mk, theme: theme, outputFile: f } )); var thisFilePath = PATH.join( outFolder, tplInfo.orgPath ); try {