Thanks to the YUI responsive grid, our application adapts nicely to changes to size
of the browser window. We’re going to go a step further though and serve different pages
based on the client request. You can configure Mojito to find files based on the request
context and a selector, which is just an identifier that is part of the file name.
This allows you to have multiple templates that can be served based on the client request.
We’re also going to take advantage of Handlebars helpers and partials to simplify our
templates.

We worked on using more sophisticated configuration to have default configurations,
store key-value pairs, and use contexts. In addition to application.json that we’ve
been working with, we introduced defaults.json and definition.json. We also worked
with the Config addon again, this time using the method getDefinition. In short,
we learned the following:

The selector is an arbitrary user-defined string, which is used to select which
version of each resource to use. The selector is defined in the application.json
with the selector property. Because the selector is a global entity, you cannot
define it at the mojit level. For example, you cannot define the selector in the
defaults.json of a mojit.

The value of the selector property is a string that must not have a period (‘.’)
or slash (‘/’) in it. In practice, it’s suggested to use alphanumeric and hyphen (‘-‘)
characters only.

Only one selector can be used in each configuration object identified by the setting
property, which defines the context. The specified selectors must match the selector
found in the resource file names. So, for example, the template views/index.iphone.hb.html
has the selector iphone.

You can also have controllers that use a selector. For example, your application could
have all of the following controllers:

Mojito can examine the HTTP header User Agent and detect the following devices/browsers.
The example templates would be based on selectors defined for each context. For our application,
we’re only going to be creating templates for the iPhone, iPad, and Android devices in
addition to index.hb.html.

Handlebars helpers in Mojito applications are defined and registered in the
controller. You define a Handlebars helper as a function outside the controller
namespace in the controller. Thus, the function toLinkHelper
shown below can be registered as a helper to create links.

After you have defined the function that will serve as your Handlebars helper, you
register it with the Helpers addon. The Helpers addon has several methods for
getting helpers, setting mojit-level helpers, or exposing helpers so that they can shared
with other mojits.

As we’ve seen with other addons, you need to require the Helpers addon by adding
the string 'mojito-helpers-addon' in the requires array of your controller.
You also access the addon and its methods through the ActionContext object.

The Helpers addon has the following three methods:

expose - Exposes a parent mojit’s helper function so that on the server
side any child mojit instance under a particular request can use the helper.
On the client, any child mojit instance on the page can use the helper.

get - Allows you to get a specify helper (if given an argument) or all
the helpers if not given any arguments.

set - Sets a helper function for a mojit instance. Other mojit instances
will not have access to this helper function.

You can expose a helper for use with a mojit instance or make it available to all
mojits. To register the helper toLinkHelper that
we defined earlier for the use of this mojit, you use ac.helpers.set as shown here:

To register a helper so that parent mojits can share them with their children, you
use the expose method of the Helpers addon. In the example controller below, the
expose method registers the helper toLinkHelper that creates links. In most cases,
you would want this helper to be available to other mojits.

After you define your handler and then register it with the Helpers addon, you can
use the handler in your template. In the template index.hb.html below, the
Handlebars block helper each iterates through the objects contained in the array
yui.modules, and then the custom helper toLink creates links with the values
of the properties title and user_guide:

Handlebars partials are simply templates using Handlebars expressions that other
templates can include. Mojito allows you to have both global (shared by all mojits)
or local (available only to one mojit) partials depending on the context. Global
and local partials are used the same way in templates, but the location of the
partials is different. Data that is available to templates is also available to
partials.

Now let’s look at the file naming convention, location, and usage of partials
before finishing up with a simple example.

After you have copied the application that you made in the
last module (see Setting Up), change into the application
09_hb_templates.

Let’s add the contexts with the selectors to application.json that will identify the templates
for devices such as the iPad and iPhone. Because of the new configuration objects,
Mojito will look for the template index.iphone.hb.html when a request is received from
an iPhone.

We’re going to use a partial for a heading that we use in many of our templates.
Create the directory views/partials.

In the newly created directory, create the partial widget_refresh_heading.hb.html
for heading of those mojits that refresh data with the markup below. It’s
just a typical HTML file with Handlebars expressions.

Before we go ahead and update the templates to use the partial, we’re going to create
a Handlebars helper in the PageLayout mojit that will be available to
all the other mojits on the page as long as their controllers include the mojito-helpers-addon.
Update mojits/PageLayout/controller.server.js with the code below that includes
a helper that takes four arguments to create links:

We’re going to update our templates so that they use the partials we just created.
The syntax for using the partial is {{>partial_name}}. Go ahead and replace the
contents of mojits/Blog/views/index.hb.html with the following:

The Twitter and Github mojits will use the partial with the refresh button.
We’re not using the linker helper because the binders will be refreshing the content and
won’t have access to the helper unless it invokes the parent mojit PageLayout.
Add the partials to the templates with the following:

The use of partials just made our templates cleaner. Now we’re going to create templates
with different selectors so Mojito can render the appropriate ones depending
on the device making an HTTP request. Notice that the layout changes for each.

In this module, we discussed how to create custom templates, use more advanced
features of Handlebars, and configure Mojito to select templates based
on the context. As for the details, we went over the following topics:

This error can be the result of a few problems. First, check to see that
the controller of the PageLayout mojit has declared the function createLink
outside of the controller namespace (Y.namespace('mojito.controllers')), has
exposed the linker function to other mojits using the Helper addon method
ac.helpers.expose('linker',createLink), and that the mojits that are using
the helper have required the Helpers addon.

Is there a way to change the default directory structure of a Mojito application
through configuration?

You can configure the directories where Mojito looks for mojits and route configuration
files with the properties mojitDirs, mojitsDirs, and routesFiles. See
the descriptions of those properties in the configuration Object.

Is there a way to use middleware in Mojito?

Yes, you can use middleware in Mojito applications although we don’t cover it in this
tutorial. See the Middleware section
for how to set up your files and configure your application to use custom middleware.

Handlebars partials - Templates using Handlebars expressions that other templates can
include.

selectors - The version of the resource. A resource is either a file to Mojito or
metadata to the Resource Store. For example,
"selector":"iphone" would configure the Resource Store to find resources with the
identifier iphone such as index.iphone.hb.html.