The Cilantro codebase follows a set of conventions for ensuring consistency across implementations of views and models.

Module Headers

Module dependencies should be defined one per line rather than a single line. This is for consistency since most modules have many dependencies and for readability.

This:

define [
    'jquery'
    'underscore'
    'marionette'
], ($, _, Marionette) ->
    # ...

Not this:

define ['jquery', 'underscore', 'marionette'], ($, _, Marionette) ->
    # ...

View Data

Most views in Cilantro have a primary model or collection that is being used as the data source for rendering the view. Backbone and Marionette have facilities for automatically referencing and binding to the passed in model or collection. Some views require supplementary data sources or simply act as proxies for passing references down to subviews. The convention is to define a data attribute for storing the supplementary models and collections for the view. If the data is required, an error should be thrown if the data is not present.

class SomeLayout extends Marionette.Layout
    initialize: ->
        @data = {}
        if not (@data.context = @options.context)
            throw new Error 'context required'
        if not (@data.view = @options.view)
            throw new Error 'view required'
        if not (@data.concepts = @options.concepts)
            throw new Error 'concepts required'

    ...

Layouts

Marionette defines a Layout class that manages rendering regions (other views) within the layout. Marionette requires the region selectors be defined in the regions object property of the class definition. For symmetry and extensibility, the corresponding view classes that will be rendered in those regions should be defined on the regionViews property using the same keys.

class SomeLayout extends Marionette.Layout
    regions:
        region1: '.region1'
        region2: '.region2'

    regionViews:
        region1: SomeView1
        region2: SomeView2

    onRender: ->
        @region1.show new @regionViews.region1
            model: @model

        @region2.show new @regionViews.region2
            model: @model

Loading, Empty, and Error Views

All of Cilantro's user interface components are load asynchronously primarily because everything is data driven by the Serrano-compatible endpoint.

Unfortunately this can have ramifications on the user experience since there is a split second (hopefully no longer) that there is nothing on the page as the components are loading. In certain cases views can be rendered immediately and populated once the data is fetched.

To alleviate this, a Marionette Region can be used to show a loading view until the data is ready to show the primary view. Cilantro makes heavy use of Layouts for defining and manipulating regions, so integrating this behavior is painless.