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)