Skip to main content
Previous sectionNext section

Working with Multiple Templates

So far this book has discussed only single-template applications, but your Zen Mojo application can use multiple template classes, which enables you to divide your application code into more easily maintained units.

Zen Mojo provides two ways to work with multiple templates: explicit dispatch and dynamic dispatch. In either case, the methods in the templates can use all the tools described in the earlier chapters of this book.

Explicit Dispatch

This section discusses the following topics:

Introduction to Explicit Dispatch

With the explicit dispatch mechanism, each template corresponds to an application area. Areas serve as short logical names for the templates, which have longer and less convenient class names.

The user makes selections on the page, invoking the goToArea() method or other methods that set the current area and therefore determine which template to use. The page methods getContent() and submitData() always use the current template, whichever that is.

Creating a page like this is only slightly more complex than creating a simple page. When a page has been set up this way, it is easy to extend the page by adding more templates.

Associating Areas with Templates

To define areas (and associate a template with each), implement the %OnGetTemplateList() method in the Zen Mojo page class. This method is as follows:

method %OnGetTemplateList(Output pTemplates) as %Status
Copy code to clipboard

Where pTemplates is expected to be a multidimensional array with the following nodes:

Node Contents
pTemplate Count of subnodes
pTemplate(i) where i is an integer A $LISTBUILD list that consists of the following items, in order:
  • Logical name of the area
  • Full package and class name of the corresponding template
  • XML namespace of the template

The following shows an example implementation:

Method %OnGetTemplateList(Output pTemplates) As %Status
{
    Set tSC = $$$OK
    Try {
        Kill pTemplates

        set area="area-home"
        set template="MyApp.Templates.HomeTemplate"
        set ns="http://www.corporate.com/myapp/home"
        Set pTemplates($I(pTemplates))=$LB(area,template,ns)

        set area="area-second"
        set template="MyApp.Templates.SecondaryTemplate"
        set ns="http://www.corporate.com/myapp/secondary"
        Set pTemplates($I(pTemplates))=$LB(area,template,ns)
    }
    Catch(ex) {
        Set tSC = ex.AsStatus()
    }
    Quit tSC
}
Copy code to clipboard

Setting the Current Area and Key for the Page

To set the current area for the page, use the following methods of the page instance. To invoke one of these methods from a client method, use the syntax zenPage.methodname().

gotoArea()
ClientMethod gotoArea(area, key1, key2, nohistory) [ Language = javascript ]
Copy code to clipboard

Sets the current area, current key1, and current key2. If nohistory is true, then do not push this change onto the history stack.

gotoAreaKB()
ClientMethod gotoArea(evt,area, key1, key2, nohistory) [ Language = javascript ]
Copy code to clipboard

Given a keyboard event (evt), sets the current area, current key1, and current key2. If nohistory is true, then do not push this change onto the history stack.

If you call any of these method, you should define changeAreaHandler() to specify what should happen when the current area and keys change.

Implementing changeAreaHandler()

If you call gotoArea() or gotoAreaKB(), be sure to define changeAreaHandler() in the page class. This method is invoked automatically by those methods, and it should specify what happens when the keys change.

The changeAreaHandler() method has following signature:

ClientMethod changeAreaHandler() [ Language = javascript ]
Copy code to clipboard

Accessing the Current Template

To access the current template, you can use the following methods of the page instance. To invoke one of these methods from a client method, use the syntax zenPage.methodname()

getTemplate()
ClientMethod getTemplate() [ Language = javascript ]
Copy code to clipboard

Returns a reference to the current template. Use this method so that, for example, you can execute methods of the template.

getTemplateForArea()
ClientMethod getTemplateForArea(area) [ Language = javascript ]
Copy code to clipboard

Returns the name of the template class associated with a given area.

Dynamic Dispatch

This section discusses the following topics:

Introduction to Dynamic Dispatch

Compared to explicit dispatch, the dynamic dispatch mechanism uses a larger set of small templates. Each template is key-specific and provides only one part of the page logic. For example, one template might only return content objects for a specific key. Another template would only handle select events for the same key.

When the dynamic dispatch mechanism is enabled (via the templateDispatchMode property), Zen Mojo checks for a key-specific template at several specific points within the page logic, loads the template, and then uses it for the designated purpose. Specifically, if dynamic dispatch is enabled:

  • When the client invokes the getContent() method of the page, Zen Mojo loads the applicable template and calls the getContent() method of that template class.

    The following subsection explains how Zen Mojo finds the applicable template in this scenario and in the following scenarios.

  • When a select event occurs on the page, Zen Mojo loads the applicable template and calls the onselect() method of that template class.

  • When a change event occurs on the page, Zen Mojo loads the applicable template and calls the onchange() method of that template class.

  • When an event of any other type occurs on the page, Zen Mojo loads the applicable template and calls the onevent() method of that template class.

How Zen Mojo Finds Templates, in Dynamic Dispatch

In dynamic dispatch, Zen Mojo finds the template to load as follows:

  1. Zen Mojo looks for a template in the following XML namespace:

    templateDispatchBaseNamespace/scenario
    Copy code to clipboard

    Where templateDispatchBaseNamespace is the value of the page property of that name and scenario indicates the scenario.

    If a data object is requested, scenario is data. If a layout graph is requested, scenario is layout. If an event (of any kind) has occurred, scenario is events.

  2. In this namespace, Zen Mojo loads the template whose short class name is key, where key is the current key.

Note that this discussion assumes that you are using data as the provider name when you are retrieving data objects and that you are using layout as the provider name when you are retrieving layout graphs.

Modifying the Page to Use Dynamic Dispatch

To modify the page class to use dynamic dispatch:

  • Override the templateDispatchMode property of the class and specify its InitialExpression keyword as 1:

    Property templateDispatchMode As %ZEN.Datatype.boolean [ InitialExpression=1] ;
    Copy code to clipboard
  • Override the templateDispatchBaseNamespace property of the class and specify its InitialExpression keyword. For the value of this keyword, specify the base part of the XML namespace used by the templates.

    For example, the Zen Mojo plugin reference documentation application uses this value:

    Property templateDispatchBaseNamespace As %ZEN.Datatype.string 
    [ InitialExpression="http://www.intersystems.com/zen/mojo/documentation"] ;
    Copy code to clipboard

Defining the Templates

To enable dynamic dispatch, define a set of templates in three groups.

  • One group returns data objects. These templates must be in the XML namespace templateDispatchBaseNamespace/data. (That is, the NAMESPACE parameter of each of these template must equal templateDispatchBaseNamespace/data where templateDispatchBaseNamespace is the value of the page class property of that name.)

    If you use a different provider name (a name other than data) to retrieve data objects, replace data with your provider name.

    These templates must implement onGetContent() and (if suitable) %OnGetJSONContent().

  • One group returns layout graphs. These templates must be in the XML namespace templateDispatchBaseNamespace/layout

    If you use a different provider name (a name other than layout) to retrieve layout graphs, replace layout with your provider name.

    These templates must implement onGetContent().

  • One group defines all event handling. These templates must be in the XML namespace templateDispatchBaseNamespace/events

    These templates must implement onselect(), onchange(), or onevent(), as needed.

Tip:

For clarify and ease of maintenance, you could place these groups of template classes in subpackages named Data, Layout, and Events, respectively. For an example, see the %ZEN.Mojo.PluginDocumentation.Templates package, which is part of the plugin reference documentation application.