whole_func_string: 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;
    }
func_code_string: 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;
    }
func_documentation_string: Load Layout
  @param  {[type]}   src      [description]
  @param  {[type]}   assemble [description]
  @param  {Function} callback [description]
  @return {[type]}            [description]