"use strict"; var mkdirp = require('mkdirp'), rimraf = require('rimraf'), winston = require('winston'), async = require('async'), path = require('path'), fs = require('fs'), nconf = require('nconf'), emitter = require('../emitter'), plugins = require('../plugins'), utils = require('../../public/src/utils'), Templates = {}, searchIndex = {}; Templates.compile = function(callback) { callback = callback || function() {}; var fromFile = nconf.get('from-file') || ''; if (nconf.get('isPrimary') === 'false' || fromFile.match('tpl')) { if (fromFile.match('tpl')) { winston.info('[minifier] Compiling templates skipped'); } emitter.emit('templates:compiled'); return callback(); } compile(callback); }; function getBaseTemplates(theme) { var baseTemplatesPaths = [], baseThemePath, baseThemeConfig; while (theme) { baseThemePath = path.join(nconf.get('themes_path'), theme); baseThemeConfig = require(path.join(baseThemePath, 'theme.json')); baseTemplatesPaths.push(path.join(baseThemePath, baseThemeConfig.templates || 'templates')); theme = baseThemeConfig.baseTheme; } return baseTemplatesPaths.reverse(); } function compile(callback) { var coreTemplatesPath = nconf.get('core_templates_path'), themeConfig = require(nconf.get('theme_config')), baseTemplatesPaths = themeConfig.baseTheme ? getBaseTemplates(themeConfig.baseTheme) : [nconf.get('base_templates_path')], viewsPath = nconf.get('views_dir'); plugins.getTemplates(function(err, pluginTemplates) { if (err) { return callback(err); } winston.verbose('[meta/templates] Compiling templates'); rimraf.sync(viewsPath); mkdirp.sync(viewsPath); async.parallel({ coreTpls: function(next) { utils.walk(coreTemplatesPath, next); }, baseThemes: function(next) { async.map(baseTemplatesPaths, function(baseTemplatePath, next) { utils.walk(baseTemplatePath, function(err, paths) { paths = paths.map(function(tpl) { return { base: baseTemplatePath, path: tpl.replace(baseTemplatePath, '') }; }); next(err, paths); }); }, next); } }, function(err, data) { var baseThemes = data.baseThemes, coreTpls = data.coreTpls, paths = {}; coreTpls.forEach(function(el, i) { paths[coreTpls[i].replace(coreTemplatesPath, '')] = path.join(coreTemplatesPath, coreTpls[i]); }); baseThemes.forEach(function(baseTpls) { baseTpls.forEach(function(el, i) { paths[baseTpls[i].path] = path.join(baseTpls[i].base, baseTpls[i].path); }); }); for (var tpl in pluginTemplates) { if (pluginTemplates.hasOwnProperty(tpl)) { paths[tpl] = pluginTemplates[tpl]; } } async.each(Object.keys(paths), function(relativePath, next) { var file = fs.readFileSync(paths[relativePath]).toString(), matches = null, regex = /[ \t]*[ \t]*/; while((matches = file.match(regex)) !== null) { var partial = "/" + matches[1]; if (paths[partial] && relativePath !== partial) { file = file.replace(regex, fs.readFileSync(paths[partial]).toString()); } else { winston.warn('[meta/templates] Partial not loaded: ' + matches[1]); file = file.replace(regex, ""); } } if (relativePath.match(/^\/admin\/[\s\S]*?/)) { addIndex(relativePath, file); } mkdirp.sync(path.join(viewsPath, relativePath.split('/').slice(0, -1).join('/'))); fs.writeFile(path.join(viewsPath, relativePath), file, next); }, function(err) { if (err) { winston.error('[meta/templates] ' + err.stack); return callback(err); } compileIndex(viewsPath, function() { winston.verbose('[meta/templates] Successfully compiled templates.'); emitter.emit('templates:compiled'); if (process.send) { process.send({ action: 'templates:compiled' }); } callback(); }); }); }); }); } function addIndex(path, file) { searchIndex[path] = file; } function compileIndex(viewsPath, callback) { fs.writeFile(path.join(viewsPath, '/indexed.json'), JSON.stringify(searchIndex), callback); } module.exports = Templates;