I am working on a Backbone.js application. We are using underscore.js templates to load the contents to the View. Currently we have all the templates inside the index.html file, so the size of the file is increasing. Can anyone help me to find a solution for separating these templates to other files? Thanks in advance.
EDIT
Recently I have visited the Backbone patterns and I found that we can use JST templates to create separate template files for each template. They explained that we can create a jst.js file to put all our template code:
// http://myapp.com/javascripts/jst.js
window.JST = {};
window.JST['person/contact'] = _.template(
"<div class='contact'><%= name %> ..."
);
window.JST['person/edit'] = _.template(
"<form method='post'><input type..."
);
<script src="http://myapp.com/javascripts/jst.js"></script>
Now all the templates are in the jst.js file. But if you have lots of templates and you want to move the templates to separate files you can create separate template files:
// http://myapp.com/javascripts/jst.js
window.JST = {};
//http://myapp.com/javascripts/contactPerson.template.js
window.JST['person/contact'] = _.template(
"<div class='contact'><%= name %> ..."
);
//http://myapp.com/javascripts/editPerson.template.js
window.JST['person/edit'] = _.template(
"<form method='post'><input type..."
);
<script src="http://myapp.com/javascripts/jst.js"></script>
<script src="http://myapp.com/javascripts/contactPerson.js"></script>
<script src="http://myapp.com/javascripts/editPerson.js"></script>
Please let me know if there is any simpler idea. Thanks!
You can have templates in seperate html files and can load them as text using requirejs. There is a plugin called text which will help you to do that.
Example:
define([
'text!templates/sampleTemplate.html'
], function(tmpl){
var Sampleview = Backbone.View.extend({
id: 'sample-page',
template: _.template(tmpl),
render: function() {
$(this.el).html(this.template());
return this;
}
});
return SampleView;
});
The html file "templates/sampleTemplate.html" will be taken from the root path specified in the require.js config
Load them via xhr. The lib requirejs (requirejs.org) loads html file dependencies this way. This will work when in development, but the templates should be compiled into the js files in production.
Related
I am very new in angularJs please guide me ,i have created custom directive called testDirective in separate file and my controller and config files are in separate files i want to use my custom directive in my html page but while loading the application that custom element is loading but not able to fetch content of directive i guess m missing some sort of mapping .kindly help me
//this is testDirective.js
var app=angular.module('mytodoApp');
app.directive('testDirective',function(){
return {
restrict:'E',
template:'<h2>This is comes from directive</h2>'
};
});
var app=angular.module('mytodoApp');
app.controller('MainCtrl', function ($scope) {
$scope.awesomeThings = [
'HTML5 Boilerplate',
'AngularJS',
'Karma'
];
});
< test-directive>
< /test-directive>
You have to bootstrap the Angular app, otherwise the HTML page does not know that you are using AngularJS and what you app has.
Bootstrapping is done by using ng-app="moduleName".
<div ng-app="mytodoApp">
<test-directive></test-directive>
</div>
As said by #JBNizet, you should add your custom directive code, by adding it trough the script tag in your HTML code.
Since browsers can only load 5 to 10 scripts at the same time, it is nessesary in production to concatenate your files with Grunt or Gulp.
Helllo, probably this is a common question, but I didn't find the appropriate answer.
I have an html file: header.html which contains a header which I want to display
Here is my Backbone.View
el: $(".header"),
initialize: function () {
this.render();
},
render: function () {
var template = _.template( $("#header_template").html(), {} );
this.$el.html( template );
},
When I put the code inside a java script template, it works:
<script type="text/template" id="header_template">
code of header.html goes here
</script>
But when I use it this way:
<script type="text/template" id="about_template" src="header.html"></script>
it stops working even though, the firebug sees the code inside a template.
Can someone tell me what my mistake is and how to solve it
A clean way to organize your templates is to create a subfolder tpl. Here you add all your .html files
Coenraets has a nice tutorial where he uses this approach together with a templateloader function.
You then load the templates in memory before bootstrapping your backbone application.
tpl.loadTemplates(['header', 'wine-details', 'wine-list-item'], function() {
app = new AppRouter();
Backbone.history.start();
});
I want to do some basic i18n in my application
I loaded the i18n plugin (from require.js) to my Application and created a directory nls in which i have several files e.g. project.js
I set up the default location in main.js file like
config : {
i18n : {
locale : 'de-de'
}
}
I now want to use the files in my View / Template. Can somebody explain to me how this is done? The templates are setup in one template.js file
My View:
define(['marionette', 'templates', 'i18n!nls/project'], function (marionette, templates, msg) {
return marionette.CompositeView.extend({
template : templates.project
});
});
My template:
<div class="container">
<div class="well">
<h2>Projects</h2>
</div>
</div>
Can someone explain to me how to use the file in my View / Template? Thanks in advance!
EDIT:
I figured out the solution by some try&error. As i am loading the templates via the require.js tpl! plugin i dont need to compile them if i call them by require('tpl!templates/dashboard.tmpl'). I can simply pass the i18n file i loaded by 'i18n!nls/dashboard'. In Marionette the view are rendered by default, so i did this:
define(['marionette', 'templates', 'i18n!nls/dashboard'], function (Marionette, templates, msg) {
return Marionette.CompositeView.extend({
template : function () {
return templates.dashboard(msg);
},
initialize : function() {
}
});
});
The files for the i18n plugin are well explained here:
http://requirejs.org/docs/api.html#i18n
I had to do this step by step, first i missed the root, then i wondered why my german locale did not load, but i simply forgot to set de-de : true in the root file. Now everything is working like a charm
first you load the i18 file via require.js to your view.
I use the handlebars templates in this example.
define([
'marionette',
'handlebars',
'text!modules/tableModule/templates/myTmpl.html',
'i18n!nls/dashboard',
],
function(Marionette, Handlebars, tmpl, locals) { ...
then you compile and load your template with the i18 object.
var template = Handlebars.compile(tmpl);
this.template = template(locals.myVar);
you can go and do complex combinations as well
var template = Handlebars.compile(tmpl);
var data =_.extend(options, {lang:locals});
this.template = template(data);
your nls file will look like this
define({
"root": {
"myVar" : "some text in",
"canBeAnObjectTo": {
"title" : "my title ",
"contact" : "Contact",
}
and your view will be something like this:
<div class="cssClass">
<div class="table-caption pull-left">{{this.myVar}}</div>
</div>
hope that helps
I am using an .ejs template in my view. But for some reason the view does not load the given template. It returns undefined. Here's the code:
sandplate2.applicationView = Backbone.View.extend({
el: 'div',
template: _.template($("appl.ejs").html()),
initialize: function(){
console.log("Application view initialize");
_.bindAll(this, "render");
this.render();
},
render: function(){
console.log("Application view rendering");
this.$el.html(this.template());
return this;
}
});
Do I have to configure something else in order to load a template?
I structured my app using Yeoman. I used the init and backbone generators.
FYI - The template I am trying to load is loaded in the index.html using a script element.
If you built it using Yeoman, take a look at app.js to see if you are using Backbone.LayoutManager. You might have to change the configuration there for EJS to work. By default, I think it should be expecting Underscore templates.
I'm using Handlebars and I updated my app.js to look like this:
Backbone.LayoutManager.configure({
manage: true,
paths: {
layout: "templates/layouts/",
template: "templates/"
},
fetch: function(path) {
path = path + ".html";
if (!JST[path]) {
$.ajax({ url: app.root + path, async: false }).then(function(contents) {
JST[path] = Handlebars.compile(contents);
});
}
return JST[path];
}
});
I also added Handlebars to the module's define() call, passing in 'Handlebars' as a reference. You might need to do something similar for EJS.
Please try with latest backbone genearator with yeoman 1.0beta.
We have made lot of improvements on it including Precompiling ejs templates. You don't want to worry about templates, yeoman will precompile and load it for you.
A sample generated code for input-view is provided below.
Todo.Views.InputView = Backbone.View.extend({
template: JST['app/scripts/templates/input.ejs'],
render: function(){
$(this.el).html(this.template());
}
});
Conventions aside, it looks like the problem is simply your jQuery lookup.
_.template($("appl.ejs")...
$('appl.ejs') isn't a valid DOM selector unless you have an element like this in your index.html
<appl class="ejs"></appl>
If you're trying to target your template with jQuery, give it an ID or something that jQuery can find like so:
<script type="text/template" id="appl">
<div></div><!-- template html here -->
</script>
// later...
$('#appl').html()
// will get your template html
However, as others have mentioned, in a yeoman and require.js workflow, you can ask require.js to fetch the template for you as text and throw it around as a variable before creating an underscore template.
I'm building an app with backbone/RequireJs on the front end and node/express on the backend. All written in CoffeeScript. I'm having trouble getting HTML template files to load properly with the text! plugin.
My Config is a s follows:
require.config
paths:
app: 'app'
jquery: 'libs/jquery-1.7.1'
jqueryTmpl: 'libs/jquery.tmpl'
jqueryUI: 'libs/jquery-ui-1.8.18.custom.min'
underscore: 'libs/underscore.amd'
order: 'libs/order'
backbone: 'libs/backbone.amd'
handlebars: 'libs/handlebars'
bootstrap: 'libs/bootstrap/js/bootstrap'
marionette: 'libs/backbone.marionette'
modelbinding: 'libs/backbone.modelbinding'
validation: 'libs/backbone.validation'
jqueryQtip: 'libs/jquery.qtip'
utils: 'utils'
jqueryDatatables: 'libs/datatables/jquery.dataTables'
DT_bootstrap: 'libs/datatables/DT_bootstrap'
user_maintenance: 'templates/tmpl.user.maintenance'
require [
"require",
"jquery",
"underscore",
"backbone",
"order!jqueryTmpl",
"order!marionette",
"order!validation",
"app"
]
This is the start of one of my views :-
define (require) ->
Backbone = require 'backbone'
Backbone.ModelBinding = require 'modelbinding'
require 'jqueryUI'
require 'jqueryQtip'
require '../../scripts/text!user_maintenance.html'
Utils = require '../../scripts/Utils.js'
class UserMaintenanceView extends Backbone.Marionette.ItemView
template: "#tmpl-user-maintenance"
className: "row"
.
.
.
If I look at the network tab in Chrome developer tools, the /scripts/templates/tmpl.user.maintenance.html file has been loaded via a GET. Clicking on it shows the contents that appear like so. (I removed the contents for brevity, its just HTML)
<script type="text/x-jquery-tmpl" id="tmpl-user-maintenance">
</script>
I don't get any script errors, but the template doesn't appear in the DOM and my view is not rendered. If I simply paste the HTML template into the main HTML file and don't try to load with the text plugin everything works fine. But I want to break my templates into separate files.
Any idea what I'm doing wrong?
The text!plugin does not inject the text into the DOM, it only loads the given file and it is up to you to process the content. See http://requirejs.org/docs/api.html#text for more information.
You'll have to assign/append the returned HTML from the template call into the DOM.
Example:
$('.someClass').html(Template, {}); // where {} === the data object for the template