8.5 KiB
{{#template name="basicTemplates"}}
Templates
In Meteor, you define your views in templates. A template is a snippet of HTML that can also include special pieces of code to include data and change which parts of the page are displayed.
Defining Templates in HTML
Templates are defined in .html files that can be located anywhere in your
Meteor project folder except the server, public, and private directories.
Each .html file can contain any number of the following top-level elements:
<head>, <body>, or <template>. Code in the <head> and <body> tags is
appended to that section of the HTML page, and code inside <template> tags can
be included using {{dstache}}> templateName}}, as shown in the example below.
Templates can be included more than once — one of the main purposes of
templates is to avoid writing the same HTML multiple times by hand.
<!-- add code to the <head> of the page -->
<head>
<title>My website!</title>
</head>
<!-- add code to the <body> of the page -->
<body>
<h1>Hello!</h1>
{{dstache}}> welcomePage}}
</body>
<!-- define a template called welcomePage -->
<template name="welcomePage">
<p>Welcome to my website!</p>
</template>
The {{dstache}} ... }} syntax is part of a language called "Spacebars" that
Meteor uses to add functionality to HTML. As shown above, it lets you include
templates in other parts of your page. Using Spacebars, you can also display
data obtained from helpers. Helpers are written in JavaSript, and can be
either simple values or functions.
{{> autoApiBox "Template#helpers"}}
Here's how you might define a helper called name for a template called
nametag (in JavaScript):
Template.nametag.helpers({
name: "Ben Bitdiddle"
});
And here is the nametag template itself (in HTML):
<!-- In an HTML file, display the value of the helper -->
<template name="nametag">
<p>My name is {{dstache}}name}}.</p>
</template>
Spacebars also has a few other handy control structures that can be used to make your views more dynamic:
{{dstache}}#each data}} ... {{dstache}}/each}}- Iterate over the items indataand display the HTML inside the block for each one.{{dstache}}#if data}} ... {{dstache}}else}} ... {{dstache}}/if}}- Ifdataistrue, display the first block; if it is false, display the second one.{{dstache}}#with data}} ... {{dstache}}/with}}- Set the data context of the HTML inside, and display it.
Each nested #each or #with block has its own data context, which is
an object whose properties can be used as helpers inside the block. For
#with blocks, the data context is simply the value that appears after
the #with and before the }} characters. For #each blocks, each
element of the given array becomes the data context while the block is
evaluated for that element.
For instance, if the people helper has the following value
Template.welcomePage.helpers({
people: [{name: "Bob"}, {name: "Frank"}, {name: "Alice"}]
});
then you can display every person's name as a list of <p> tags:
{{dstache}}#each people}}
<p>{{dstache}}name}}</p>
{{dstache}}/each}}
or use the "nametag" template from above instead of <p> tags:
{{dstache}}#each people}}
<p>{{dstache}}> nametag}}</p>
{{dstache}}/each}}
Remember that helpers can be functions as well as simple values. For
example, to show the logged in user's username, you might define a
function-valued helper called username:
// in your JS file
Template.profilePage.helpers({
username: function () {
return Meteor.user() && Meteor.user().username;
}
});
Now, each time use the username helper, the helper function will be
called to determine the user's name:
// in your HTML
<template name="profilePage">
<p>Profile page for {{username}}</p>
</template>
The helpers above have all been associated with specific templates, but
you can also make a helper available in all templates by using
Template.registerHelper.
You can find detailed documentation for Spacebars in the
README on GitHub.
Later in this documentation, the sections about Session, Tracker,
Collections, and Accounts will talk more about how to add dynamic data
to your templates.
{{> autoApiBox "Template#events"}}
The event map passed into Template.myTemplate.events has event
descriptors as its keys and event handler functions as the values. Event
handlers get two arguments: the event object and the template instance.
To attach event handlers to the following template
<template name="example">
<button class="my-button">My button</button>
<form>
<input type="text" name="myInput" />
<input type="submit" value="Submit Form" />
</form>
</template>
you might call Template.example.events as follows:
Template.example.events({
"click .my-button": function (event, template) {
alert("My button was clicked!");
},
"submit form": function (event, template) {
var inputValue = event.target.myInput.value;
alert(inputValue);
}
});
The first part of the key (before the first space) is the name of the
event being captured. Pretty much any DOM event is supported. Some common
ones are: click, mousedown, mouseup, mouseenter, mouseleave,
keydown, keyup, keypress, focus, blur, and change.
The second part of the key (after the first space) is a selector that indicates which elements to listen to. This can be almost any selector supported by JQuery.
Whenever the indicated event happens on the selected element, the corresponding event handler function will be called with the relevant DOM event object and template instance. See the Event Maps section for details.
{{> autoApiBox "Template#rendered"}}
The function assigned to this property is called once for every instance of Template.myTemplate when it is inserted into the document for the first time.
This rendered callback can be used to integrate external libraries that aren't
familiar with Meteor's automatic view rendering, and need to be initialized
every time HTML is inserted into the page. Use the
created and
destroyed callbacks to perform
initialization or clean-up on any objects.
For example, to use the HighlightJS library to apply code highlighting to
all <pre> elements inside the codeSample template, you might assign
the following function to Template.codeSample.rendered:
Template.codeSample.rendered = function () {
hljs.highlightBlock(this.findAll('pre'));
};
In the callback function, this is bound to a template
instance object that is unique to this inclusion of the
template and remains across re-renderings. You can use methods like
this.find and
this.findAll to access DOM nodes in the template's
rendered HTML.
Template instances
A template instance object represents a single inclusion of a template in the document. It can be used to access the DOM and it can be assigned properties that persist as the template is reactively updated.
Template instance objects can be found in several places:
- The value of
thisin thecreated,rendered, anddestroyedtemplate callbacks - The second argument to event handlers
- As
Template.instance()inside helpers
You can assign additional properties of your choice to the template instance to
keep track of any state relevant to the template. For example, when using the
Google Maps API you could attach the map object to the current template
instance to be able to refer to it in helpers and event handlers. Use the
created and destroyed callbacks
to perform initialization or clean-up.
{{> autoApiBox "Blaze.TemplateInstance#findAll"}}
template.findAll returns an array of DOM elements matching selector. You can
also use template.$, which works exactly like JQuery but only returns elements
within template.
{{> autoApiBox "Blaze.TemplateInstance#find"}}
Get one DOM element matching selector, or null if there are no
such elements. Like findAll, find only returns elements from inside the
template.
{{/template}}