Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Separate template files not rendering using backbone and underscore

Tags:

backbone.js

By using

<script type="text/template" id="templateid">
<!-- Template content goes here -->
</script>

the code works well.

However if i put the template as an external file like

<script type="text/template" id="templateid" src="template.js"></script>

this wont work.

What is the difference between the above two methods and also how can i get around this issue? Or am i missing something here which maybe obvious?

like image 350
Roy M J Avatar asked Jun 26 '13 09:06

Roy M J


2 Answers

Even though ive accepted another answer, i went ahead and implemented this particular requirement in a few different ways. Im posting the best and simple method that i found which i think will be useful for people who do not want to use any templating engines like marionette or so.

Using Backbone and Underscore :

Folder Structure

The folder Structure can be as follows :

Root:
├───css
├───js
│   ├───router.js
│   ├───model.js
│   ├───view.js
│   └───config.js   
├───templates
│   ├───home.html
│   ├───login.html
│   └───register.html   
└───images
└───index.html

Base Template

You will need to have a base template(index.html) within which you will be rendering the different templates. This will ensure that common html contents like hearder, footer, navigation menus etc are not loaded everytime a new page is rendered and thereby increasing the page loading speed drastically.

Sample structure can be as follows :

<html>
<head>
<!--Relevant CSS files-->
</head>
<body>
<div class="template_body">
    <div class="header">  
         <!--HTML content for header-->
    </div>
    <div class="content" id="template">
          <!--This would be where the dynamic content will be loaded-->
    </div>
    <div class="footer">
         <!--HTML content for footer-->
    </div>
</div>
<!--Include relevant JS Files-->
</body>
</html> 

Note : Please note that you can decide on the structure of template as one wants. What i am using is a more general one so that everyone could relate to it easily.


View

In your view, you can render a particular template to the base template as follows :

var LoginView = Backbone.View.extend({
    el: "#template",//Container div inside which we would be dynamically loading the templates
    initialize: function () {
        console.log('Login View Initialized');
    },
    render: function () {
        var that = this;
        //Fetching the template contents
        $.get('templates/login.html', function (data) {
            template = _.template(data, {});//Option to pass any dynamic values to template
            that.$el.html(template);//adding the template content to the main template.
        }, 'html');
    }
});

var loginView = new LoginView();

Note that the el tag is very important.

To pass values to view, simply pass it like :

var data_to_passed = "Hello";
$.get('templates/login.html', function (data) {
    template = _.template(data, { data_to_passed : data_to_passed }); //Option to pass any dynamic values to template
    that.$el.html(template); //adding the template content to the main template.
}, 'html');

And in the template :

<%=data_to_passed;%>//Results in "Hello"

You can pass an array, object or even a variable.

Hope this has been helpful. Cheers

like image 79
Roy M J Avatar answered Nov 08 '22 16:11

Roy M J


If you are simply trying to get the template text by using something like the $("#templateid").html() from various examples, this will work only if the text is really inline in the <script> tag.

In general, it is not possible to get the contents of a remote file using a <script> tag.

If you want to load an external template, you have to use code to explicitly get the contents (for example, using JQuery's $.get() or require.js with the text plugin).

Here is more detail on how to fetch external templates in the context of Backbone:

  • http://c2journal.com/2012/12/26/backbone-js-external-template-files-the-proper-way/ - pure Backbone + JQuery
  • http://jsdude.wordpress.com/2012/12/11/requirejs-and-backbone-template-preloading/ - using require.js and its text plugin

Be careful, however - overusing this solution will lead to a lot of additional requests to fetch templates, and a rather sluggish application as a result. In general, it is better for performance to embed the templates in the usual manner (inline in <script> tags).

like image 10
Jakub Wasilewski Avatar answered Nov 08 '22 15:11

Jakub Wasilewski