Marionette - How to set the template for Layout from html loading through requirejs?

915 views Asked by At

I am using Marionette for my app development. I am loading controllers by dynamically from routes. works fine.

once the controller loaded, It calls appropriate layout. for ex. loginController calls the loginLayout.

I have a single layouts.html, where all my layout nested. i am using requirejs and getting the layouts.html using:

"text!./layouts.html"

but from the layouts.html, I can't able to get my template. my layout.html is:

    <script type="text/template" id="loginTemplate">
        <section class="login">
            <p>I am only for login purpose</p>
        </section>
    </script>

   <script type="text/template" id="contactTemplate">
    <header>

    </heder>
    <section class="login">
        <p>I am only for login purpose</p>
    </section>
    <footer></footer>
</script>

I am trying like this:

define([
    "jQuery","underscore",
    "backbone","marionette",
    "text!./layouts.html"
    ],
    function($,_,Backbone,Marionette,template){

        var loginLayout = Backbone.Marionette.Layout.extend({

            template:$(template,"#loginTemplate"), //i am not getting the template from layouts.html

            regions:{
                content:'section'
            },
            initialize:function(){
                console.log(this.template)
            },
            render:function(view){
                $(this.content.el).html(view);
            }

        });

        return loginLayout;

    }
);

why I am not able to get my template? and what is the correct way to get it? any one help me please?

Thanks in advance.

2

There are 2 answers

0
kalley On

Here's one option:

// This needs to go in some configuration file or something that gets called before your views
_.extend(Marionette.TemplateCache.prototype, {
  constructor: function(templateId, context) {
    this.templateId = templateId;
    this.context = context;
  },
  loadTemplate: function(templateId) {
    var template = Marionette.$(templateId, this.context).html();

    if ( ! template || template.length === 0 ) {
      throw new Error("Could not find template: '" + templateId + "'");
    }

    return template;
  }
});

And then in your view, you'd use it like this:

var loginLayout = Backbone.Marionette.Layout.extend({

    template:Marionette.TemplateCache.get("#loginTemplate", template),

    regions:{
        content:'section'
    },
    initialize:function(){
        console.log(this.template)
    },
    render:function(view){
        $(this.content.el).html(view);
    }

});

Another option would be to only include the layout.hml file in a configuration file, then you won't need to call it in each file:

define([
    "jQuery","underscore",
    "backbone","marionette",
    "text!./layouts.html"
    ],
    function($,_,Backbone,Marionette,template){
        _.extend(Marionette.TemplateCache.prototype, {
            loadTemplate: function(templateId) {
                var template = Marionette.$(templateId, template).html();

                if ( ! template || template.length === 0 ) {
                    throw new Error("Could not find template: '" + templateId + "'");
                }

                return template;
            }
        });

        return Marionette.TemplateCache;
});

Then you'd just have:

template: '#loginTemplate'

The benefit of this is that you can also throw in another check for it to check the document or anything else that you'd want to find that template within.

0
Dave Vanderburg On

You can load the template as HTML instead of providing a DOM identifier by defining the Marionette view template property as a function instead of a string.

define([
    'text!templates/my_template.html'
], function(
    Templates
) {

    return Marionette.View.extend({

        template: function(data) {
            return _.template($(Templates).filter("#template_id").html())(data);
        }

    });

});

This looks for an element with the ID "template_id" in the my_template.html file, gets the inner HTML of that element and the uses it as a template, passing in the template data.