mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
277 lines
9.2 KiB
Markdown
277 lines
9.2 KiB
Markdown
{{#template name="basicTemplates"}}
|
|
|
|
<h2 id="templates"><span>Templates</span></h2>
|
|
|
|
In Meteor, views are defined in _templates_. A template is a snippet of HTML
|
|
that can include dynamic data. You can also interact with your templates from
|
|
JavaScript code to insert data and listen to events.
|
|
|
|
<h3 class="api-title" id="defining-templates">Defining Templates in HTML</h3>
|
|
|
|
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 JavaScript, 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 in
|
|
`data` and display the HTML inside the block for each one.
|
|
- `{{dstache}}#if data}} ... {{dstache}}else}} ... {{dstache}}/if}}` - If `data`
|
|
is `true`, 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 you use the `username` helper, the helper function above
|
|
will be called to determine the user's name:
|
|
|
|
```
|
|
<!-- in your HTML -->
|
|
<template name="profilePage">
|
|
<p>Profile page for {{dstache}}username}}</p>
|
|
</template>
|
|
```
|
|
|
|
Helpers can also take arguments. For example, here's a helper that pluralizes
|
|
a word:
|
|
|
|
```js
|
|
Template.post.helpers({
|
|
commentCount: function (numComments) {
|
|
if (numComments === 1) {
|
|
return "1 comment";
|
|
} else {
|
|
return numComments + " comments";
|
|
}
|
|
}
|
|
});
|
|
```
|
|
|
|
Pass in arguments by putting them inside the curly braces after the name of the
|
|
helper:
|
|
|
|
```html
|
|
<p>There are {{dstache}}commentCount 3}}.</p>
|
|
```
|
|
|
|
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`](#template_registerhelper).
|
|
|
|
You can find detailed documentation for Spacebars in the
|
|
[README on GitHub](https://github.com/meteor/meteor/blob/devel/packages/spacebars/README.md).
|
|
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. Event handlers can also
|
|
access the data context of the target element in `this`.
|
|
|
|
To attach event handlers to the following template
|
|
|
|
```
|
|
<template name="example">
|
|
{{#with myHelper}}
|
|
<button class="my-button">My button</button>
|
|
<form>
|
|
<input type="text" name="myInput" />
|
|
<input type="submit" value="Submit Form" />
|
|
</form>
|
|
{{/with}}
|
|
</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;
|
|
var helperValue = this;
|
|
alert(inputValue, helperValue);
|
|
}
|
|
});
|
|
```
|
|
|
|
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 CSS selector that
|
|
indicates which elements to listen to. This can be almost any selector
|
|
[supported by JQuery](http://api.jquery.com/category/selectors/).
|
|
|
|
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](#eventmaps)
|
|
for details.
|
|
<!-- TODO Update the link to full docs for Event Maps -->
|
|
|
|
{{> autoApiBox "Template#rendered"}}
|
|
|
|
The function assigned to this property is called once for every instance of
|
|
*Template.myTemplate* when it is inserted into the page 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`](#template_created) and
|
|
[`destroyed`](#template_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`:
|
|
|
|
<!-- XXX Why is this not a function like Meteor.startup? -->
|
|
```
|
|
Template.codeSample.rendered = function () {
|
|
hljs.highlightBlock(this.findAll('pre'));
|
|
};
|
|
```
|
|
|
|
In the callback function, `this` is bound to a [template
|
|
instance](#template_inst) object that is unique to this inclusion of the
|
|
template and remains across re-renderings. You can use methods like
|
|
[`this.find`](#template_find) and
|
|
[`this.findAll`](#template_findAll) to access DOM nodes in the template's
|
|
rendered HTML.
|
|
|
|
<h2 id="template_inst"><span>Template instances</span></h2>
|
|
|
|
A template instance object represents a single inclusion of a template in the
|
|
document. It can be used to access the HTML elements inside the template and it
|
|
can be assigned properties that persist as the template is reactively updated.
|
|
|
|
Template instance objects can be found in several places:
|
|
|
|
1. The value of `this` in the `created`, `rendered`,
|
|
and `destroyed` template callbacks
|
|
2. The second argument to event handlers
|
|
3. As [`Template.instance()`](#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`](#template_created) and [`destroyed`](#template_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 the JQuery `$` function but only
|
|
returns elements within `template`.
|
|
|
|
{{> autoApiBox "Blaze.TemplateInstance#find"}}
|
|
|
|
<!-- XXX Why is this not findOne? -->
|
|
|
|
`find` is just like `findAll` but only returns the first element found. Like
|
|
`findAll`, `find` only returns elements from inside the template.
|
|
|
|
{{/template}}
|