mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
701 lines
28 KiB
HTML
701 lines
28 KiB
HTML
<template name="concepts">
|
|
|
|
<h1 id="concepts">Concepts</h1>
|
|
|
|
We've written our fair share of single-page JavaScript applications by hand.
|
|
Writing an entire application in one language (JavaScript) with one
|
|
data format (JSON) is a real joy. Meteor is everything we wanted
|
|
when writing those apps.
|
|
|
|
{{> structure }}
|
|
{{> data }}
|
|
{{> reactivity }}
|
|
{{> livehtml }}
|
|
{{> templates }}
|
|
{{> packages_concept }}
|
|
{{> deploying }}
|
|
</template>
|
|
|
|
<template name="structure">
|
|
{{#better_markdown}}
|
|
|
|
<h2 id="structuringyourapp">Structuring your application</h2>
|
|
|
|
A Meteor application is a mix of JavaScript that runs inside a client web
|
|
browser, JavaScript that runs on the Meteor server inside a
|
|
[Node.js](http://nodejs.org/) container, and all the supporting HTML fragments,
|
|
CSS rules, and static assets. Meteor automates the packaging and transmission
|
|
of these different components. And, it is quite flexible about how you choose
|
|
to structure those components in your file tree.
|
|
|
|
The only server asset is JavaScript. Meteor gathers all your JavaScript
|
|
files, excluding anything under the `client`
|
|
and `public` subdirectories, and loads them into a Node.js
|
|
server instance inside a fiber. In Meteor, your server code runs in
|
|
a single thread per request, not in the asynchronous callback style
|
|
typical of Node. We find the linear execution model a better fit for
|
|
the typical server code in a Meteor application.
|
|
|
|
There are more assets to consider on the client side. Meteor
|
|
gathers all JavaScript files in your tree with the exception of
|
|
the `server` and `public` subdirectories for the
|
|
client. It minifies this bundle and serves it to each new client.
|
|
You're free to use a single JavaScript file for your entire application, or
|
|
create a nested tree of separate files, or anything in between.
|
|
|
|
Files outside the `client`, `server` and `tests` subdirectories are loaded on
|
|
both the client and the server! That's the place for model definitions and
|
|
other functions. Meteor provides the variables [`isClient`](#meteor_isclient) and
|
|
[`isServer`](#meteor_isserver) so that your code can alter its behavior depending
|
|
on whether it's running on the client or the server. (Files in directories named
|
|
`tests` are not loaded anywhere.)
|
|
|
|
Any sensitive code that you don't want served to the client, such as code
|
|
containing passwords or authentication mechanisms, should be
|
|
kept in the `server` directory.
|
|
|
|
CSS files are gathered together as well: the client will get a bundle with all
|
|
the CSS in your tree (excluding the `server`
|
|
and `public` subdirectories).
|
|
|
|
In development mode, JavaScript and CSS files are sent individually to make
|
|
debugging easier.
|
|
|
|
HTML files in a Meteor application are treated quite a bit differently
|
|
from a server-side framework. Meteor scans all the HTML files in your
|
|
directory for three top-level elements: `<head>`, `<body>`, and
|
|
`<template>`. The head and body sections are separately concatenated
|
|
into a single head and body, which are transmitted to the client on
|
|
initial page load.
|
|
|
|
Template sections, on the other hand, are converted into JavaScript
|
|
functions, available under the `Template` namespace. It's
|
|
a really convenient way to ship HTML templates to the client.
|
|
See the [templates](#templates) section for more.
|
|
|
|
Lastly, the Meteor server will serve any files under the `public`
|
|
directory, just like in a Rails or Django project. This is the place
|
|
for images, `favicon.ico`, `robots.txt`, and anything else.
|
|
|
|
It is best to write your application in such a way that it is
|
|
insensitive to the order in which files are loaded, for example by
|
|
using [Meteor.startup](#meteor_startup), or by moving load order
|
|
sensitive code into [Smart Packages](#smartpackages), which can explicitly control both
|
|
the load order of their contents and their load order with respect to
|
|
other packages. However sometimes load order dependencies in your
|
|
application are unavoidable. The JavaScript and CSS files in an
|
|
application are loaded according to these rules:
|
|
|
|
* Files in the `lib` directory at the root of your application are
|
|
loaded first.
|
|
|
|
* Files that match `main.*` are loaded after everything else.
|
|
|
|
* Files in subdirectories are loaded before files in parent
|
|
directories, so that files in the deepest subdirectory are loaded
|
|
first (after `lib`), and files in the root directory are loaded last
|
|
(other than `main.*`).
|
|
|
|
* Within a directory, files are loaded in alphabetical order by
|
|
filename.
|
|
|
|
These rules stack, so that within `lib`, for example, files are still
|
|
loaded in alphabetical order; and if there are multiple files named
|
|
`main.js`, the ones in subdirectories are loaded earlier.
|
|
|
|
{{/better_markdown}}
|
|
</template>
|
|
|
|
<template name="data">
|
|
{{#better_markdown}}
|
|
|
|
<h2 id="dataandsecurity">Data and security</h2>
|
|
|
|
Meteor makes writing distributed client code as simple as talking to a
|
|
local database. It's a clean, simple, and secure approach that obviates
|
|
the need to implement individual RPC endpoints, manually cache data on
|
|
the client to avoid slow roundtrips to the server, and carefully
|
|
orchestrate invalidation messages to every client as data changes.
|
|
|
|
In Meteor, the client and server share the same database API. The same
|
|
exact application code — like validators and computed properties — can
|
|
often run in both places. But while code running on the server has
|
|
direct access to the database, code running on the client does *not*.
|
|
This distinction is the basis for Meteor's data security model.
|
|
|
|
{{#note}}
|
|
By default, a new Meteor app includes the `autopublish` and `insecure`
|
|
packages, which together mimic the effect of each client having full
|
|
read/write access to the server's database. These are useful
|
|
prototyping tools, but typically not appropriate for production
|
|
applications. When you're ready, just remove the packages.
|
|
{{/note}}
|
|
|
|
Every Meteor client includes an in-memory database cache. To manage the
|
|
client cache, the server *publishes* sets of JSON documents, and the
|
|
client *subscribes* to those sets. As documents in a set change, the
|
|
server patches each client's cache.
|
|
|
|
Today most Meteor apps use MongoDB as their database because it is the
|
|
best supported, though support for other databases is coming in the
|
|
future. The
|
|
[`Meteor.Collection`](http://docs.meteor.com/#meteor_collection) class
|
|
is used to declare Mongo collections and to manipulate them. Thanks to
|
|
`minimongo`, Meteor's client-side Mongo emulator, `Meteor.Collection`
|
|
can be used from both client and server code.
|
|
|
|
// declare collections
|
|
// this code should be included in both the client and the server
|
|
Rooms = new Meteor.Collection("rooms");
|
|
Messages = new Meteor.Collection("messages");
|
|
Parties = new Meteor.Collection("parties");
|
|
|
|
// server: populate collections with some initial documents
|
|
Rooms.insert({name: "Conference Room A"});
|
|
var myRooms = Rooms.find({}).fetch();
|
|
Messages.insert({text: "Hello world", room: myRooms[0]._id});
|
|
Parties.insert({name: "Super Bowl Party"});
|
|
|
|
Each document set is defined by a publish function on the server. The
|
|
publish function runs each time a new client subscribes to a document
|
|
set. The data in a document set can come from anywhere, but the common
|
|
case is to publish a database query.
|
|
|
|
// server: publish all room documents
|
|
Meteor.publish("all-rooms", function () {
|
|
return Rooms.find(); // everything
|
|
});
|
|
|
|
// server: publish all messages for a given room
|
|
Meteor.publish("messages", function (roomId) {
|
|
check(roomId, String);
|
|
return Messages.find({room: roomId});
|
|
});
|
|
|
|
// server: publish the set of parties the logged-in user can see.
|
|
Meteor.publish("parties", function () {
|
|
return Parties.find({$or: [{"public": true},
|
|
{invited: this.userId},
|
|
{owner: this.userId}]});
|
|
});
|
|
|
|
Publish functions can provide different results to each client. In the
|
|
last example, a logged in user can only see `Party` documents that
|
|
are public, that the user owns, or that the user has been invited to.
|
|
|
|
Once subscribed, the client uses its cache as a fast local database,
|
|
dramatically simplifying client code. Reads never require a costly
|
|
round trip to the server. And they're limited to the contents of the
|
|
cache: a query for every document in a collection on a client will only
|
|
return documents the server is publishing to that client.
|
|
|
|
// client: start a parties subscription
|
|
Meteor.subscribe("parties");
|
|
|
|
// client: return array of Parties this client can read
|
|
return Parties.find().fetch(); // synchronous!
|
|
|
|
Sophisticated clients can turn subscriptions on and off to control how
|
|
much data is kept in the cache and manage network traffic. When a
|
|
subscription is turned off, all its documents are removed from the cache
|
|
unless the same document is also provided by another active
|
|
subscription.
|
|
|
|
When the client *changes* one or more documents, it sends a message to
|
|
the server requesting the change. The server checks the proposed change
|
|
against a set of allow/deny rules you write as JavaScript functions.
|
|
The server only accepts the change if all the rules pass.
|
|
|
|
// server: don't allow client to insert a party
|
|
Parties.allow({
|
|
insert: function (userId, party) {
|
|
return false;
|
|
}
|
|
});
|
|
|
|
// client: this will fail
|
|
var party = { ... };
|
|
Parties.insert(party);
|
|
|
|
If the server accepts the change, it applies the change to the database
|
|
and automatically propagates the change to other clients subscribed to
|
|
the affected documents. If not, the update fails, the server's database
|
|
remains untouched, and no other client sees the update.
|
|
|
|
Meteor has a cute trick, though. When a client issues a write to the
|
|
server, it also updates its local cache immediately, without waiting for
|
|
the server's response. This means the screen will redraw right away.
|
|
If the server accepted the update — what ought to happen most of the
|
|
time in a properly behaving client — then the client got a jump on the
|
|
change and didn't have to wait for the round trip to update its own
|
|
screen. If the server rejects the change, Meteor patches up the
|
|
client's cache with the server's result.
|
|
|
|
Putting it all together, these techniques accomplish latency
|
|
compensation. Clients hold a fresh copy of the data they need, and
|
|
never need to wait for a roundtrip to the server. And when clients
|
|
modify data, those modifications can run locally without waiting for the
|
|
confirmation from the server, while still giving the server final say
|
|
over the requested change.
|
|
|
|
<h3 id="dataandsecurity-authentication">Authentication and user accounts</h3>
|
|
|
|
Meteor includes [Meteor Accounts](#accounts_api), a state-of-the-art
|
|
authentication system. It features secure password login using the
|
|
[Secure Remote Password
|
|
protocol](http://en.wikipedia.org/wiki/Secure_Remote_Password_protocol),
|
|
and integration with external services including Facebook, GitHub,
|
|
Google, Meetup, Twitter, and Weibo. Meteor Accounts defines a
|
|
[`Meteor.users`](#meteor_users) collection where developers can store
|
|
application-specific user data.
|
|
|
|
Meteor also includes pre-built forms for common tasks like login, signup,
|
|
password change, and password reset emails. You can add [Accounts
|
|
UI](#accountsui) to your app with just one line of code. The `accounts-ui` smart
|
|
package even provides a configuration wizard that walks you through the steps to
|
|
set up the external login services you're using in your app.
|
|
|
|
{{#note}}
|
|
The current release of Meteor supports MongoDB, the popular document
|
|
database, and the examples in this section use the
|
|
[MongoDB API](http://www.mongodb.org/display/DOCS/Manual). Future
|
|
releases will include support for other databases.
|
|
{{/note}}
|
|
|
|
|
|
<h3 id="dataandsecurity-validation">Input validation</h3>
|
|
|
|
Meteor allows your methods and publish functions to take arguments of any
|
|
[JSON](http://json.org/) type. (In fact, Meteor's wire protocol supports
|
|
[EJSON](#ejson), an extension of JSON which also supports other common types
|
|
like dates and binary buffers.) JavaScript's dynamic typing means you don't need
|
|
to declare precise types of every variable in your app, but it's usually helpful
|
|
to ensure that the arguments that clients are passing to your methods and
|
|
publish functions are of the type that you expect.
|
|
|
|
Meteor provides a [lightweight library](#match) for checking that arguments and
|
|
other values are the type you expect them to be. Simply start your functions
|
|
with statements like `check(username, String)` or
|
|
`check(office, {building: String, room: Number})`. The `check` call will
|
|
throw an error if its argument is of an unexpected type.
|
|
|
|
Meteor also provides an easy way to make sure that all of your methods
|
|
and publish functions validate all of their arguments. Just run
|
|
<code>meteor add [audit-argument-checks](#auditargumentchecks)</code> and any
|
|
method or publish function which skips `check`ing any of its arguments will fail
|
|
with an exception.
|
|
|
|
{{/better_markdown}}
|
|
</template>
|
|
|
|
<template name="reactivity">
|
|
{{#better_markdown}}
|
|
|
|
<h2 id="reactivity">Reactivity</h2>
|
|
|
|
Meteor embraces the concept of [reactive
|
|
programming](http://en.wikipedia.org/wiki/Reactive_programming). This means that
|
|
you can write your code in a simple imperative style, and the result will be
|
|
automatically recalculated whenever data changes that your code depends on.
|
|
|
|
Deps.autorun(function () {
|
|
Meteor.subscribe("messages", Session.get("currentRoomId"));
|
|
});
|
|
|
|
This example (taken from a chat room client) sets up a data
|
|
subscription based on the session variable `currentRoomId`.
|
|
If the value of `Session.get("currentRoomId")` changes for any reason, the
|
|
function will be automatically re-run, setting up a new subscription that
|
|
replaces the old one.
|
|
|
|
This automatic recomputation is achieved by a cooperation between
|
|
`Session` and `Deps.autorun`. `Deps.autorun` performs an arbitrary "reactive
|
|
computation" inside of which data dependencies are tracked, and it
|
|
will re-run its function argument as necessary. Data providers like
|
|
`Session`, on the other hand, make note of the computation they are
|
|
called from and what data was requested, and they are prepared to send
|
|
an invalidation signal to the computation when the data changes.
|
|
|
|
This simple pattern (reactive computation + reactive data source) has wide
|
|
applicability. Above, the programmer is saved from writing
|
|
unsubscribe/resubscribe calls and making sure they are called at the
|
|
right time. In general, Meteor can eliminate whole classes of data
|
|
propagation code which would otherwise clog up your application with
|
|
error-prone logic.
|
|
|
|
These Meteor functions run your code as a reactive computation:
|
|
|
|
* [Templates](#templates)
|
|
* [`Meteor.render`](#meteor_render) and [`Meteor.renderList`](#meteor_renderlist)
|
|
* [`Deps.autorun`](#deps_autorun)
|
|
|
|
And the reactive data sources that can trigger changes are:
|
|
|
|
* [`Session`](#session) variables
|
|
* Database queries on [Collections](#find)
|
|
* [`Meteor.status`](#meteor_status)
|
|
* The `ready()` method on a [subscription handle](#meteor_subscribe)
|
|
* [`Meteor.user`](#meteor_user)
|
|
* [`Meteor.userId`](#meteor_userid)
|
|
* [`Meteor.loggingIn`](#meteor_loggingin)
|
|
|
|
In addition, the following functions which return an object with a
|
|
`stop` method, if called from a reactive computation, are stopped when
|
|
the computation is rerun or stopped:
|
|
|
|
* [`Deps.autorun`](#deps_autorun) (nested)
|
|
* [`Meteor.subscribe`](#meteor_subscribe)
|
|
* [`observe()`](#observe) and [`observeChanges()`](#observe_changes) on cursors
|
|
|
|
Meteor's
|
|
[implementation](https://github.com/meteor/meteor/blob/master/packages/deps/deps.js)
|
|
is a package called [`Deps`](#deps) that is fairly short and straightforward.
|
|
You can use it yourself to implement new reactive data sources.
|
|
|
|
{{/better_markdown}}
|
|
</template>
|
|
|
|
<template name="livehtml">
|
|
{{#better_markdown}}
|
|
|
|
<h2 id="livehtml">Live HTML</h2>
|
|
|
|
HTML templating is central to web applications. With Meteor's live
|
|
page update technology, you can render your HTML _reactively_, meaning
|
|
that it will update automatically to track changes in the data used to
|
|
generate it.
|
|
|
|
This optional feature works with any HTML templating library, or even
|
|
with HTML you generate manually from JavaScript. Here's an example:
|
|
|
|
var fragment = Meteor.render(
|
|
function () {
|
|
var name = Session.get("name") || "Anonymous";
|
|
return "<div>Hello, " + name + "</div>";
|
|
});
|
|
document.body.appendChild(fragment);
|
|
|
|
Session.set("name", "Bob"); // page updates automatically!
|
|
|
|
[`Meteor.render`](#meteor_render) takes a rendering function, that is, a
|
|
function that returns some HTML as a string. It returns an auto-updating
|
|
`DocumentFragment`. When there is a change to data used by the rendering
|
|
function, it is re-run. The DOM nodes in the `DocumentFragment` then
|
|
update themselves in-place, no matter where they were inserted on the
|
|
page. It's completely automatic. [`Meteor.render`](#meteor_render) uses
|
|
a [reactive computation](#reactivity) to discover what data is used by the
|
|
rendering function.
|
|
|
|
Most of the time, though, you won't call these functions directly
|
|
— you'll just use your favorite templating package, such as
|
|
Handlebars or Jade. The `render` and `renderList` functions are intended
|
|
for people that are implementing new templating systems.
|
|
|
|
Meteor normally batches up any needed updates and executes them only
|
|
when your code isn't running. That way, you can be sure that the DOM
|
|
won't change out from underneath you. Sometimes you want the opposite
|
|
behavior. For example, if you've just inserted a record in the
|
|
database, you might want to force the DOM to update so you can find
|
|
the new elements using a library like jQuery. In that case, call
|
|
[`Deps.flush`](#deps_flush) to bring the DOM up to date
|
|
immediately.
|
|
|
|
When live-updating DOM elements are taken off the screen, they are automatically
|
|
cleaned up — their callbacks are torn down, any associated database
|
|
queries are stopped, and they stop updating. For this reason, you never have to
|
|
worry about the [zombie
|
|
templates](http://lostechies.com/derickbailey/2011/09/15/zombies-run-managing-page-transitions-in-backbone-apps/)
|
|
that plague hand-written update logic. To protect your elements from cleanup,
|
|
just make sure that they are on-screen before your code returns to the event loop,
|
|
or before any call you make to [`Deps.flush`](#deps_flush).
|
|
|
|
Another thorny problem in hand-written applications is element
|
|
preservation. Suppose the user is typing text into an `<input>`
|
|
element, and then the area of the page that includes that element is
|
|
redrawn. The user could be in for a bumpy ride, as the focus, the
|
|
cursor position, the partially entered text, and the accented
|
|
character input state will be lost when the `<input>` is recreated.
|
|
|
|
This is another problem that Meteor solves for you. You can specify
|
|
elements to preserve when templates are re-rendered with the
|
|
[`preserve`](#template_preserve) directive on the template. Meteor will
|
|
preserve these elements even when their enclosing template is
|
|
rerendered, but will still update their children and copy over any
|
|
attribute changes.
|
|
|
|
{{/better_markdown}}
|
|
</template>
|
|
|
|
<template name="templates">
|
|
{{#better_markdown}}
|
|
|
|
<h2 id="templates">Templates</h2>
|
|
|
|
Meteor makes it easy to use your favorite HTML templating language,
|
|
such as Handlebars or Jade, along with Meteor's live page update
|
|
technology. Just write your template as you normally would, and Meteor
|
|
will take care of making it update in realtime.
|
|
|
|
To use this feature, create a file in your project with the `.html`
|
|
extension. In the file, make a `<template>` tag and give it a
|
|
`name` attribute. Put the template contents inside the tag. Meteor
|
|
will precompile the template, ship it down to the client, and make it
|
|
available as a function on the global `Template` object.
|
|
|
|
{{#note}}
|
|
Today, the only templating system that has been packaged for Meteor is
|
|
Handlebars. Let us know what templating systems you'd like to use with
|
|
Meteor. Meanwhile, see the [Handlebars
|
|
documentation](http://www.handlebarsjs.com/) and [Meteor Handlebars
|
|
extensions](https://github.com/meteor/meteor/wiki/Handlebars).
|
|
{{/note}}
|
|
|
|
A template with a `name` of `hello` is rendered by calling the
|
|
function `Template.hello`, passing any data for the template:
|
|
|
|
<!-- in myapp.html -->
|
|
<template name="hello">
|
|
<div class="greeting">Hello there, {{dstache}}first}} {{dstache}}last}}!</div>
|
|
</{{! }}template>
|
|
|
|
// in the JavaScript console
|
|
> Template.hello({first: "Alyssa", last: "Hacker"});
|
|
=> "<div class="greeting">Hello there, Alyssa Hacker!</div>"
|
|
|
|
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:
|
|
|
|
<template name="players">
|
|
{{dstache}}#each topScorers}}
|
|
<div>{{dstache}}name}}</div>
|
|
{{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;
|
|
};
|
|
|
|
<!-- in a HTML file -->
|
|
<template name="players">
|
|
{{dstache}}#each topScorers}}
|
|
{{dstache}}#if leagueIs "junior"}}
|
|
<div>Junior: {{dstache}}name}}</div>
|
|
{{dstache}}/if}}
|
|
{{dstache}}#if leagueIs "senior"}}
|
|
<div>Senior: {{dstache}}name}}</div>
|
|
{{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.
|
|
|
|
<!-- myapp.html -->
|
|
<template name="scores">
|
|
{{dstache}}#each player}}
|
|
{{dstache}}> playerScore}}
|
|
{{dstache}}/each}}
|
|
</{{! }}template>
|
|
|
|
<template name="playerScore">
|
|
<div>{{dstache}}name}}: {{dstache}}score}}
|
|
<span class="givePoints">Give points</span>
|
|
</div>
|
|
</{{! }}template>
|
|
|
|
<!-- myapp.js -->
|
|
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.
|
|
|
|
<!-- in myapp.html -->
|
|
<template name="forecast">
|
|
<div>It'll be {{dstache}}prediction}} tonight</div>
|
|
</{{! }}template>
|
|
|
|
<!-- in myapp.js -->
|
|
// JavaScript: reactive helper function
|
|
Template.forecast.prediction = function () {
|
|
return Session.get("weather");
|
|
};
|
|
|
|
<!-- in the console -->
|
|
> Session.set("weather", "cloudy");
|
|
> document.body.appendChild(Meteor.render(Template.forecast));
|
|
In DOM: <div>It'll be cloudy tonight</div>
|
|
|
|
> Session.set("weather", "cool and dry");
|
|
In DOM: <div>It'll be cool and dry tonight</div>
|
|
|
|
{{/better_markdown}}
|
|
</template>
|
|
|
|
<template name="packages_concept">
|
|
{{#better_markdown}}
|
|
|
|
<h2 id="smartpackages">Smart packages</h2>
|
|
|
|
Meteor has an unusually powerful package system. All of the
|
|
functionality you've read about so far is implemented as standard
|
|
Meteor packages.
|
|
|
|
Meteor packages are intelligent: the packages are themselves
|
|
JavaScript programs. They can inject code into the client or the
|
|
server, or hook new functions into the bundler, so they can extend the
|
|
Meteor environment in arbitrary ways. Some examples of packages are:
|
|
|
|
* The [coffeescript](#coffeescript) package extends the
|
|
bundler, automatically compiling any `.coffee` files in
|
|
your tree. Once added, you can write your application in CoffeeScript
|
|
instead of JavaScript.
|
|
|
|
* The [jQuery](#jquery) and [Backbone](#backbone) packages are examples of using
|
|
Meteor to prepackage client JavaScript libraries. You could get
|
|
the same result by copying the JavaScript files into your tree, but
|
|
it's faster to add a package.
|
|
|
|
* The [underscore](#underscore) package extends both the
|
|
client and server environments.
|
|
|
|
Many of the core Meteor features,
|
|
including Minimongo, the Session object, and reactive Handlebars
|
|
templates, are implemented as internal packages automatically
|
|
included with every Meteor application.
|
|
|
|
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).
|
|
|
|
See the [Package List](#packages) section for a description
|
|
of the existing packages.
|
|
|
|
{{#warning}}
|
|
The package API is rapidly changing and isn't documented, so you can't
|
|
make your own packages just yet. Coming soon.
|
|
{{/warning}}
|
|
|
|
{{/better_markdown}}
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<template name="deploying">
|
|
{{#better_markdown}}
|
|
|
|
<h2 id="deploying">Deploying</h2>
|
|
|
|
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.
|
|
|
|
<h3 class="nosection">Running on Meteor's infrastructure</h3>
|
|
|
|
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.
|
|
|
|
<h3 class="nosection">Running on your own infrastructure</h3>
|
|
|
|
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.8 and a MongoDB server. 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/server/node_modules
|
|
$ rm -r fibers
|
|
$ npm install fibers@1.0.0
|
|
{{/warning}}
|
|
|
|
{{/better_markdown}}
|
|
</template>
|