function(src, assemble, callback) {

    var layoutStack = [];
    var layoutName = 'layout';
    var defaultLayout = assemble.engine.startDelimiter + ' body ' + assemble.engine.endDelimiter; // '{{> body }}';

    var layoutext = assemble.options.layoutext || '';
    var layout = '';
    var layoutdir = assemble.options.layoutdir || assemble.options.layouts || '';

    var load = function(src) {

      var loadFile = true;

      // if the src is empty, create a default layout in memory
      if (!src || src === false || src === '' || src.length === 0 || src === 'none') {
        loadFile = false;
        layout = defaultLayout; // '{{>body}}';
      }

      var layoutPath = src + layoutext;

      if (loadFile) {
        grunt.verbose.writeln(src);
        // Check if we should use the files resolved with glob
        if (assemble.layoutFiles) {
          var matchedLayout = assemble.layoutFiles.filter(function findLayout(layout) {
            return path.basename(layout) === layoutPath;
          })[0];
          layout = matchedLayout ? path.normalize(matchedLayout) : layoutPath;
        } else {
          // If layouts or layoutdir was not a valid glob pattern, validate that the layout file exists if we assume
          // layouts or layoutdir to be a directory path
          layout = path.normalize(path.join(layoutdir, layoutPath));
        }
        grunt.verbose.writeln(layout);

        if (!fs.existsSync(layout)) {
          var err = 'Layout file (' + layout + ') not found.';
          grunt.warn(err);
          if (callback) {
            callback({message: err}, null);
          }
          return false;
        }

        // load layout
        layoutName = path.basename(layout, path.extname(layout));

        layout = grunt.file.read(layout);
        layout = layout.replace(/\{{>\s*body\s*}}/, function() { return defaultLayout; });
      }

      var parsedLayout = matter(layout, assemble.options.matter);
      var layoutData = parsedLayout.data;

      var results = {
        layoutName: layoutName,
        layout: parsedLayout.content,
        data: layoutData
      };

      layoutStack.push(results);

      if (layoutData && (layoutData.layout || layoutData.layout === false || layoutData.layout === 'none')) {
        load(layoutData.layout);
      }
    };

    load(src);

    var layoutInfo;
    var finalResults = {
      layoutName: '',
      layout: defaultLayout, // '{{>body}}',
      data: {}
    };

    // eslint-disable-next-line
    while (layoutInfo = layoutStack.pop()) {
      finalResults.layout = injectBody(finalResults.layout, layoutInfo.layout);
      finalResults.data = _.extend({}, finalResults.data, layoutInfo.data);
      finalResults.layoutName = layoutInfo.layoutName;
    }

    if (callback) {
      callback(null, finalResults);
    }
    return finalResults;
  }
function(src, assemble, callback) {

    var layoutStack = [];
    var layoutName = 'layout';
    var defaultLayout = assemble.engine.startDelimiter + ' body ' + assemble.engine.endDelimiter; 

    var layoutext = assemble.options.layoutext || '';
    var layout = '';
    var layoutdir = assemble.options.layoutdir || assemble.options.layouts || '';

    var load = function(src) {

      var loadFile = true;

      
      if (!src || src === false || src === '' || src.length === 0 || src === 'none') {
        loadFile = false;
        layout = defaultLayout; 
      }

      var layoutPath = src + layoutext;

      if (loadFile) {
        grunt.verbose.writeln(src);
        
        if (assemble.layoutFiles) {
          var matchedLayout = assemble.layoutFiles.filter(function findLayout(layout) {
            return path.basename(layout) === layoutPath;
          })[0];
          layout = matchedLayout ? path.normalize(matchedLayout) : layoutPath;
        } else {
          
          
          layout = path.normalize(path.join(layoutdir, layoutPath));
        }
        grunt.verbose.writeln(layout);

        if (!fs.existsSync(layout)) {
          var err = 'Layout file (' + layout + ') not found.';
          grunt.warn(err);
          if (callback) {
            callback({message: err}, null);
          }
          return false;
        }

        
        layoutName = path.basename(layout, path.extname(layout));

        layout = grunt.file.read(layout);
        layout = layout.replace(/\{{>\s*body\s*}}/, function() { return defaultLayout; });
      }

      var parsedLayout = matter(layout, assemble.options.matter);
      var layoutData = parsedLayout.data;

      var results = {
        layoutName: layoutName,
        layout: parsedLayout.content,
        data: layoutData
      };

      layoutStack.push(results);

      if (layoutData && (layoutData.layout || layoutData.layout === false || layoutData.layout === 'none')) {
        load(layoutData.layout);
      }
    };

    load(src);

    var layoutInfo;
    var finalResults = {
      layoutName: '',
      layout: defaultLayout, 
      data: {}
    };

    
    while (layoutInfo = layoutStack.pop()) {
      finalResults.layout = injectBody(finalResults.layout, layoutInfo.layout);
      finalResults.data = _.extend({}, finalResults.data, layoutInfo.data);
      finalResults.layoutName = layoutInfo.layoutName;
    }

    if (callback) {
      callback(null, finalResults);
    }
    return finalResults;
  }
function ( src , assemble , callback ) { var layoutStack = [ ] ; var layoutName = 'layout' ; var defaultLayout = assemble . engine . startDelimiter + ' body ' + assemble . engine . endDelimiter ; // '{{> body }}'; var layoutext = assemble . options . layoutext || '' ; var layout = '' ; var layoutdir = assemble . options . layoutdir || assemble . options . layouts || '' ; var load = function ( src ) { var loadFile = true ; // if the src is empty, create a default layout in memory if ( ! src || src === false || src === '' || src . length === 0 || src === 'none' ) { loadFile = false ; layout = defaultLayout ; // '{{>body}}'; } var layoutPath = src + layoutext ; if ( loadFile ) { grunt . verbose . writeln ( src ) ; // Check if we should use the files resolved with glob if ( assemble . layoutFiles ) { var matchedLayout = assemble . layoutFiles . filter ( function findLayout ( layout ) { return path . basename ( layout ) === layoutPath ; } ) [ 0 ] ; layout = matchedLayout ? path . normalize ( matchedLayout ) : layoutPath ; } else { // If layouts or layoutdir was not a valid glob pattern, validate that the layout file exists if we assume // layouts or layoutdir to be a directory path layout = path . normalize ( path . join ( layoutdir , layoutPath ) ) ; } grunt . verbose . writeln ( layout ) ; if ( ! fs . existsSync ( layout ) ) { var err = 'Layout file (' + layout + ') not found.' ; grunt . warn ( err ) ; if ( callback ) { callback ( { message : err } , null ) ; } return false ; } // load layout layoutName = path . basename ( layout , path . extname ( layout ) ) ; layout = grunt . file . read ( layout ) ; layout = layout . replace ( / \{{>\s*body\s*}} / , function ( ) { return defaultLayout ; } ) ; } var parsedLayout = matter ( layout , assemble . options . matter ) ; var layoutData = parsedLayout . data ; var results = { layoutName : layoutName , layout : parsedLayout . content , data : layoutData } ; layoutStack . push ( results ) ; if ( layoutData && ( layoutData . layout || layoutData . layout === false || layoutData . layout === 'none' ) ) { load ( layoutData . layout ) ; } } ; load ( src ) ; var layoutInfo ; var finalResults = { layoutName : '' , layout : defaultLayout , // '{{>body}}', data : { } } ; // eslint-disable-next-line while ( layoutInfo = layoutStack . pop ( ) ) { finalResults . layout = injectBody ( finalResults . layout , layoutInfo . layout ) ; finalResults . data = _ . extend ( { } , finalResults . data , layoutInfo . data ) ; finalResults . layoutName = layoutInfo . layoutName ; } if ( callback ) { callback ( null , finalResults ) ; } return finalResults ; }
Load Layout
@param  {[type]}   src      [description]
@param  {[type]}   assemble [description]
@param  {Function} callback [description]
@return {[type]}            [description]
Load Layout