Introduction to Blaze live templating engine and more
## Luca Zulian
### developer
### Summary
1. #### What is **Blaze**
2. #### **Tracker**
3. #### **Spacebars**
4. #### Meteor app structure
5. #### **IronRouter**
### What is **Blaze**
Blaze is a powerful library for creating user interfaces by writing reactive HTML templates
1. #### reactive DOM engine (builds and manages the DOM at runtime)
2. #### template compiler (flagship template syntax is **Spacebars**)
Integrated with Tracker's "transparent reactivity" and Minimongo's database cursors, the DOM updates automatically
### **Tracker**
Meteor Tracker is a library for transparent reactive programming in JavaScript,
it's a simple interface that lets reactive data sources talk to reactive data consumers
Meteor has several types of reactive data sources such as:
1. #### Session object
2. #### Reactive variables
3. #### Minimongo
4. #### Meteor.user(), Meteor.status()
These objects create Tracker dependency objects for you internally (reactivity for free)
### **Spacebars**
Spacebars and [Handlebars](http://handlebarsjs.com/) share the same syntax, but Spacebars brings quite a few Meteor-specific innovations
1. #### Template everywhere
2. #### Creating custom helpers
3. #### Dealing with HTML attributes
### **Handlebars**
Handlebars templates look like regular HTML, with embedded handlebars expressions
```
<div class="entry">
{{!-- this is a comment --}}
<h1>{{title}}</h1>
<div class="body">
{{body}}
</div>
</div>
```
```{{```, some contents, followed by a ```}}```
### **Handlebars**
You can use the ```if``` helper to conditionally render a block
```
<div class="entry">
{{#if author}}
<h1>{{firstName}} {{lastName}}</h1>
{{/if}}
</div>
```
```unless``` helper as the inverse of the ```if``` helper
```
<div class="entry">
{{#unless license}}
<h3 class="warning">WARNING</h3>
{{/unless}}
</div>
```
### **Handlebars**
You can iterate over a list using the built-in ```each``` helper
```
<ul class="people_list">
{{#each people}}
<li>{{this}}</li>
{{/each}}
</ul>
```
```
{{#each paragraphs}}
<p>{{this}}</p>
{{else}}
<p class="empty">No content</p>
{{/each}}
```
### **Handlebars**
You can shift the context for a section by using the built-in ```with``` block helper
```
{
title: "My first post!",
author: {
firstName: "Charles",
lastName: "Jolley"
}
}
```
```
<div class="entry">
<h1>{{title}}</h1>
{{#with author}}
<h2>By {{firstName}} {{lastName}}</h2>
{{/with}}
</div>
```
```
<div class="entry">
<h1>My first post!</h1>
<h2>By Charles Jolley</h2>
</div>
```
### **Spacebars - Template everywhere**
```
<template name="forecast">
{{#if myFirstHelper}}
<h1>Hello world!</h1>
{{/if}}
</template>
```
```
Template.forecast.helpers({
myFirstHelper: function () {
return true;
}
});
```
Nested template
```
<template name="people-template">
{{#each people}}
{{> person}}
{{/each}}
</template>
```
### **Spacebars - Template everywhere**
Register a function to be called when an instance of this template is inserted into the DOM
```
Template.myTemplate.onRendered(function () {
// your content here
});
```
Register a function to be called when an instance of this template is created
```
Template.myTemplate.onCreated(function () {
// your content here
});
```
Register a function to be called when an instance of this template is removed from the DOM and destroyed
```
Template.myTemplate.onDestroyed(function () {
// your content here
});
```
### **Spacebars - Template everywhere**
Find all elements matching selector in this template instance
```
template.findAll(selector)
```
Find all elements matching selector in this template instance, and return them as a JQuery object
```
template.$(selector)
```
### **Spacebars - Template everywhere**
```
<template name="myTemplate">
<button type="button">Click</button>
</template>
```
```
Template.myTemplate.events({
'click button': function (event, template) {
console.log("foo button clicked");
}
});
```
```click```, ```dblclick```, ```focus```, ```blur```, ```change```, ```mouseenter```, ```mouseleave```, ```mousedown```, ```mouseup```, ```keydown```, ```keypress```, ```keyup``` ...
### **Spacebars - Custom helpers**
```
Template.profile.helpers({
createdAtFormatted: function () {
return moment(this.createdAt).format('MM/DD/YYYY, HH:MM');
}
});
```
```
<template name="profile">
<h3>{{name}}</h3>
<h4>{{createdAtFormatted}}</h4>
<p>{{bio}}</p>
</template>
```
### **Spacebars - Custom helpers**
```
Template.registerHelper('formatTime', function(myDate) {
if(myDate) {
return moment(myDate).format('MM/DD/YYYY, hh:mm');
}
});
```
```
<template name="profile">
<h3>{{name}}</h3>
<h4>{{formatTime createdAt}}</h4>
<p>{{bio}}</p>
</template>
```
### **Spacebars - Smarter Attributes**
```
<input type="checkbox" checked="{{isChecked}}" />
```
```
<input {{attributes}} />
```
```
Template.myTemplate.helpers({
attributes: function () {
return {
name: "myName",
class: "myClass anotherClass",
value: 123
}
}
});
```
Spacebars will then automatically map out the object to the tag’s attributes
```
<input name="myName" class="myClass anotherClass" value="123" />
```
### **Meteor app structure**
Basically it's up to you, but Meteor has some standards anyways. 4 main entities
1. #### lib
2. #### client
3. #### server
4. #### public
### **Meteor app structure**
![Alt text](img/meteor_app.png)
### **Iron Router**
A router that works on the server and the browser
```
Router.route('/', function () {
this.render('Home');
});
```
```
Router.route('/items');
```
```
Router.route('/item', function () {
var req = this.request;
var res = this.response;
res.end('hello from the server\n');
}, {where: 'server'});
```
The where: 'server' option tells the Router this is a server side route
# Thanks!
#### Slides
#### http://lucazulian.it/slides/meteorjs-19-03-2015
#### Source Code
#### https://github.com/lucazulian/meteor-todos
### [https://github.com/lucazulian](https://github.com/lucazulian)
### [@luca_julian](https://twitter.com/luca_julian)