Skip to content

Instantly share code, notes, and snippets.

@doowb
Last active August 29, 2015 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save doowb/a0df5b4c548ff541837d to your computer and use it in GitHub Desktop.
Save doowb/a0df5b4c548ff541837d to your computer and use it in GitHub Desktop.
Assemble context (config, options, data, front matter, pages, partials, layouts, etc...)
var normalize = require('normalize-config');
var plasma = require('plasma');
var _ = require('lodash');
function Assemble (config) {
// normalize the config object
this.config = normalize(config);
// store a reference to the config options on assemble
this.options = this.config.options;
// use plasma to read/normalzie the data
this.data = plasma(this.options.data);
// local context will be set for each page (post, etc...) before rendering.
// This allows heleper the chance to get the current page context at render time.
this.localContext = {}; // maybe figure out a better name for this
// context is a method that combines all the global assemble config (config, options, data) into one for use at the current time
this.context = function () {
// the order here needs to be figured out... I think it's like this
// config
// options
// data
// localContext
// additional arguments
var args = [
this.config,
this.options,
this.data,
this.localContext
];
args = args.concat([].slice(null, arguments));
return _.extend.apply(_, args);
};
}

Context

Context is built at runtime by combining other pieces of data stored in assemble

Config

Config is the entire configuration object that is passed into assemble. This configuration object gets normalized through normalize-config to ensure a common data structure.

Options

Options are a property on the configuration object after normalization. Options are normally used to pass information to 3rd party modules and for customizing assemble middleware and helpers.

Data

Data refers to the data property on options and will be read and normalized through plasma. This gives users the ability to pass in plain old JavaScript objects or glob patterns pointing to data files.

Local Context

Local context will be an object that is set just before calling render. This local context will usually refer to the page front matter and will be merged in last to ensure overwritting less specific contexts. To update local context in middlewares, update the corresponding page.data object. Helpers will be able to use the local context either directly (assemble.localContext) or through getting the global context with the local context extended (assemble.context())

Context

The context() method combines the other data structures into one by using lodash extend. Additional arguments may be passed to context for additional extensions (These would normally come from page or partial front matter).

Updating values

If a helper or middleware needs to update values on the assemble context, it should do so through the base object that is used to build the context. For instance, when needing to update a configuration property, update assemble.config directly. If a middleware needs to update specific page front matter, update it on the page.data object directly so it's merged in properly during render time.

var relative = require('relative');
var _ = require('lodash');
function linkToHelper (assemble) {
var helpers = {};
helpers['link-to'] = function (to, ctx) {
var Handlebars = assemble.Handlebars;
// get the current context and extend it with any optional ctx passed into the helper
var context = assemble.context(ctx);
var pages = assemble.pages;
// find any pages with the `name` property matching the `to` parameter
var filtered = _.filter(pages, {'name', to});
// do some logic to figure out which one it should be if multiple were returned
var page = filtered[0]; // or something else
return new Handlebars.SafeString(relative(context.page.dest, page.dest));
}
return helpers;
}
module.exports = linkToHelper;
@doowb
Copy link
Author

doowb commented May 19, 2014

Thinking about some of these base data objects...

We could always wrap them in some sort of class like Cache that has the get and set methods on them and when doing a get we could get the entire context and run the returned object through expander like:

get = function (namespace) {
  var ctx = assemble.context();
  return expander.get(expander.process(this, ctx), namespace);
};

set = function (namespace, value) {
  return expander.set(this, namespace, value);
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment