Hello there, {{dstache}}first}} {{dstache}}last}}!
{{! }}template>
// in the JavaScript console
> Template.hello({first: "Alyssa", last: "Hacker"});
=> "Hello there, Alyssa Hacker!
"
This returns a string. To use the template along with the [`Live
HTML`](#livehtml) system, and get DOM elements that update
automatically in place, use [`Meteor.render`](#meteor_render):
Meteor.render(function () {
return Template.hello({first: "Alyssa", last: "Hacker"});
})
=> automatically updating DOM elements
The easiest way to get data into templates is by defining helper
functions in JavaScript. Just add the helper functions directly on the
`Template.[template name]` object. For example, in this template:
{{dstache}}#each topScorers}}
{{dstache}}name}}
{{dstache}}/each}}
{{! }}template>
instead of passing in `topScorers` as data when we call the
template function, we could define a function on `Template.players`:
Template.players.topScorers = function () {
return Users.find({score: {$gt: 100}}, {sort: {score: -1}});
};
In this case, the data is coming from a database query. When the
database cursor is passed to `#each`, it will wire up all of the
machinery to efficiently add and move DOM nodes as new results enter
the query.
Helpers can take arguments, and they receive the current template data
in `this`:
// in a JavaScript file
Template.players.leagueIs = function (league) {
return this.league === league;
};
{{dstache}}#each topScorers}}
{{dstache}}#if leagueIs "junior"}}
Junior: {{dstache}}name}}
{{dstache}}/if}}
{{dstache}}#if leagueIs "senior"}}
Senior: {{dstache}}name}}
{{dstache}}/if}}
{{dstache}}/each}}
{{! }}template>
{{#note}}
Handlebars note: `{{dstache}}#if leagueIs "junior"}}` is
allowed because of a Meteor extension that allows nesting a helper
in a block helper. (Both `if` and `leagueIs` are
technically helpers, and stock Handlebars would not invoke
`leagueIs` here.)
{{/note}}
Helpers can also be used to pass in constant data.
// Works fine with {{dstache}}#each sections}}
Template.report.sections = ["Situation", "Complication", "Resolution"];
Finally, you can use an `events` declaration on a template function to set up a
table of event handlers. The format is documented at [Event
Maps](#eventmaps). The `this` argument to the event handler will be
the data context of the element that triggered the event.
{{dstache}}#each player}}
{{dstache}}> playerScore}}
{{dstache}}/each}}
{{! }}template>
{{dstache}}name}}: {{dstache}}score}}
Give points
{{! }}template>
Template.playerScore.events({
'click .givePoints': function () {
Users.update(this._id, {$inc: {score: 2}});
}
});
Putting it all together, here's an example of how you can inject
arbitrary data into your templates, and have them update automatically
whenever that data changes. See [Live HTML](#livehtml) for further
discussion.
It'll be {{dstache}}prediction}} tonight
{{! }}template>
// JavaScript: reactive helper function
Template.forecast.prediction = function () {
return Session.get("weather");
};
> Session.set("weather", "cloudy");
> document.body.appendChild(Meteor.render(Template.forecast));
In DOM: It'll be cloudy tonight
> Session.set("weather", "cool and dry");
In DOM: It'll be cool and dry tonight
{{/better_markdown}}
{{#better_markdown}}
Using packages
All of the functionality you've read about so far is implemented as
standard Meteor packages. This is possible thanks to Meteor's
unusually powerful package and build system. The same packages work in
the browser and on the server, and packages can contain plugins that
extend the build process, such as `coffeescript` ([CoffeeScript](http://coffeescript.org)
compilation) or `templating` (compiling HTML templates).
You can see a list of available packages
with [`meteor list`](#meteorlist), add packages to your project
with [`meteor add`](#meteoradd), and remove them
with [`meteor remove`](#meteorremove).
By default all apps include the `standard-app-packages` package. This
automatically pulls in the packages that make up the core Meteor
stack. To keep things simple, these core packages are also hidden in
the output for `meteor list`, but you can read the
[source code of `standard-app-packages`](https://github.com/meteor/meteor/blob/master/packages/standard-app-packages/package.js)
to see what they are (as Meteor is pre-1.0, they may change from release to
release). If you want to build your own custom stack, just remove
`standard-app-packages` from your app and add back in whichever of the standard
packages you want to keep.
In addition to the packages in the official Meteor release being used
by your app, `meteor list` and `meteor add` also search the `packages`
directory at the top of your app. If you've downloaded an unofficial
package from Atmosphere you should unpack it into that directory (the
unofficial [Meteorite](http://oortcloud.github.io/meteorite/) tool
streamlines this process). You can also use the `packages` directory
to break your app into subpackages for your convenience — if you
are willing to brave the fact that the Meteor package format is not
documented yet and will change significantly before Meteor 1.0. See
[Writing Packages](#writingpackages).
{{/better_markdown}}
{{#better_markdown}}
Namespacing
Meteor's namespacing support makes it easy to write large applications
in JavaScript. Each package that you use in your app exists in its own
separate namespace, meaning that it sees only its own global variables
and any variables provided by the packages that it specifically
uses. Here's how it works.
When you declare a top-level variable, you have a choice. You can make
the variable File Scope or Package Scope.
// File Scope. This variable will be visible only inside this
// one file. Other files in this app or package won't see it.
var alicePerson = {name: "alice"};
// Package Scope. This variable is visible to every file inside
// of this package or app. The difference is that 'var' is
// omitted.
bobPerson = {name: "bob"};
Notice that this is just the normal JavaScript syntax for declaring a
variable that is local or global. Meteor scans your source code for
global variable assignments and generates a wrapper that makes sure
that your globals don't escape their appropriate namespace.
In addition to File Scope and Package Scope, there are also
Exports. An export is a variable that a package makes available to you
when you use it. For example, the `email` package exports the `Email`
variable. If your app uses the `email` package (and _only_ if it uses
the `email` package!) then your app can see `Email` and you can call
`Email.send`. Most packages have only one export, but some packages
might have two or three (for example, a package that provides several
classes that work together).
You see only the exports of the packages that you use directly. If you
use package A, and package A uses package B, then you only see package
A's exports. Package B's exports don't "leak" into your namespace just
because you used package A. This keeps each namespace nice and
tidy. Each app or package only sees their own globals plus the APIs of
the packages that they specifically asked for.
When debugging your app, your browser's JavaScript console behaves as
if it were attached to your app's namespace. You see your app's
globals and the exports of the packages that your app uses
directly. You don't see the variables from inside those packages, and
you don't see the exports of your transitive dependencies (packages
that aren't used directly by your app, but that are used by packages
that are used by your app).
If you want to look inside packages from inside your in-browser
debugger, you've got two options:
* Set a breakpoint inside package code. While stopped on that
breakpoint, the console will be in the package's namespace. You'll
see the package's package-scope variables, imports, and also any
file-scope variables for the file you're stopped in.
* If a package `foo` is included in your app, regardless of whether
your app uses it directly, its exports are available in
`Package.foo`. For example, if the `email` package is loaded, then
you can access `Package.email.Email.send` even from namespaces that
don't use the `email` package directly.
When declaring functions, keep in mind that `function x () {}` is just
shorthard for `var x = function () {}` in JavaScript. Consider these
examples:
// This is the same as 'var x = function () ...'. So x() is
// file-scope and can be called only from within this one file.
function x () { ... }
// No 'var', so x() is package-scope and can be called from
// any file inside this app or package.
x = function () { ... }
{{#note}}
Technically speaking, globals in an app (as opposed to in a package)
are actually true globals. They can't be captured in a scope that is
private to the app code, because that would mean that they wouldn't be
visible in the console during debugging! This means that app globals
actually end up being visible in packages. That should never be a
problem for properly written package code (since the app globals will
still be properly shadowed by declarations in the packages). You
certainly shouldn't depend on this quirk, and in the future Meteor may
check for it and throw an error if you do.
{{/note}}
{{/better_markdown}}
{{#better_markdown}}
Deploying
Meteor is a full application server. We include everything you need
to deploy your application on the internet: you just provide the JavaScript,
HTML, and CSS.
Running on Meteor's infrastructure
The easiest way to deploy your application is to use `meteor
deploy`. We provide it because it's what, personally, we've always
wanted: an easy way to take an app idea, flesh it out over a weekend,
and put it out there for the world to use, with nothing getting in the
way of creativity.
$ meteor deploy myapp.meteor.com
Your application is now available at myapp.meteor.com. If
this is the first time deploying to this hostname, Meteor creates a
fresh empty database for your application. If you want to deploy an
update, Meteor will preserve the existing data and just refresh the
code.
You can also deploy to your own domain. Just set up the hostname you
want to use as a CNAME to `origin.meteor.com`,
then deploy to that name.
$ meteor deploy www.myapp.com
We provide this as a free service so you can try Meteor. It is also
helpful for quickly putting up internal betas, demos, and so on.
Running on your own infrastructure
You can also run your application on your own infrastructure, or any
other hosting provider like Heroku.
To get started, run
$ meteor bundle myapp.tgz
This command will generate a fully-contained Node.js application in the form of
a tarball. To run this application, you need to provide Node.js 0.10 and a
MongoDB server. (The current release of Meteor has been tested with Node
0.10.22, and is recommended for use with 0.10.22 through 0.10.24 only.) You can
then run the application by invoking node, specifying the HTTP port for the
application to listen on, and the MongoDB endpoint. If you don't already have a
MongoDB server, we can recommend our friends at [MongoHQ](http://mongohq.com).
$ PORT=3000 MONGO_URL=mongodb://localhost:27017/myapp node bundle/main.js
Other packages may require other environment variables (for example, the `email`
package requires a `MAIL_URL` environment variable).
{{#warning}}
For now, bundles will only run on the platform that the bundle was
created on. To run on a different platform, you'll need to rebuild
the native packages included in the bundle. To do that, make sure you
have `npm` available, and run the following:
$ cd bundle/programs/server/node_modules
$ rm -r fibers
$ npm install fibers@1.0.1
{{/warning}}
{{/better_markdown}}
{{#better_markdown}}
Writing packages
The Meteor package format isn't officially documented and will change
before Meteor 1.0. But that hasn't stopped people like you from
creating hundreds of packages by reading the source code of existing
packages and following the model. If you do decide to create your own
packages, you will have to do some detective work, but here are some
quick tips:
* A package is simply a directory with a `package.js` file in it. Look in the
[`packages` directory of the Meteor source
tree](https://github.com/meteor/meteor/tree/master/packages/) for example
`package.js` files. The format and name of the `package.js` file will change
significantly before Meteor 1.0, but the functionality will be basically the
same even though the syntax is different, so it will be easy to port your
code.
* Packages explicitly list all of their source files using `api.add_files`, and
the files are loaded exactly in the order specified. (This is different from
apps, where Meteor scans a directory tree to find the source files.) Don't
forget to include any build plugin packages (such as `coffeescript` or, if
using HTML templates, `templating`) that you require.
* Exporting a symbol from your package (see
[Namespacing](#namespacing)) is accomplished with an `api.export` call
from inside your `on_use` handler.
* An esoteric point about exports: they are not lvalues. You can't set
an exported variable to a new value after exporting it. If you
export `a = {name: 'alice'}` then you can change `a.name` anytime
you want, but if after startup you set `a` to a whole new object
then the packages that import `a` won't see the change. Since your
exports are most always objects or functions, this is hardly ever an
issue.
* Packages can use [npm modules](https://npmjs.org/). Use `Npm.depends` in your
`package.js` to list the npm modules that you need and the specific
versions that you want to use. Then use `Npm.require` inside your
package to pull in the modules when you need them. Meteor strives to
have 100% repeatable builds so that everyone on your team is always
running the same code, and that's why you must explicitly lock your
npm dependencies to specific versions. Behind the scenes, Meteor
will use `npm shrinkwrap` to also lock down the versions of the
transitive dependencies of all of the npm modules that you use.
* Whenever your package changes, Meteor will rebuild it (compiling
non-JavaScript source files, fetching npm dependencies, constructing
namespace wrappers, and so on). The built package will be cached and
rebuilt only when a source file changes (tracked by SHA1) or when
other dependencies such as build plugins change. To force a rebuild
you can use the undocumented command `meteor rebuild-all`, but this
should never be necessary (if it is, please send a
[bug report](https://github.com/meteor/meteor/blob/devel/Contributing.md#filing-bug-reports)!).
* Build plugins are created with `_transitional_registerBuildPlugin`,
an API that is very much in flux. See the `coffeescript` package for
an example. Build plugins are fully-fledged Meteor programs in their
own right and have their own namespace, package dependencies, source
files and npm requirements. The old `register_extension` API is
removed.
* It is possible to create weak dependencies between packages. If
package A has a weak dependency on package B, it means that
including A in an app does not force B to be included too —
but, if B _is_ included, say by the app developer or by another
package, then B will load before A. You can use this to make
packages that optionally integrate with or enhance other packages if
those packages are present. To create a weak dependency, pass
`{weak: true}` as the third argument to `api.use`. When you weakly
depend on a package you don't see its exports. You can detect if
the possibly-present weakly-depended-on package is there by seeing
if `Package.foo` exists, and get its exports from the same place.
* It is also possible to create unordered dependencies by passing
`{unordered: true}`. An unordered dependency is the exact opposite
of a weak dependency. If A has an unordered dependency on B, then
including A forces B to be included as well, but doesn't require B
to load before A. This is occasionally useful for resolving circular
dependencies.
* The build system also supports package implication. If package A
implies package B, then it means that when someone depends on
package A, it's as if they also depended on package B as well. In
particular, they get B's exports. This is done with `api.imply` and
can be used to create umbrella packages such as
`standard-app-packages` that are a shortcut for pulling in a set of
packages, or it can be helpful in factoring common code out of a set
of packages as with `accounts-base`.
* The build system understands the idea of native code and has a
system of architecture names to ensure that packages that are
specific to one architecture aren't run on the wrong
architecture. For example, if you include an npm module that has a
native extension, your built Meteor package will be specific to your
machine architecture, but if not your built Meteor package will be
portable.
{{/better_markdown}}