mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
- Data streamed from the server is quiesced on a per-object basis, not a global
basis. We track which documents a method stubs modifies, and create individual
snapshots ("server documents") of those documents rather than whole-Collection
snapshots. Data writes from the server to documents not modified by stubs are
applied immediately to the local cache; other writes are applied to the
"server document" snapshots. Server documents are flushed to the local cache
when all method stubs that wrote to the document have sent their "data write"
message. (We still do "full database" quiescence after a reconnect.)
- Instead of calling method callbacks as soon as the result is received, we wait
until all data that precedes their "data done" message is flushed to the local
cache. This way, method callbacks can see all of their results locally. (This
applies to Collection mutator callbacks as well.) If this delay is
unacceptable, you can also specify the onResultReceived option to
Meteor.apply; this callback is given the method result as soon as it comes in,
and there's no guarantee that the local cache is up to date.
(This is a client-only change: server-side callbacks do not block on the
write fence.)
- Methods invoked with the "wait" option to Meteor.apply now wait until all
preceding methods are fully finished to be *sent*, not just to call their
callbacks. ie, previous calls block the "wait" method in the same way that
"wait" methods block subsequent calls.
- Remove Meteor.userLoaded and {{currentUserLoaded}}.
Meteor.userId() is now set only at the point where Meteor.user() is fully
loaded.
Current user data is published via an unnamed subscription, not via
"meteor.currentUser".
Replace them with Meteor.loggingIn() and {{loggingIn}}, which become true
as soon as the login method is sent (instead of only once it succeeds).
In accounts-ui, move the spinny into the dropdown, because it now shows up
before error messages would.
- Previously, if we received the "result" message from a method but no "data"
message, and then disconnected and reconnected, quiescence would be
permanently blocked. Now, not only do we allow the app to continue working,
but we even guarantee that the method's callback will be called at the
"reconnect quiescence" point.
- Remove reset function from the Store API (the interface between
_LivedataConnection and Collection), and add a boolean "reset" argument to
beginUpdate instead.
Add saveOriginals/retrieveOriginals functions to the Store API (pass-through
to minimongo implementation).
Allow "replace" messages to be passed to the Store API's update function
(in addition to set/unset).
Allow Store API implementations (eg tinytest_client) to not specify all
functions.
- Server-side tinytest results now stream into the result page instead of
appearing all at once at the end.
- Rename fields and methods of Meteor._LivedataConnection as camelCase, and
prepend all internal fields with _.
- Different Meteor._LivedataConnection objects now have separate
_userIdListeners _ContextSets.
- Remove snapshot/restore functionality from Minimongo collections. (Individual
queries still have result snapshots.) The "server documents" in
Meteor._LivedataConnection serve the equivalent purpose.
- Meteor.loginWithToken's callback is now a "call with error on error, call
with no args on success" callback like the other login callbacks.
- The test-only Meteor._LivedataConnection.onQuiesce function is removed.
Every single use of it is now supported by normal method callbacks.
646 lines
25 KiB
HTML
646 lines
25 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` and
|
|
`isServer`](#meteor_isclient) 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, 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.
|
|
|
|
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) {
|
|
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.
|
|
|
|
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, 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}}
|
|
|
|
{{/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.
|
|
|
|
Meteor.autosubscribe(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 `Meteor.autosubscribe`.
|
|
Methods like `Meteor.autosubscribe` establish a "reactive
|
|
context" inside of which data dependencies are tracked, and they are
|
|
prepared to re-run their function argument as necessary. Data
|
|
providers like `Session`, on the other hand, make note of
|
|
the context they are called from and what data was requested, and they
|
|
are prepared to send an invalidation signal when the data changes.
|
|
|
|
This simple pattern (reactive context + 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 in a reactive context:
|
|
|
|
* [Templates](#templates)
|
|
* [`Meteor.render`](#meteor_render) and [`Meteor.renderList`](#meteor_renderlist)
|
|
* [`Meteor.autosubscribe`](#meteor_autosubscribe)
|
|
* [`Meteor.autorun`](#meteor_autorun)
|
|
|
|
And the reactive data sources that can trigger changes are:
|
|
|
|
* [`Session`](#session) variables
|
|
* Database queries on [Collections](#find)
|
|
* [`Meteor.status`](#meteor_status)
|
|
* [`Meteor.user`](#meteor_user)
|
|
* [`Meteor.userId`](#meteor_userid)
|
|
* [`Meteor.loggingIn`](#meteor_loggingin)
|
|
|
|
Meteor's
|
|
[implementation](https://github.com/meteor/meteor/blob/master/packages/deps/deps.js)
|
|
of reactivity is short and sweet, about 50 lines of code. You can hook into it
|
|
yourself to add new reactive contexts or data sources, using the
|
|
[`Meteor.deps`](#meteor_deps) module.
|
|
|
|
{{/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
|
|
[reactive contexts](#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
|
|
[`Meteor.flush`](#meteor_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 on-screen before your code returns to the event loop,
|
|
or before any call you make to [`Meteor.flush`](#meteor_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({_id: 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 run also 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@0.6.9
|
|
{{/warning}}
|
|
|
|
{{/better_markdown}}
|
|
</template>
|