docs: function(locals, fn) {
      if (typeof locals === 'function') {
        fn = locals;
        locals = {};
      }
  
      var res = this.locals;
      var data = this.app.cache.data;
      this.ctx('global', data);
  
      // extend context with same-named data-property from `app.cache.data`
      if (!this.hint('extended')) {
        this.hint('extended', true);
        var name = this.collection.renameKey(this.path);
        this.ctx('matched', data[name]);
      }
  
      this.ctx('data', this.data);
      this.ctx('options', this.options);
  
      // build up the array of context keys to calculate
      var keys = ['global', 'compile', 'render', 'options', 'matched'];
      if (this.pickOption('prefer locals') === true) {
        keys = keys.concat(['data', 'locals']);
      } else {
        keys = keys.concat(['locals', 'data']);
      }
      keys = keys.concat(['helper', 'custom']);
  
      function calculate(obj, contexts, props) {
        var len = props.length, i = -1;
        while (++i < len) {
          var key = props[i];
          lazy.extend(obj, contexts[key] || {});
        }
      }
  
      fn = fn || this.pickOption('context');
      if (typeof fn === 'function') {
        fn.call(this, res, this.contexts, keys, calculate);
      } else {
        calculate(res, this.contexts, keys);
      }
  
      locals = locals || {};
      lazy.extend(res, this.app.mergePartials(locals));
      lazy.extend(res, locals);
      return res;
    }