Merge branch 'release-0.8.0' into devel

Conflicts:
	History.md
This commit is contained in:
Avital Oliver
2014-03-26 20:55:34 -07:00
15 changed files with 235 additions and 186 deletions

View File

@@ -17,6 +17,7 @@ GITHUB: OyoKooN <nathan@sxnlabs.com>
GITHUB: RobertLowe <robert@iblargz.com>
GITHUB: ansman <nicklas@ansman.se>
GITHUB: awwx <andrew.wilcox@gmail.com>
GITHUB: cmather <mather.chris@gmail.com>
GITHUB: codeinthehole <david.winterbottom@gmail.com>
GITHUB: dandv <ddascalescu+github@gmail.com>
GITHUB: emgee3 <hello@gravitronic.com>
@@ -24,6 +25,7 @@ GITHUB: icellan <icellan@icellan.com>
GITHUB: jacott <geoffjacobsen@gmail.com>
GITHUB: jfhamlin <jfhamlin@gmail.com>
GITHUB: marcandre <github@marc-andre.ca>
GITHUB: mart-jansink <m.jansink@gmail.com>
GITHUB: meawoppl <meawoppl@gmail.com>
GITHUB: michaelbishop <michael@michaelsplace.net>
GITHUB: mitar <mitar.git@tnode.com>

View File

@@ -8,7 +8,78 @@
## v0.8.0
(Currently being stabilized. Features Blaze.)
Meteor 0.8.0 introduces Blaze, a total rewrite of our live templating engine,
replacing Spark. Advantages of Blaze include:
* Better interoperability with jQuery plugins and other techniques which
directly manipulate the DOM
* More fine-grained updates: only the specific elements or attributes that
change are touched rather than the entire template
* A fully documented templating language
* No need for the confusing `{{#constant}}`, `{{#isolate}}`, and `preserve`
directives
* Uses standard jQuery delegation (`.on`) instead of our custom implementation
* Blaze supports live SVG templates that work just like HTML templates
See
[the Using Blaze wiki page](https://github.com/meteor/meteor/wiki/Using-Blaze)
for full details on upgrading your app to 0.8.0. This includes:
* The `Template.foo.rendered` callback is now only called once when the template
is rendered, rather than repeatedly as it is "re-rendered", because templates
now directly update changed data instead of fully re-rendering.
* The `accounts-ui` login buttons are now invoked as a `{{> loginButtons}}`
rather than as `{{loginButtons}}`.
* Previous versions of Meteor used a heavily modified version of the Handlebars
templating language. In 0.8.0, we've given it its own name: Spacebars!
Spacebars has an
[explicit specification](https://github.com/meteor/meteor/blob/devel/packages/spacebars/README.md)
instead of being defined as a series of changes to Handlebars. There are some
incompatibilities with our previous Handlebars fork, such as a
[different way of specifying dynamic element attributes](https://github.com/meteor/meteor/blob/devel/packages/spacebars/README.md#in-attribute-values)
and a
[new way of defining custom block helpers](https://github.com/meteor/meteor/blob/devel/packages/spacebars/README.md#custom-block-helpers).
* Your template files must consist of
[well-formed HTML](https://github.com/meteor/meteor/blob/devel/packages/spacebars/README.md#html-dialect). Invalid
HTML is now a compilation failure. (There is a current limitation in our HTML
parser such that it does not support
[omitting end tags](http://www.w3.org/TR/html5/syntax.html#syntax-tag-omission)
on elements such as `<P>` and `<LI>`.)
* `Template.foo` is no longer a function. It is instead a
"component". Components render to an intermediate representation of an HTML
tree, not a string, so there is no longer an easy way to render a component to
a static HTML string.
* `Meteor.render` and `Spark.render` have been removed. Use `UI.render` and
`UI.insert` instead.
* The `<body>` tag now defines a template just like the `<template>` tag, which
can have helpers and event handlers. Define them directly on the object
`UI.body`.
* Previous versions of Meteor shipped with a synthesized `tap` event,
implementing a zero-delay click event on mobile browsers. Unfortunately, this
event never worked very well. We're eliminating it. Instead, use one of the
excellent third party solutions.
* The `madewith` package (which supported adding a badge to your website
displaying its score from http://madewith.meteor.com/) has been removed, as it
is not compatible with the new version of that site.
* The internal `spark`, `liverange`, `universal-events`, and `domutils` packages
have been removed.
* The `preserve-inputs` package is no longer necessary and has been removed.
* The `Handlebars` namespace has been deprecated. `Handlebars.SafeString` is
now `Spacebars.SafeString`, and `Handlebars.registerHelper` is now
`UI.registerHelper`.
Patches contributed by GitHub users cmather and mart-jansink.
## v0.7.2

View File

@@ -455,7 +455,7 @@ the server. The return value is an object with the following fields:
Instead of using callbacks to notify you on changes, this is
a [reactive](#reactivity) data source. You can use it in a
[template](#templates) or [computation](#deps_autorun)
[template](#livehtmltemplates) or [computation](#deps_autorun)
to get realtime updates.
{{> api_box reconnect}}
@@ -2195,11 +2195,20 @@ This returns an "instantiated component" object, which can be passed to
will be invoked. The component will continue to be updated reactively as the
data used changes.
{{#note}}
{{#warning}}
Future releases will provide a richer API for "instantiated components"
(probably unifying them with "template instances"). For now, all you can
do with them is pass them to `UI.insert`.
{{/note}}
Most users will not need to manually render components or manually insert them
into the DOM at all. As of 0.8.0, if you call `UI.render` and never insert
the result into the DOM, the logic to keep the instantiated component updated
will continue running in your browser forever. Additionally, if you remove any
part of your DOM using any mechanism other than jQuery, the logic to keep that
part of the the DOM updated will continue running. To avoid these issues,
either avoid directly updating the DOM and ensure that any removals go through
jQuery.
{{/warning}}
{{> api_box ui_renderwithdata}}
@@ -2610,15 +2619,6 @@ same flush until there is no more work to be done. Callbacks
registered with [`Deps.afterFlush`](#deps_afterflush) are called
after processing outstanding invalidations.
Any auto-updating DOM elements that are found to not be in the
document during a flush may be cleaned up by Meteor (meaning that
Meteor will stop tracking and updating the elements, so that the
browser's garbage collector can delete them). So, if you manually
call `flush`, you need to make sure that any auto-updating elements
that you have manually created by calling [`UI.render`](#ui_render)
have already been inserted in the main DOM tree with
[`UI.insert`](#ui_insert).
It is illegal to call `flush` from inside a `flush` or from a running
computation.

View File

@@ -11,8 +11,7 @@ when writing those apps.
{{> structure }}
{{> data }}
{{> reactivity }}
{{> livehtml }}
{{> templates }}
{{> livehtmltemplates }}
{{> packages_concept }}
{{> namespacing }}
{{> deploying }}
@@ -139,7 +138,7 @@ 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.
See the [templates](#livehtmltemplates) 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
@@ -387,9 +386,9 @@ error-prone logic.
These Meteor functions run your code as a reactive computation:
* [Templates](#templates)
* [Templates](#livehtmltemplates)
* [`Deps.autorun`](#deps_autorun)
* `UI.render` and `UI.renderWithData`
* [`UI.render`](#ui_render) and [`UI.renderWithData`](#ui_renderwithdata)
And the reactive data sources that can trigger changes are:
@@ -417,147 +416,95 @@ You can use it yourself to implement new reactive data sources.
{{/markdown}}
</template>
<template name="livehtml">
<template name="livehtmltemplates">
{{#markdown}}
<h2 id="livehtml">Live HTML</h2>
<h2 id="livehtmltemplates">Live HTML templates</h2>
HTML templating is central to web applications. With Blaze, 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:
Meteor makes it easy to use your favorite HTML templating language 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.
var fragment = Meteor.render(
function () {
var name = Session.get("name") || "Anonymous";
return "<div>Hello, " + name + "</div>";
});
document.body.appendChild(fragment);
Meteor ships with a templating language called
[Spacebars](https://github.com/meteor/meteor/blob/devel/packages/spacebars/README.md),
inspired by [Handlebars](http://handlebarsjs.com/). It shares some of the
spirit and syntax of Handlebars, but it has been tailored to produce reactive
Meteor templates when compiled.
Session.set("name", "Bob"); // page updates automatically!
{{#note}}
Today, the only templating system that ships with Meteor is Spacebars, though
our community has created packages for other languages such as
[Jade](https://atmospherejs.com/package/jade).
{{/note}}
[`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
&mdash; 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 &mdash; 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.
{{/markdown}}
</template>
<template name="templates">
{{#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`
To define templates, 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.
available as 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>
{{lt}}/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
When you app is loaded, it automatically renders the special template called
`<body>`, which is written using the `<body>` element instead of a
`<template>`. You insert a template inside another template by using the
`{{dstache}}> inclusion}}` operator.
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.`*templateName* object. Putting it all together:
<!-- in myapp.html -->
<body>
<h1>Today's weather!</h1>
{{dstache}}> forecast}}
</body>
<template name="forecast">
<div>It'll be {{dstache}}prediction}} tonight</div>
{{lt}}/template>
// in client/myapp.js: reactive helper function
Template.forecast.prediction = function () {
return Session.get("weather");
};
// in the JavaScript console
> Session.set("weather", "cloudy");
> document.body.innerHTML
=> "<h1>Today's weather!</h1> <div>It'll be cloudy tonight</div>"
> Session.set("weather", "cool and dry");
> document.body.innerHTML
=> "<h1>Today's weather!</h1> <div>It'll be cool and dry tonight</div>"
To iterate over an array or database cursor, use `{{dstache}}#each}}`:
<!-- in myapp.html -->
<template name="players">
{{dstache}}#each topScorers}}
<div>{{dstache}}name}}</div>
{{dstache}}/each}}
{{lt}}/template>
instead of passing in `topScorers` as data when we call the
template function, we could define a function on `Template.players`:
// in myapp.js
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
database cursor is passed to `{{dstache}}#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 context data
in `this`. Note that some block helpers change the current context (notably
`each` and `with`):
`{{dstache}}#each}}` and `{{dstache}}#with}}`):
// in a JavaScript file
Template.players.leagueIs = function (league) {
@@ -576,14 +523,6 @@ in `this`. Note that some block helpers change the current context (notably
{{dstache}}/each}}
{{lt}}/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}}
@@ -614,29 +553,8 @@ the data context of the element that triggered the event.
}
});
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>
{{lt}}/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>
For more details about Spacebars, read [the Spacebars
README](https://github.com/meteor/meteor/blob/devel/packages/spacebars/README.md).
{{/markdown}}
</template>

View File

@@ -101,8 +101,7 @@ var toc = [
"Structuring your app",
"Data and security",
"Reactivity",
"Live HTML",
"Templates",
"Live HTML templates",
"Using packages",
"Namespacing",
"Deploying",

View File

@@ -1 +0,0 @@
.build*

View File

@@ -1 +0,0 @@
console.log("The 'preserve-inputs' package is now unnecessary and deprecated.");

View File

@@ -1,8 +0,0 @@
Package.describe({
summary: "Deprecated package (now empty)",
internal: true
});
Package.on_use(function (api) {
api.add_files('deprecated.js', 'server');
});

View File

@@ -7,18 +7,20 @@ Spacebars is a Meteor template language inspired by [Handlebars](http://handleba
A Spacebars template consists of HTML interspersed with template tags, which are delimited by `{{` and `}}` (two curly braces).
```
<h1>{{pageTitle}}</h1>
<template name="myPage">
<h1>{{pageTitle}}</h1>
{{> nav}}
{{> nav}}
{{#each posts}}
<div class="post">
<h3>{{title}}</h3>
<div class="post-content">
{{{content}}}
{{#each posts}}
<div class="post">
<h3>{{title}}</h3>
<div class="post-content">
{{{content}}}
</div>
</div>
</div>
{{/each}}
{{/each}}
</template>
```
As illustrated by the above example, there are four major types of template tags:
@@ -356,3 +358,24 @@ or equivalently `<br/>`.
The HTML spec allows omitting some additional end tags, such as P and
LI, but Spacebars doesn't currently support this.
## Top-level Elements in a `.html` file
Technically speaking, the `<template>` element is not part of the Spacebars
language. A `foo.html` template file in Meteor consists of one or more of the
following elements:
* `<template name="myName">` - The `<template>` element contains a Spacebars
template (as defined in the rest of this file) which will be compiled to the
`Template.myName` component.
* `<head>` - Static HTML that will be inserted into the `<head>` element of the
default HTML boilerplate page. Cannot contain template tags. If `<head>` is
used multiple times (perhaps in different files), the contents of all of the
`<head>` elements are concatenated.
* `<body>` - A template that will be inserted into the `<body>` of the main
page. It will be compiled to the `UI.body` component. If `<body>` is used
multiple times (perhaps in different files), the contents of all of the
`<body>` elements are concatenated.

View File

@@ -1,5 +1,5 @@
<template name="stylus_test_presence">
<p class="less-dashy-left-border"></p>
<p class="stylus-dashy-left-border"></p>
</template>
<template name="stylus_test_import">

View File

@@ -1,5 +1,7 @@
=> Meteor 0.7.2: Support limit queries in the oplog tailing driver. Add
hooks to customize the login process.
=> Meteor 0.8.0: Introducing Blaze, Meteor's new live templating engine!
Better integration with jQuery plugins, fine-grained updates,
reactive SVG support, and more!
https://github.com/meteor/meteor/wiki/Using-Blaze
This release is being downloaded in the background. Update your
project to Meteor 0.7.2 by running 'meteor update'.
project to Meteor 0.8.0 by running 'meteor update'.

View File

@@ -248,11 +248,28 @@ var main = function () {
_.each(notices, function (record) {
if (!record.release)
die("An element of notices.json lacks a release.");
_.each(record.notices, function (line) {
if (line.length + record.release.length + 2 > 80) {
die("notices.json: notice line too long: " + line);
var checkNotices = function (lines) {
if (!(lines instanceof Array)) {
die("notices.json: notice not array");
}
});
_.each(lines, function (line) {
if (line.length + record.release.length + 2 > 80) {
die("notices.json: notice line too long: " + line);
}
});
};
if (record.notices) {
checkNotices(record.notices);
}
if (record.packageNotices) {
_.each(record.packageNotices, function (lines, pkg) {
checkNotices(lines);
});
}
});
var bannerFilename = path.resolve(__dirname, 'banner.txt');

View File

@@ -46,7 +46,7 @@ cat > "$OUTDIR/release.json-$PLATFORM" <<ENDOFMANIFEST
"packages": {
$MANIFEST_PACKAGE_CHUNK
},
"upgraders": ["app-packages"]
"upgraders": ["app-packages", "no-preserve-inputs"]
}
ENDOFMANIFEST

View File

@@ -94,6 +94,23 @@
{
"release": "0.7.2"
},
{
"release": "0.8.0",
"notices": [
"Meteor has a new live templating engine: Blaze!",
"See https://github.com/meteor/meteor/wiki/Using-Blaze for what's new."
],
"packageNotices": {
"accounts-ui": ["Include login buttons with {{> loginButtons}}, not {{loginButtons}}."],
"spark": ["The spark package has been removed."],
"domutils": ["The domutils package has been removed."],
"universal-events": ["The universal-events package has been removed.",
"Use jQuery event delegation instead."],
"liverange": ["The liverange package has been removed."],
"madewith": ["The madewith package has been removed.",
"http://madewith.meteor.com/ no longer supports app badges."]
}
},
{
"release": "NEXT"
}

View File

@@ -55,9 +55,19 @@ var addAppPackagesAndStandardAppPackages = function (appDir) {
});
};
// In Meteor 0.8.0, preserve-inputs became a no-op, because Blaze doesn't
// require manual preserve directives any more. We print a deprecation message
// on apps that use it, but it's part of the default app skeleton, and we don't
// want literally every user to have to type the same "meteor remove
// preserve-inputs" command. So we do it for them.
var noPreserveInputs = function (appDir) {
project.removePackage(appDir, 'preserve-inputs');
};
var upgradersByName = {
"app-packages": addAppPackagesAndStandardAppPackages
"app-packages": addAppPackagesAndStandardAppPackages,
"no-preserve-inputs": noPreserveInputs
};
exports.runUpgrader = function (upgraderName, appDir) {