Only this pageAll pages
Powered by GitBook
1 of 6

Discover Meteor

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Templates

To ease into Meteor development, we'll adopt an outside-in approach. In other words we'll build a "dumb" HTML/JavaScript outer shell first, and then hook it up to our app's inner workings later on.

This means that in this chapter we'll only concern ourselves with what's happening inside the /client directory.

If you haven't done so already, create a new file named main.html inside our /client directory, and fill it with the following code:

<head>
  <title>Microscope</title>
</head>
<body>
  <div class="container">
    <header class="navbar navbar-default" role="navigation"> 
      <div class="navbar-header">
        <a class="navbar-brand" href="/">Microscope</a>
      </div>
    </header>
    <div id="main">
      {{> postsList}}
    </div>
  </div>
</body>

<%= caption "client/main.html" %>

This will be our main app template. As you can see it's all HTML except for a single {{> postsList}} template inclusion tag, which is an insertion point for the upcoming postsList template. For now, let's create a couple more templates.

Meteor Templates

At its core, a social news site is composed of posts organized in lists, and that's exactly how we'll organize our templates.

Let's create a /templates directory inside /client. This will be where we put all our templates, and to keep things tidy we'll also create /posts inside /templates just for our post-related templates.

<% note do %>

Finding Files

Meteor is great at finding files. No matter where you put your code in the /client directory, Meteor will find it and compile it properly. This means you never need to manually write include paths for JavaScript or CSS files.

It also means you could very well put all your files in the same directory, or even all your code in the same file. But since Meteor will compile everything to a single minified file anyway, we'd rather keep things well-organized and use a cleaner file structure.

<% end %>

We're finally ready to create our second template. Inside client/templates/posts, create posts_list.html:

<template name="postsList">
  <div class="posts">
    {{#each posts}}
      {{> postItem}}
    {{/each}}
  </div>
</template>

<%= caption "client/templates/posts/posts_list.html" %>

And post_item.html:

<template name="postItem">
  <div class="post">
    <div class="post-content">
      <h3><a href="{{url}}">{{title}}</a><span>{{domain}}</span></h3>
    </div>
  </div>
</template>

<%= caption "client/templates/posts/post_item.html" %>

Note the name="postsList" attribute of the template element. This is the name that will be used by Meteor to keep track of what template goes where (note that the name of the actual file is not relevant).

It's time to introduce Meteor's templating system, Spacebars. Spacebars is simply HTML, with the addition of three things: inclusions (also sometimes known as “partials”), expressions and block helpers.

Inclusions use the {{> templateName}} syntax, and simply tell Meteor to replace the inclusion with the template of the same name (in our case postItem).

Expressions such as {{title}} either call a property of the current object, or the return value of a template helper as defined in the current template's manager (more on this later).

Finally, block helpers are special tags that control the flow of the template, such as {{#each}}…{{/each}} or {{#if}}…{{/if}}.

<% note do %>

Going Further

You can refer to the Spacebars documentation if you'd like to learn more about Spacebars.

<% end %>

Armed with this knowledge, we can start to understand what's going on here.

First, in the postsList template, we're iterating over a posts object with the {{#each}}…{{/each}} block helper. Then, for each iteration we're including the postItem template.

Where is this posts object coming from? Good question. It's actually a template helper, and you can think of it as a placeholder for a dynamic value.

The postItem template itself is fairly straightforward. It only uses three expressions: {{url}} and {{title}} both return the document's properties, and {{domain}} calls a template helper.

Template Helpers

Up to now we've been dealing with Spacebars, which is little more than HTML with a few tags sprinkled in. Unlike other languages like PHP (or even regular HTML pages, which can include JavaScript), Meteor keeps templates and their logic separated, and these templates don't do much by themselves.

In order to come to life, a template needs helpers. You can think of these helpers as the cooks that take raw ingredients (your data) and prepare them, before handing out the finished dish (the templates) to the waiter, who then presents it to you.

In other words, while the template's role is limited to displaying or looping over variables, the helpers are the one who actually do the heavy lifting by assigning a value to each variable.

<% note do %>

Controllers?

It might be tempting to think of the file containing all of a template's helpers as a controller of sorts. But that can be ambiguous, as controllers (at least in the MVC sense) usually have a slightly different role.

So we decided to stay away from that terminology, and simply refer to “the template's helpers“ or “the template's logic” when talking about a template's companion JavaScript code.

<% end %>

To keep things simple, we'll adopt the convention of naming the file containing the helpers after the template, but with a .js extension. So let's create posts_list.js inside client/templates/posts right away and start building our first helper:

var postsData = [
  {
    title: 'Introducing Telescope',
    url: 'http://sachagreif.com/introducing-telescope/'
  }, 
  {
    title: 'Meteor',
    url: 'http://meteor.com'
  }, 
  {
    title: 'The Meteor Book',
    url: 'http://themeteorbook.com'
  }
];
Template.postsList.helpers({
  posts: postsData
});

<%= caption "client/templates/posts/posts_list.js" %>

If you've done it right, you should now be seeing something similar to this in your browser:

<%= screenshot "3-1", "Our first templates with static data" %>

We're doing two things here. First we're setting up some dummy prototype data in the postsData array. That data would normally come from the database, but since we haven't seen how to do that yet (wait for the next chapter!) we're “cheating” by using static data.

Second, we're using Meteor's Template.postsList.helpers() function to create a template helper called posts that returns the postsData array we just defined above.

If you remember, we are using that posts helper in our postsList template:

<template name="postsList">
  <div class="posts page">
    {{#each posts}}
      {{> postItem}}
    {{/each}}
  </div>
</template>

<%= caption "client/templates/posts/posts_list.html" %>

Defining the posts helper means it is now available for our template to use, so our template will be able to iterate over our postsData array and pass each object contained within to the postItem template.

<%= commit "3-1", "Added basic posts list template and static data." %>

The domain Helper

Similarly, we'll now create post_item.js to hold the postItem template's logic:

Template.postItem.helpers({
  domain: function() {
    var a = document.createElement('a');
    a.href = this.url;
    return a.hostname;
  }
});

<%= caption "client/templates/posts/post_item.js" %>

This time our domain helper's value is not an array, but an anonymous function. This pattern is much more common (and more useful) compared to our previous simplified dummy data example.

<%= screenshot "3-2", "Displaying domains for each links." %>

The domain helper takes a URL and returns its domain via a bit of JavaScript magic. But where does it take that url from in the first place?

To answer that question we need to go back to our posts_list.html template. The {{#each}} block helper not only iterates over our array, it also sets the value of this inside the block to the iterated object.

This means that between both {{#each}} tags, each post is assigned to this successively, and that extends all the way inside the included template's manager (post_item.js).

We now understand why this.url returns the current post's URL. And moreover, if we use {{title}} and {{url}} inside our post_item.html template, Meteor knows that we mean this.title and this.url and returns the correct values.

<%= commit "3-2", "Setup a domain helper on the postItem." %>

<% note do %>

JavaScript Magic

Although this is not specific to Meteor, here's a quick explanation of the above bit of “JavaScript magic”. First, we're creating an empty anchor (a) HTML element and storing it in memory.

We then set its href attribute to be equal to the current post's URL (as we've just seen, in a helper this is the object currently being acted upon).

Finally, we take advantage of that a element's special hostname property to get back the link's domain name without the rest of the URL.

<% end %>

If you've followed along correctly, you should be seeing a list of posts in your browser. That list is just static data, so it doesn't take advantage of Meteor's real-time features just yet. We'll show you how to change that in the next chapter!

<% note do %>

Hot Code Reload

You might have noticed that you didn't even need to manually reload your browser window whenever you changed a file.

This is because Meteor tracks all the files within your project directory, and automatically refreshes your browser for you whenever it detects a modification to one of them.

Meteor's hot code reload is pretty smart, even preserving the state of your app in-between two refreshes!

<% end %>

Getting Started

First impressions are important, and Meteor's install process should be relatively painless. In most cases, you'll be up and running in less than five minutes.

To begin with, if you're on Mac OS or Linux you can install Meteor by opening a terminal window and typing:

curl https://install.meteor.com | sh

If you're running Windows, refer to the install instructions on the Meteor site.

This will install the meteor executable onto your system and have you ready to use Meteor.

<% note do %>

Not Installing Meteor

If you can't (or don't want to) install Meteor locally, we recommend checking out Nitrous.io.

Nitrous.io is a service that lets you run apps and edit their code right in your browser, and we've written a short guide to help you get set up.

You can simply follow that guide up to (and including) the "Installing Meteor" section, and then follow along with the book again starting from the "Creating a Simple App" section of this chapter.

<% end %>

Creating a Simple App

Now that we have installed Meteor, let's create an app. To do this, we use Meteor's command line tool meteor:

meteor create microscope

This command will download Meteor, and set up a basic, ready to use Meteor project for you. When it's done, you should see a directory, microscope/, containing the following directories and files:

.meteor
client
| main.css
| main.html
| main.js
server
| main.js
.gitignore
package.json

The app that Meteor has created for you is a simple boilerplate application demonstrating a few simple patterns.

Even though our app doesn't do much, we can still run it. To run the app, go back to your terminal and type:

cd microscope
meteor

Now point your browser to http://localhost:3000/ (or the equivalent http://0.0.0.0:3000/) and you should see something like this:

<%= screenshot "2-1", "Meteor's Hello World." %>

<%= commit "2-1", "Created basic microscope project." %>

Congratulations! You've got your first Meteor app running. By the way, to stop the app all you need to do is bring up the terminal tab where the app is running, and press ctrl+c.

Also note that if you're using Git, this is a good time to initialize your repo with git init.

<% note do %>

Bye Bye Meteorite

There was a time where Meteor relied on an external package manager called Meteorite. Since Meteor version 0.9.0, Meteorite is not needed anymore since its features have been assimilated into Meteor itself.

So if you encounter any references to Meteorite's mrt command line utility while browsing Meteor-related material, you can safely replace them by the usual meteor.

<% end %>

Adding a Package

We will now use Meteor's package system to add the Bootstrap framework to our project.

This is no different from adding Bootstrap the usual way by manually including its CSS and JavaScript files, except that we rely on the package maintainer to keep everything up to date for us.

The bootstrap package is maintained by the twbs user, which gives us the full name of the package, twbs:bootstrap.

meteor add twbs:bootstrap

Note that we're adding Bootstrap 3. Some of the screenshots in this book were taken with an older version of Microscope running Bootstrap 2, which means they might look slightly different.

We'll also add the Session package, which will come in handy later:

meteor add session

Although Session is a first-party Meteor package, it's not enabled by default in new Meteor apps so we need to add it manually.

This is a good time to check which packages we're running. It turns out that in addition to the one we just added, Meteor also comes with a few packages enabled out of the box. You can see the list by opening the packages file inside the hidden .meteor directory:

# Meteor packages used by this project, one per line.
# Check this file (and the other files in this directory) into your repository.
#
# 'meteor add' and 'meteor remove' will edit this file for you,
# but you can also edit it by hand.

meteor-base             # Packages every Meteor app needs to have
mobile-experience       # Packages for a great mobile UX
mongo                   # The database Meteor supports right now
blaze-html-templates    # Compile .html files into Meteor Blaze views
reactive-var            # Reactive variable for tracker
jquery                  # Helpful client-side library
tracker                 # Meteor's client-side reactive programming library

standard-minifier-css   # CSS minifier run for production mode
standard-minifier-js    # JS minifier run for production mode
es5-shim                # ECMAScript 5 compatibility for older browsers.
ecmascript              # Enable ECMAScript2015+ syntax in app code

autopublish             # Publish all data to the clients (for prototyping)
insecure                # Allow all DB writes from clients (for prototyping)

session
twbs:bootstrap

This might seem a bit overwhelming, but you don't need to worry about every single package right now. Just verify that our twbs:bootstrap package was successfully added at the end of your package list.

Also, note that unlike twbs:bootstrap, the other packages don't have an author: part in their name, signaling the fact that these are official, core Meteor packages.

<%= commit "2-2", "Added bootstrap package." %>

As soon as you've added the Bootstrap package you should notice a change in our bare-bones app:

<%= screenshot "2-1b", "With Bootstrap." %>

Unlike the “traditional” way of including external assets, we haven't had to link up any CSS or JavaScript files, because Meteor takes care of all that for us! That's just one of the many advantages of Meteor packages.

NPM Packages

While we're on the subject of packages, you'll notice we also have a package.json file in our repository:

{
  "name": "microscope",
  "private": true,
  "scripts": {
    "start": "meteor run"
  },
  "dependencies": {
    "meteor-node-stubs": "~0.2.0"
  }
}

This file is used to tell NPM (Node's package manager) what to do, just like the .meteor/packages file tells Meteor which packages to run. One key difference between both packages system though is that unlike Meteor, NPM doesn't automatically parse an app's package.json file. So you'll have to do it manually every time you add or remove an NPM package.

Let's do it right now with:

npm install

<% note do %>

A Note on Packages

When speaking about packages in the context of Meteor, it pays to be specific. Meteor uses five basic types of packages:

  • The meteor-base package stands alone: it contains Meteor's core components, and a Meteor app can't run without it.

  • First-party packages come bundled with Meteor. Some, such as mongo or session, are included with new Meteor apps by default but can be removed if you don't need them, while others (such as check or http) need to be added explicitly.

  • Local packages are specific to your app, and live in its local /packages directory.

  • Atmosphere packages are custom, third-party packages that have been published to Atmosphere, Meteor's online package repository. They all follow the author:package naming convention.

  • Finally, NPM packages are Node.js packages. They can't be included in your Meteor package list, but instead are listed in your app's package.json file.

<% end %>

The File Structure of a Meteor App

Before we begin coding, we must set up our project properly. To ensure we have a clean build, open up the client and server directory and delete the contents of client/main.html, client/main.js. Then go ahead and delete server/main.js entirely.

Next, create two new root directories inside /microscope: /public, and /lib.

Don't worry if all this breaks the app for now, we'll start filling in these files in the next chapter.

We should mention that some of these directories are special. When it comes to running code, Meteor has a few rules:

  • Code in the /server directory only runs on the server.

  • Code in the /client directory only runs on the client.

  • Everything else runs on both the client and server.

  • Your static assets (fonts, images, etc.) go in the /public directory.

And it's also useful to know how Meteor decides in which order to load your files:

  • Files in /lib are loaded before anything else.

  • Any main.* file is loaded after everything else.

  • Everything else loads in alphabetical order based on the file name.

Note that although Meteor has these rules, it doesn't really force you to use any predefined file structure for your app if you don't want to. So the structure we suggest is just our way of doing things, not a rule set in stone.

We encourage you to check out the official Meteor docs if you want more details on this.

<% note do %>

Is Meteor MVC?

If you're coming to Meteor from other frameworks such as Ruby on Rails, you might be wondering if Meteor apps adopt the MVC (Model View Controller) pattern.

The short answer is no. Unlike Rails, Meteor doesn't impose any predefined structure to your app. So in this book we'll simply lay out code in the way that makes the most sense to us, without worrying too much about acronyms.

<% end %>

No public?

OK, we lied. We don't actually need the public/ directory for the simple reason that Microscope doesn't use any static assets! But, since most other Meteor apps are going to include at least a couple images, we thought it was important to cover it too.

By the way, you might also notice a hidden .meteor directory. This is where Meteor stores its own code, and modifying things in there is usually a very bad idea. In fact, you don't really ever need to look in this directory at all. The only exceptions to this are the .meteor/packages and .meteor/release files, which are respectively used to list your smart packages and the version of Meteor to use. When you add packages and change Meteor releases, it can be helpful to check the changes to these files.

<% note do %>

Underscores vs CamelCase

The only thing we'll say about the age-old underscore (my_variable) vs camelCase (myVariable) debate is that it doesn't really matter which one you pick as long as you stick to it.

In this book, we're using camelCase because it's the usual JavaScript way of doing things (after all, it's JavaScript, not java_script!).

The only exceptions to this rule are file names, which will use underscores (my_file.js), and CSS classes, which use hyphens (.my-class). The reason for this is that in the filesystem, underscores are most common, while the CSS syntax itself already uses hyphens (font-family, text-align, etc.).

<% end %>

Taking Care of CSS

This book is not about CSS. So to avoid slowing you down with styling details, we've decided to make the whole stylesheet available from the start, so you don't need to worry about it ever again.

CSS automatically gets loaded and minified by Meteor, so unlike other static assets it goes into /client, not /public. Go ahead and create a client/stylesheets/ directory now, and put this style.css file inside it:

.grid-block, .main, .post, .comments li, .comment-form {
  background: #fff;
  border-radius: 3px;
  padding: 10px;
  margin-bottom: 10px;
  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15);
  -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15);
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15); }

body {
  background: #eee;
  color: #666666; }

#main {
  position: relative;
}
.page {
  position: absolute;
  top: 0px;
  width: 100%;
}

.navbar {
  margin-bottom: 10px; }
  /* line 32, ../sass/style.scss */
  .navbar .navbar-inner {
    border-radius: 0px 0px 3px 3px; }

#spinner {
  height: 300px; }

.post {
  /* For modern browsers */
  /* For IE 6/7 (trigger hasLayout) */
  *zoom: 1;
  position: relative;
  opacity: 1; }
  .post:before, .post:after {
    content: "";
    display: table; }
  .post:after {
    clear: both; }
  .post.invisible {
    opacity: 0; }
  .post.instant {
    -webkit-transition: none;
    -moz-transition: none;
    -o-transition: none;
    transition: none; }
  .post.animate{
    -webkit-transition: all 300ms 0ms;
    -moz-transition: all 300ms 0ms ease-in;
    -o-transition: all 300ms 0ms ease-in;
    transition: all 300ms 0ms ease-in; }
  .post .upvote {
    display: block;
    margin: 7px 12px 0 0;
    float: left; }
  .post .post-content {
    float: left; }
    .post .post-content h3 {
      margin: 0;
      line-height: 1.4;
      font-size: 18px; }
      .post .post-content h3 a {
        display: inline-block;
        margin-right: 5px; }
      .post .post-content h3 span {
        font-weight: normal;
        font-size: 14px;
        display: inline-block;
        color: #aaaaaa; }
    .post .post-content p {
      margin: 0; }
  .post .discuss {
    display: block;
    float: right;
    margin-top: 7px; }

.comments {
  list-style-type: none;
  margin: 0; }
  .comments li h4 {
    font-size: 16px;
    margin: 0; }
    .comments li h4 .date {
      font-size: 12px;
      font-weight: normal; }
    .comments li h4 a {
      font-size: 12px; }
  .comments li p:last-child {
    margin-bottom: 0; }

.dropdown-menu span {
  display: block;
  padding: 3px 20px;
  clear: both;
  line-height: 20px;
  color: #bbb;
  white-space: nowrap; }

.load-more {
  display: block;
  border-radius: 3px;
  background: rgba(0, 0, 0, 0.05);
  text-align: center;
  height: 60px;
  line-height: 60px;
  margin-bottom: 10px; }
  .load-more:hover {
    text-decoration: none;
    background: rgba(0, 0, 0, 0.1); }

.posts .spinner-container{
  position: relative;
  height: 100px;
}

.jumbotron{
  text-align: center;
}
.jumbotron h2{
  font-size: 60px;
  font-weight: 100;
}

@-webkit-keyframes fadeOut {
  0% {opacity: 0;}
  10% {opacity: 1;}
  90% {opacity: 1;}
  100% {opacity: 0;}
}

@keyframes fadeOut {
  0% {opacity: 0;}
  10% {opacity: 1;}
  90% {opacity: 1;}
  100% {opacity: 0;}
}

.errors{
  position: fixed;
  z-index: 10000;
  padding: 10px;
  top: 0px;
  left: 0px;
  right: 0px;
  bottom: 0px;
  pointer-events: none;
}
.alert {
          animation: fadeOut 2700ms ease-in 0s 1 forwards;
  -webkit-animation: fadeOut 2700ms ease-in 0s 1 forwards;
     -moz-animation: fadeOut 2700ms ease-in 0s 1 forwards;
  width: 250px;
  float: right;
  clear: both;
  margin-bottom: 5px;
  pointer-events: auto;
}

<%= caption "client/main.css" %>

<%= commit "2-3","Re-arranged file structure." %>

<% note do %>

A Note on CoffeeScript

In this book we'll be writing in pure JavaScript. But if you prefer CoffeeScript, Meteor has you covered. Simply add the CoffeeScript package and you'll be good to go:

meteor add coffeescript

<% end %>

Idea 💡

Using this GitBook for Discover Meteor might be really great for the community

Consider porting content from Discover Meteor Book to this book for easier long term support, maintenance, etc.

See WIP concept at this GitBook link...

Introduction

Page preview for evaluation of importing data to GitBook

Do a little mental experiment for me. Imagine you're opening the same folder in two different windows on your computer.

Now click inside one of the two windows and delete a file. Did the file disappear from the other window as well?

You don't need to actually do these steps to know that it did. When we modify something on our local filesystems, the change is applied everywhere without the need for refreshes or callbacks. It just happens.

However, let's think about how the same scenario would play out on the web. For example, let's say you opened the same WordPress site admin in two browser windows and then created a new post in one of them. Unlike on the desktop, no matter how long you wait, the other window won't reflect the change unless you refresh it.

Over the years, we've gotten used to the idea that a website is something that you only communicate with in short, separate bursts.

But Meteor is part of a new wave of frameworks and technologies that are looking to challenge the status quo by making the web real-time and reactive.

What is Meteor?

Meteor is a platform built on top of Node.js for building real-time web apps. It's what sits between your app's database and its user interface and makes sure that both are kept in sync.

Since it's built on Node.js, Meteor uses JavaScript on both the client and on the server. What's more, Meteor is also able to share code between both environments.

The result of all this is a platform that manages to be very powerful and very simple by abstracting away many of the usual hassles and pitfalls of web app development.

Why Meteor?

So why should you spend your time learning Meteor rather than another web framework? Leaving aside all the various features of Meteor, we believe it boils down to one thing: Meteor is easy to learn.

More so than any other framework, Meteor makes it possible to get a real-time web app up and running on the web in a matter of hours. And if you've ever done front-end development before, you'll already be familiar with JavaScript and won't even need to learn a new language.

Meteor might be the ideal framework for your needs, or then again it might not. But since you can get started over the course of a few evenings or a week-end, why not try it and find out for yourself?

Why This Book?

For the past couple years, we've been working on numerous Meteor projects, spanning the range from web to mobile apps, and from commercial to open-source projects.

We learned a ton, but it wasn't always easy to find the answers to our questions. We had to piece things together from many different sources, and in many cases even invent our own solutions. So with this book, we wanted to share all these lessons, and create a simple step-by-step guide that will walk you through building a full-fledged Meteor app from scratch.

The app we'll be building is a simplified version of a social news site like Hacker News or Reddit, which we'll call Microscope (by analogy with its big brother, Meteor open-source app Telescope). While building it, we'll address all the different elements that go into building a Meteor app, such as user accounts, Meteor collections, routing, and more.

Who Is This Book For?

One of our goals while writing the book was to keep things approachable and easy to understand. So, you should be able to follow along even if you have no experience with Meteor, Node.js, MVC frameworks, or even server-side coding in general.

On the other hand, we do assume familiarity with basic JavaScript syntax and concepts. But if you've ever hacked together some jQuery code or played around with the browser's developer console, you should be OK.

If you're not that comfortable with JavaScript yet, we suggest checking out our JavaScript primer for Meteor before getting started with the book.

About the Authors

In case you're wondering who we are and why you should trust us, here is a little more background on both of us.

Tom Coleman

Tom Coleman founded Percolate Studio, a web development shop with a focus on quality and user experience, was one of the creators of the Atmosphere package repository, and is also one of the brains behind many other Meteor open-source projects. He now works full-time for the Meteor Development Group.

Sacha Greif

Sacha Greif has worked with startups such as Hipmunk and RubyMotion as a product and web designer. He's the creator of Telescope and Sidebar (which is based on Telescope).

Chapters & Sidebars

We wanted this book to be useful both for the novice Meteor user and the advanced programmer, so we split the chapters into two categories: regular chapters (numbered 1 through 14) and sidebars (.5 numbers).

Regular chapters will walk you through building the app, and will try to get you operational as soon as possible by explaining the most important steps without bogging you down with too much detail.

On the other hand, sidebars will go deeper into Meteor's intricacies, and will help you get a better understanding of what's really going on behind the scenes.

So if you're a beginner, feel free to skip the sidebars on your first read, and come back to them later on once you've played around with Meteor.

Git Commits

There's nothing worse than following along in a programming book and suddenly realizing your code has gotten out of sync with the examples and that nothing works like it should anymore.

To prevent this, we've set up a GitHub repository for Microscope, and we'll also provide direct links to git commits every few code changes. Here's an example of what that will look like:

<%= commit "11-2", "Display notifications in the header." %>

But note that just because we provide these commits doesn't mean you should just go from one git checkout to the next. You will learn much better if you take the time to manually type out your app's code!

A Few Other Resources

If you ever want to learn more about a particular aspect of Meteor, the official Meteor documentation and Meteor Guide are the best places to start.

We also recommend Stack Overflow for troubleshooting and questions, and the #meteor IRC channel if you need live help.

<% note do %>

Do I Need Git?

While being familiar with Git version control is not strictly necessary to follow along with this book, we strongly recommend it.

If you want to get up to speed, we recommend Nick Farina's Git Is Simpler Than You Think.

If you're a Git novice, we also recommend the GitHub app (Mac OS), which lets you clone and manage repos without using the command line, or SourceTree (Mac OS & Windows), both of which are free.

<% end %>

Getting in Touch

  • If you'd like to get in touch with us, you can email us at hello@discovermeteor.com.

  • Additionally, if you find a typo or another mistake in the book's contents, you can let us know by submitting a bug in this GitHub repo.

  • If you have a problem with Microscope's code, you can submit a bug in Microscope's repository.

  • Finally, for every other question you can also just leave us a comment in this app's side panel.

Using GitHub

GitHub is a social repository for open-source projects based around the Git version control system, and its primary function is to make it easy to share code and collaborate on projects. But it's also a great learning tool. In this sidebar, we'll quickly go over a few ways you can use GitHub to follow along with Discover Meteor.

This sidebar assumes you're not that familiar with Git and GitHub. If you're already comfortable with both, feel free to skip on to the next chapter!

Being Committed

The basic working block of a git repository is a commit. You can think of a commit as a snapshot of your codebase's state at a given moment in time.

Instead of simply giving you the finished code for Microscope, we've taken these snapshots every step of the way, and you can see all of them online on GitHub.

For example, this is what the last commit of the previous chapter looks like:

<%= screenshot "s3-1", "A Git commit as shown on GitHub." %>

What you see here is the “diff” (for “difference”) of the post_item.js file, in other words the changes introduced by this commit. In this case, we created the post_item.js file from scratch, so all its contents are highlighted in green.

Let's compare with an example from later on in the book:

<%= screenshot "s3-2", "Modifying code." %>

This time, only the modified lines are highlighted in green.

And of course, sometimes you're not adding or modifying lines of code, but deleting them:

<%= screenshot "s3-3", "Deleting code." %>

So we've seen the first use of GitHub: seeing what's changed at a glance.

Browsing A Commit's Code

Git's commit view shows us the changes included in this commit, but sometimes you might want to look at files that haven't changed, just to make sure what their code is supposed to look like at this stage of the process.

Once again GitHub comes through for us. When you're on a commit page, click the Browse code button:

<%= screenshot "s3-5", "The Browse code button." %>

You'll now have access to the repo as it stands at a specific commit:

<%= screenshot "s3-6", "The repository at commit 3-2." %>

GitHub doesn't give us a lot of visual clues that we're looking at a commit, but you can compare with the “normal” master view and see at a glance that the file structure is different:

<%= screenshot "s3-7", "The repository at commit 14-2." %>

Accessing A Commit Locally

We've just seen how to browse a commit's entire code online on GitHub. But what if you want to do the same thing locally? For example, you might want to run the app locally at a specific commit to see how it's supposed to behave at this point in the process.

To do this, we'll take our first steps (well, in this book at least) with the git command line utility. For starters, make sure you have Git installed. Then clone (in other words, download a copy locally) the Microscope repository with:

git clone https://github.com/DiscoverMeteor/Microscope.git github_microscope

That github_microscope at the end is simply the name of the local directory you'll be cloning the app into. Assuming you already have a pre-existing microscope directory, just pick any different name (it doesn't need to have the same name as the GitHub repo).

Let's cd into the repository so that we can start using the git command line utility:

cd github_microscope

Now when we cloned the repository from GitHub, we downloaded all the code of the app, which means we're looking at the code for the last ever commit.

Thankfully, there is a way to go back in time and “check out” a specific commit without affecting the other ones. Let's try it out:

git checkout chapter3-1
Note: checking out 'chapter3-1'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b new_branch_name

HEAD is now at a004b56... Added basic posts list template and static data.

Git informs us that we are in “detached HEAD” state, which means that as far as Git is concerned, we can observe past commits but we can't modify them. You can think of it as a wizard inspecting the past through a crystal ball.

(Note that Git also has commands that let you change past commits. This would be more like a time traveller going back in time and possibly stepping on a butterfly, but it's outside the scope of this brief introduction.)

The reason why you were able to simply type chapter3-1 is that we've pre-tagged all of Microscope's commits with the correct chapter marker. If this weren't the case, you'd need to first find out the commit's hash, or unique identifier.

Once again, GitHub makes our life easier. You can find a commit's hash in the bottom right corner of the blue commit header box, as shown here:

<%= screenshot "s3-4", "Finding a commit hash." %>

So let's try it with the hash instead of a tag (if this specific hash doesn't work, feel free to get another one from GitHub):

git checkout b1280aa8affdb9f4ca5dab5f84d0f9878fc2f67d
Previous HEAD position was a004b56... Added basic posts list template and static data.
HEAD is now at c7af59e... Augmented the postsList route to take a limit

And finally, what if we want to stop looking into our magic crystal ball and come back to the present? We tell Git that we want to check out the master branch:

git checkout master

Note that you can also run the app with the meteor command at any point in the process, even when in “detached HEAD” state. You might need to run a quick meteor update first if Meteor complains about missing packages, since package code is not included in Microscope's Git repo.

Historical Perspective

Here's another common scenario: you're looking at a file and notice some changes you hadn't seen before. The thing is, you can't remember when the file changed. You could just look at each commit one by one until you find the right one, but there's an easier way thanks to GitHub's History feature.

First, access one of your repository's files on GitHub, then locate the “History” button:

<%= screenshot "s3-8", "GitHub's History button." %>

You now have a neat list of all the commits that affected this particular file:

<%= screenshot "s3-9", "Displaying a file's history." %>

The Blame Game

To wrap things up, let's take a look at Blame:

<%= screenshot "s3-10", "GitHub's Blame button." %>

This neat view shows us line by line who modified a file, and in which commit (in other words, who's to blame when things aren't working anymore):

<%= screenshot "s3-11", "GitHub's Blame view." %>

Now Git is a fairly complex tool – and so is GitHub –, so we can't hope to cover everything in a single chapter. In fact, we've barely scratched the surface of what is possible with these tools. But hopefully, even that tiny bit will prove helpful as you follow along the rest of the book.

Deploying

Some people like to work quietly on a project until it's perfect, while others can't wait to show the world as soon as possible.

If you're the first kind of person and would rather develop locally for now, feel free to skip this chapter. On the other hand, if you'd rather take the time to learn how to deploy your Meteor app online, we've got you covered.

We will be learning how to deploy a Meteor app in few different ways. Feel free to use each of them at any stage of your development process, whether you're working on Microscope or any other Meteor app. Let's get started!

<% note do %>

Introducing Sidebars

This is a sidebar chapter. Sidebars take a deeper look at more general Meteor topics independently of the rest of the book.

So if you'd rather go on with building Microscope, you can safely skip it for now and come back to it later.

<% end %>

Deploying On Heroku

A fast and easy (and free!) way to deploy your Meteor app is to deploy to Heroku using the Horse buildpack.

See the readme for a step-by-step explanation.

Deploying On Galaxy

Galaxy is the Meteor Development Group's official hosting platform, and it's built in right into the Meteor command line tool via the meteor deploy command.

Galaxy doesn't offer a free plan, but it's a great option once you're ready to push your app live.

Note that the Meteor Development Group used to provide a free hosting service (usually referred to as just “Meteor hosting”) but as of March 2016, that free tier sadly doesn't exist anymore.

Deploying with MupX

Finally, if you'd rather deploy on your own servers, MupX is a handy Docker deploy script that will set up and deploy your app on any Digital Ocean, AWS, etc. box.

These three ways of deploying Meteor apps should be enough for most use cases. Of course, we know some of you would prefer to be in complete control and set up their Meteor server from scratch. But that's a topic for another day… or maybe another book!