lib/mod-render.js
function renderModule(context, options) {
	var  cacheKey
		,modSourceTemplate
		,mergedData
		,html
	;

	// this check is used when rendering isolated modules or views for development and testing (in the default layout!).
	// skip any modules that are not THE module or THE view.
	// view: skip all modules that have the attribute _isLayout="true"
	// module: skip all other modules
	if (
		context.skipModules === true ||                         // case: module
		context.skipModules == 'layout' && options._isLayout    // case: view
		)
	{ return ''; }

	options.template = options.template || options.name;
	options.tag = options.tag || defaults.tag;
	options.data = options.data || {};
	options.data.moduleNestingLevel = typeof context.moduleNestingLevel === 'undefined' ? 0 : context.moduleNestingLevel + 1;
	autoIncrementIndent = options.data.moduleNestingLevel > 0 ? 1 : false;
	options.data.indent = options.indent || autoIncrementIndent || context.indent || 0;

	// merge the request context and data in the module include, with the latter trumping the former.
	mergedData = _.merge({}, context, options.data);

	// create a unique identifier for the module/template combination
	cacheKey = options.name + ' ' + options.template;

	// If addTest exists it means we should pass module options into it for later client-side module testing.
	context._locals && context._locals.addTest && context._locals.addTest(options);

	// force reading from disk in development mode
	NODE_ENV == 'development' && (cache[cacheKey] = null);

	// if the module/template combination is cached use it, else read from disk and cache it.
	modSourceTemplate = cache[cacheKey] || (cache[cacheKey] = getModTemplate(options));

	// render the module source in the locally merged context
	// moduleSrc is a {{variable}} in the moduleWrapper template
	try {
		options.moduleSrc = modSourceTemplate.fn(mergedData);
	}
	catch (e) {
		if (process.env.NODE_ENV != 'test') {
			if (e instanceof RenderError)   // if this is our error from a nested template rethrow it.
				throw e;
			else                            // if this is the original Handlebars error, make it useful
				throw new RenderError('Module: ' + options.name + ', Template: ' + options.template + cfg.templateExtension +'\n'+ e.toString().replace(/^Error/, 'Reason'));
		}
	}


	if (options.noWrapper) {
		html = options.moduleSrc;
	}
	else {
		// if we have a persisted read error, add the error class to the module.
		modSourceTemplate.err && (options.classes = options.classes ? options.classes + ' xtc-error' : 'xtc-error');

		if (annotateModules) {
			options._module = modSourceTemplate.name;
			options._file = modSourceTemplate.file;
			options._path = modSourceTemplate.path;
			options._repository = modSourceTemplate.repository;
		}

		// render the wrapper template
		html = wrapperFn(options);
	}

	// manage indentation
	if (mergedData.indent) {
		html = utils.indent(html, mergedData.indent, cfg.indentString);
	}

	return html;
}
function renderModule(context, options) {
	var  cacheKey
		,modSourceTemplate
		,mergedData
		,html
	;

	// this check is used when rendering isolated modules or views for development and testing (in the default layout!).
	// skip any modules that are not THE module or THE view.
	// view: skip all modules that have the attribute _isLayout="true"
	// module: skip all other modules
	if (
		context.skipModules === true ||                         // case: module
		context.skipModules == 'layout' && options._isLayout    // case: view
		)
	{ return ''; }

	options.template = options.template || options.name;
	options.tag = options.tag || defaults.tag;
	options.data = options.data || {};
	options.data.moduleNestingLevel = typeof context.moduleNestingLevel === 'undefined' ? 0 : context.moduleNestingLevel + 1;
	autoIncrementIndent = options.data.moduleNestingLevel > 0 ? 1 : false;
	options.data.indent = options.indent || autoIncrementIndent || context.indent || 0;

	// merge the request context and data in the module include, with the latter trumping the former.
	mergedData = _.merge({}, context, options.data);

	// create a unique identifier for the module/template combination
	cacheKey = options.name + ' ' + options.template;

	// If addTest exists it means we should pass module options into it for later client-side module testing.
	context._locals && context._locals.addTest && context._locals.addTest(options);

	// force reading from disk in development mode
	NODE_ENV == 'development' && (cache[cacheKey] = null);

	// if the module/template combination is cached use it, else read from disk and cache it.
	modSourceTemplate = cache[cacheKey] || (cache[cacheKey] = getModTemplate(options));

	// render the module source in the locally merged context
	// moduleSrc is a {{variable}} in the moduleWrapper template
	try {
		options.moduleSrc = modSourceTemplate.fn(mergedData);
	}
	catch (e) {
		if (process.env.NODE_ENV != 'test') {
			if (e instanceof RenderError)   // if this is our error from a nested template rethrow it.
				throw e;
			else                            // if this is the original Handlebars error, make it useful
				throw new RenderError('Module: ' + options.name + ', Template: ' + options.template + cfg.templateExtension +'\n'+ e.toString().replace(/^Error/, 'Reason'));
		}
	}


	if (options.noWrapper) {
		html = options.moduleSrc;
	}
	else {
		// if we have a persisted read error, add the error class to the module.
		modSourceTemplate.err && (options.classes = options.classes ? options.classes + ' xtc-error' : 'xtc-error');

		if (annotateModules) {
			options._module = modSourceTemplate.name;
			options._file = modSourceTemplate.file;
			options._path = modSourceTemplate.path;
			options._repository = modSourceTemplate.repository;
		}

		// render the wrapper template
		html = wrapperFn(options);
	}

	// manage indentation
	if (mergedData.indent) {
		html = utils.indent(html, mergedData.indent, cfg.indentString);
	}

	return html;
}
function renderModule ( context , options ) { var cacheKey , modSourceTemplate , mergedData , html ; // this check is used when rendering isolated modules or views for development and testing (in the default layout!). // skip any modules that are not THE module or THE view. // view: skip all modules that have the attribute _isLayout="true" // module: skip all other modules if ( context . skipModules === true || // case: module context . skipModules == 'layout' && options . _isLayout // case: view ) { return '' ; } options . template = options . template || options . name ; options . tag = options . tag || defaults . tag ; options . data = options . data || { } ; options . data . moduleNestingLevel = typeof context . moduleNestingLevel === 'undefined' ? 0 : context . moduleNestingLevel + 1 ; autoIncrementIndent = options . data . moduleNestingLevel > 0 ? 1 : false ; options . data . indent = options . indent || autoIncrementIndent || context . indent || 0 ; // merge the request context and data in the module include, with the latter trumping the former. mergedData = _ . merge ( { } , context , options . data ) ; // create a unique identifier for the module/template combination cacheKey = options . name + ' ' + options . template ; // If addTest exists it means we should pass module options into it for later client-side module testing. context . _locals && context . _locals . addTest && context . _locals . addTest ( options ) ; // force reading from disk in development mode NODE_ENV == 'development' && ( cache [ cacheKey ] = null ) ; // if the module/template combination is cached use it, else read from disk and cache it. modSourceTemplate = cache [ cacheKey ] || ( cache [ cacheKey ] = getModTemplate ( options ) ) ; // render the module source in the locally merged context // moduleSrc is a {{variable}} in the moduleWrapper template try { options . moduleSrc = modSourceTemplate . fn ( mergedData ) ; } catch ( e ) { if ( process . env . NODE_ENV != 'test' ) { if ( e instanceof RenderError ) // if this is our error from a nested template rethrow it. throw e ; else // if this is the original Handlebars error, make it useful throw new RenderError ( 'Module: ' + options . name + ', Template: ' + options . template + cfg . templateExtension + '\n' + e . toString ( ) . replace ( / ^Error / , 'Reason' ) ) ; } } if ( options . noWrapper ) { html = options . moduleSrc ; } else { // if we have a persisted read error, add the error class to the module. modSourceTemplate . err && ( options . classes = options . classes ? options . classes + ' xtc-error' : 'xtc-error' ) ; if ( annotateModules ) { options . _module = modSourceTemplate . name ; options . _file = modSourceTemplate . file ; options . _path = modSourceTemplate . path ; options . _repository = modSourceTemplate . repository ; } // render the wrapper template html = wrapperFn ( options ) ; } // manage indentation if ( mergedData . indent ) { html = utils . indent ( html , mergedData . indent , cfg . indentString ) ; } return html ; }
Render a Terrific markup module
@param {Object} context
@param {{name: String}} options
@returns {String} – Module HTML
Render a Terrific markup module