## What is context? Context is an object that is created in-memory for rendering templates. Context is made up of other data objects that are created and modified throughout the render cycle. Below we'll discuss [which data objects](#what-objects-are-used-to-create-the-context) are used, where they come from and the [order in which they're merged](#how-are-the-objects-merged). We're also going to learn how to [customize the context object](#customizing-context) and how to use the context in your own [custom helpers](#context-and-helpers). This repository also contains [examples](./examples) that may be run from the command line with [assemble][]. [See below](#examples) for more information on installing and running the examples. --- ## What objects are used to create the context? - `app.cache.data` (from `app.data()`) * main data object that is useful for "global" data. * usually includes properties like `site` (this is controlled by the user) - `view.locals` * individual view "local" data * overrides `app.cache.data` at the individual view level * added through middleware or when creating a view with `views.addView()` - `view.data` (front-matter) * individual view data object * overrides `app.cache.data` and `view.locals` * may be specified as view "front-matter" that is parsed in `onLoad` middleware * usually includes properties like `title` and `layout` to override "global" data at the view (page) level - `render` locals * local data object specified when calling the `.render()` method. * useful for specifying data that may not exist on `view.locals` or `view.data` - `helper` locals * local data object specified when calling a view helper in another template * works with the built-in "singular" view helper (e.g. `\{{partial "foo" locals}}`) * will override all other data. --- ## How are the objects merged? There is a default order of operations when it comes to merging the data context. The order is [customizable](#customizing-context) by the user. - `app.cache.data` - `view.locals` - `render.locals` - `view.data` - `helper-locals` The context is created by merging the objects in the specified order through the various methods discribed in [Customizing context](#customizing-context): ```js // merges the view context first // e.g.: `merge(view.locals, locals, view.data)` var context = view.context(locals); // merges the `app.cache.data` context = merge({}, app.cache.data, context); ``` In addition to the main context, helpers may use the `this.ctx()` method to merge in helper locals that are passed. The built-in singular helpers like `\{{partial}}` use this method to ensure helper locals are used. ```handlebars \{{partial "button" locals}} ``` This will result in the `locals` object being merged onto the context when rendering the "button" partial. The default behaviour for merging the helper context is: ```js // merge the current "view" front-matter with current context built above context = merge({}, context, page.data); // merge in the partial locals and front-matter context = merge({}, context, button.locals, button.data); // merge in helper locals and options.hash context = merge({}, context, locals, options.hash); ``` --- ## Customizing context Customize how the context object is created. - `view.context` * method that takes optional `locals` object * merges data by doing `return merge(view.locals, locals, view.data)` * may override directly to change the behaviour - `app.context` * method that takes `view` and optional `locals` object * calls the `view.context` before merging data * merges data by doing `return merge({}, this.cache.data, view.context(locals))` - `options.context`: Customize how the context object is created. * may override functionality through the `context` option: ```js app.option('context', function(view, locals) { // this is the app return merge({}, this.cache.data, view.context(), locals); }); ``` - `options.helperContext`: Custom how the helper context is created. * may override the functionality used in the `this.ctx()` method in helpers through the `helperContext` option: ```js app.option('helperContext', function(view, locals, options) { return merge({}, view.context(), locals); }); ``` ## Examples {%= docs('examples.md') %}