0
votes

I am building a large scale application using backbone and marionette. Instead of using underscore templating engine, I am planning to use dust.js.

I have found marionette-dust plugin which could do the job but currently I am at a loss in understanding how to use it with require.js. Also, it there a better way of implementing dust besides using this plugin?

Feedback appreciated.

Following is the code in sample application

testView.js

  define(["app", "templates/test.dust"], function(app, testTpl){
    app.module("test.view", function(view, app, Backbone, Marionette, $, _){

      view.list = Marionette.ItemView.extend({
        template: testTpl,
      });
    });

    return app.test.view;
  });

test.dust

(function() {
  dust.register("demo", body_0);

  function body_0(chk, ctx) {
    return chk.write("This is Dust.js Test");
  }
  return body_0;
})();

main.js

    requirejs.config({
      baseUrl: "assets/js",
      paths: {
        backbone: "vendor/backbone-min",
        jquery: "vendor/jquery-min",
        marionette: "vendor/backbone.marionette-min",
        tpl: "vendor/tpl",
        underscore: "vendor/underscore-min",
        dust: "vendor/dust",
        dustHelpers: 'vendor/dust-helpers',    
        dustMarionette: "vendor/backbone.marionette.dust",
        templates: 'templates/compiled',    
      },

      shim: {
        jquery: {
          exports: 'jquery'
        },

        underscore: {
          exports: "_"
        },
        backbone: {
          deps: ["jquery", "underscore"],
          exports: "Backbone"
        },
        marionette: {
          deps: ["backbone"],
          exports: "Marionette"
        },

        dust: {
            exports: 'dust'
        },
        dustHelpers: ['dust'],
        templates: ['dust', 'dustMarionette']
      }
    });

    require(["app"], function(app){
      app.start();
    });
1

1 Answers

1
votes

I'm the author of that plugin. Basically you need to define the three dependencies 'backbone', 'dust' and 'marionette' in your Requirejs config file and then define the AMD version of this module as a dependency after marionette during the initial application setup.

The plugin is written under the assumption that you have compiled all of your dust templates and they are in the dust cache (you should find details on how to do that in the dust documentation). You may see why if you have a look at the plugin source code. Inside of each your views simply set the template property to the name of the template in the dust cache that you want to use.

The plugin overrides the render function in the Marionette.Renderer object that is used by all views. So basically under the hood, Marionette is calling the render function of this plugin which renders the templates with Dust and then returns the HTML. Marionette's documentation here mentions this is the best way to provide custom rendering.

I've tried to outline all of this in the Readme file for the plugin but if you think it can be improved (which I don't doubt it can) then please let me know which areas are unclear.

I've written a Yeoman generator called generator-maryo to provide scaffolding for a marionette and dust web application. There are still a few todos in there but it provides you with a good foundation on how to use the marionette-dust plugin with marionette. If I can be more explicit in any area then let me know.

EDIT AFTER CODE ADDED TO QUESTION

The marionette-dust plugin is access by template name, not by the compiled template function. So essentially you need to run the compiled template function (which it should do by itself as it's an anonymous function), then it will be placed in the dust cache under the name "demo". So your item view should look like:

define(["app", "templates/test.dust"], function(app, testTpl){
    app.module("test.view", function(view, app, Backbone, Marionette, $, _){

        view.list = Marionette.ItemView.extend({
            template: "demo",
        });
    });

    return app.test.view;
});

Note that all I did was set the template property to "demo". Also, is this all of the code for the demo app? You need to actually show the view using a region or you can just call the render function on the view manually. To get something working quickly, you can do something like this:

myView = new app.test.view;
$('body').append(myView.render().$el);

Also, why are you wrapping the view in a module block? As you're already using RequireJS, Marionette's module system is not really necessary. I am in the process of writing a demo app for Marionette using generator-maryo which will probably explain a lot. Keep an eye out for it in the github repo.