Less than *ambitious* websites with Ember.js

Published Mar 27, 2017Last updated Aug 24, 2017
Less than *ambitious* websites with Ember.js

What is involved in building a website in 2017?

Building "a website" can mean many things. Some people curate content on the SquareSpace platform and change the logo a bit or customise a Tumblr. They are probably the smart ones who learned how to make money instead of how to write programs. You can use WordPress as a free way to manage user content for more complex/dynamic sites or use a static-site generator to spit out lean HTML. Some people write standard HTML pages or maybe they got excited about a PHP or JavaScript framework. More and more of us are building 'web-applications' - or "websites that do things."

TL;DR - just don't read it if you don't have time.

The kind of website I'm going to outline here, is the classic 4-page brochure website. This type of site isn't typically complex but it's not as simple as it used to be, or - it is, but it's not. The client often expects full control over the content. We all want our layouts to be responsive to all screen sizes and contexts. I want to make things that feel snappy and fancy and "native", and I want the authoring process to be manageable. I want to keep track of my changes with version control. I want to deploy my changes to the host with ease and safety. I want something that can be extended and can scale up if the project gains complexity. This last one may be unreasonable... but I also want it to be fun.

A standard website is made up of documents / sorta. When you ask the browser to retrieve something from a specified URL, the server will point you to an HTML document or it may smash together some PHP (or JS) first - and then point you to that document. The browser will look the document over, make some notes, and then create its own model of that document in memory. It uses this DOM to paint what you see on the screen. Fantastic. It is, but every time you click a link on a site like this - that whole process has to happen again. This means when you land on the page–when you click about–when you click contact and so on - that the entire page will be searched for, read over, and rerender - and will also loose any 'state' it had. This is not ideal. I want to use something with a great router that handles the page linking inside the site and only updates the unique parts. I want to keep track of what the visitor has and hasn't interacted with so I can make smart decisions about delivering them the right content.

I'm definitly going to use CSS preprocessor. I love writing CSS and I love using Stylus to do that. Things like variables allow me to quickly test out ideas and mixins allow me to author super readable style rules. You'll also likely use a preprocessor of some sort. I'm going to want to add some fancy user interaction/animation, and I'll need to manage bits of JavaScript programs or 'packages'. So, I'm looking at some setup time to gather the boilerplate HTML structure for those pages, and then I'll have to copy and paste site-wide markup like the menu, on each page every time I make a change. Then I start thinking - I could use PHP to partial out the pieces of reused markup but they I'll need apache and MAMP... codekit for managing dependencies with bower or maybe grunt to smash all the JS together - I'll just need to look up the config syntax and maybe I'll use jade or coffeescript... Or browserify? or webpack or gulp or brunch and... NOOOOO!!! I don't want to do any of that stuff. If you don't know what some of that stuff I just mentioned is, then that is part of my point. There are tons of options and combinations of these things and it's not fun to switch between them and learn new ones all the time. How can I just get to work on the parts that actually matter? I just don't think that a tiny tiny website should be this much setup - and I want to spend my time on the hard parts. I am not lazy. I just know that if I can't align myself with some conventions, I believe in, I'll burn myself out trying to build my own framework. If you have a budget and a timeline, it's hard to write in 50%: setup and feel good about it. What if there was one really great setup we could all use and collectively improve over time without having to ditch the whole thing every six months? (there is) and they called it "Ember."

How can I just get to work on the parts that actually matter?

Ember isn't just for ambitious applications

All the JavaScript frameworks have fun branding and hype, and they are all very impressive and should be given mucho respect for their creativity and all that they bring to the greater conversation. Ember is one such framework, but it is different. Ember doesn't seek to be 'unique'. {{images.borgifiedTomster}} Ember is a collection of best practices. It's a bunch of solutions to problems that everyone faces while building projects. It collects these patterns together in one place so we can all improve those solutions over time as a community. Ember seeks to be a Software Developer Kit for the web as a whole. These are what we've found to be the most practical, safe, and manageable ways to deal with the most common challenges that arise in our lives as developers. It is so closely aligned with the future JavaScript standards that another of it's goals is to one day peel away the Ember parts to reveal native JS wherever possible. Ember is stable, but it isn't stagnant. If there is something truly magic happening in the latest niche framework or library, you can bet that it will be incorporated by Ember at some point.

Shut up, Derek! We get it... you think Ember is really special - what about the example brochure site?

So, for the site I'm outlining - I'll need templates for the content, a magic machine that does all the processing and live-reloading, and a trusted way to travel between the templates while keeping the URL in tact.

Ember has:

  • a wonderful templating system (if you've used handlebars before... it's 10x more elegant in Ember)
  • a built-in asset pipeline to handle CSS and JavaScript preprocessing and concatenation
  • a solid router for handling the state of the application (what page you're on and other data).
  • an ecosystem of reusable code called 'addons,' and all sorts of great stuff that work together.

The overall goal is to arm developers with the tools to create incredibly ambitious projects. BUT guess what... Ember isn't just for ambitious applications. It is for everything - if you let it be.

If you've read this far, I dare you to follow this walk-through and give it a chance. I'm NOT going to explain how anything works and I'm only going to show you the most entry level parts of what Ember has to offer. Want more? That's not what this article is. If you'd like to know more, let me know in the comments, and I'll point you to the right places or write more about it. 😃

Do what I'm about to outline! And then tell me if you don't like it.

Prerequisites: (besides the expected, computer, text editor, browser)

  • 15-30 minutes of your very valuable time
  • A terminal and how to use it a little (at least how to change directories)
  • You are going to need NODE.js (I'm not going to talk about that here.)
  • https://nodejs.org/en/ (get it - if you don't have it) (it will also install the 'npm' package manager)
  • Install the Ember Command Line Interface (Ember CLI) through npm (this will install it globally)

Type the following command in the terminal (then hit enter 😛)

npm install -g ember-cli

(this says, hey node package manager, please install ember-cli and not just in the current directory, but on the 'global' system (-g)

Wait wait wait... done.

Ok. So, you have the command line tool now. A fun thing about Ember's architecture is that it forces you to think about your content and strategy from the start. For example...

I'm going to make a website called "Marci's Flowers."

A friend of mine is a fantastic painter in the bay area. I'll pull some of her images for this example.

Where should I create this project? I suggest in your /sites folder, so - in your terminal window cd sites will change directory to the sites folder.

This is where you want the website to be - so now you need to use the ember-cli to create it. Instead of using the package manager with npm we use ember for the command. Think of a SHORT but descriptive name for the site (no spaces or crazy stuff). marcis-flowers will be wonderful.

ember new marcis-flowers

"ember, please create a new project called marcis-flowers"

Ember is now installing tons of gnarly stuff. Look away. Take this time to think about what the site will be. With Ember and similar MVCish type frameworks, you think in 'routes' instead of 'pages.' A route is more than a page. You can nest routes and summon route specific data and you have control over each stage of leaving and entering them. Ember encourages you to really think about what you want to make instead of just filling in content in a WordPress theme. "Well, there is an about page in this theme - so we should put something there. See if the client can drum up some content." Nobody wants a website.

Ember's install will also create a git repo. I synced it with GitHub and kept my commits concise in case you want to follow along. https://github.com/sheriffderek/marcis-flowers If you don't know what git or version control is - that's fine. You can learn about that later.

Strategy

Nobody wants a 'website' - they want to share content - and a site on the web is a globally accessible place to do that.

Marci is really cool. She's a painter, and sometimes she paints radical floral patterns. I'm thinking that when we get to the site - that there should be a big image (or a tiny one) - but just something to say "Welcome, check out this rad thing!" Maybe it's her latest piece or a flier for an upcoming show. I'm going to think of that as the welcome route. After they've been wowed by that, they might want to know a little about Marci's flowers. I'll have a page that lists out all the flowers. After they've looked at all of the flowers - they may want to learn more about Marci. I'll have that be the about route. People are also going to want to contact her and buy her flowers, so I guess I'll need a contact route. (I actually think that contact could just go in the footer and then always be available). The 4th page can be a 404 page as an example of when a visitor hits a non-existant URL.

  • welcome (or home or landing or whatever)
  • flowers
  • about
  • 404

The ember install is surely done by now. But notice that your terminal still shows you in the /sites path, so change directories with terminal

cd marcis-flowers

OK. Now you are in the project. To check out your fabulous new project, run

ember serve

Ember's built-in server(node) will start up, and you can visit http://localhost:4200/ in your browser to see a fun welcome message. 😃

Open the project files in a text editor. Find application.hbs - it will be in app/templates/->

It's going to look something like this:

{{welcome-page}}

{{outlet}}

but you should change it. (Brochure sites often have site-wide headers - and we don't need the ember-welcome-page anymore.) Remove the welcome page 'component' and add the markup below.

<header class='site-header'>I'm the Header for Marci's Flowers</header>

<div class='outlet'>
  {{outlet}}
</div>

That outlet is a 'handlebars expression,' but you don't really need to understand that yet. Think about it as a window where the routes will display. It's kinda like an iframe on the page.

Now you can make those routes we outlined. Ember has many commands at your disposal. Use the generate command to generate the route.

ember generate route welcome

Then do the same for flowers about and 404.

You'll notice that the terminal shows a few different files being created each time you generate a route but just worry about the templates in this example. We're making a less than ambitious website here. It's going to be awesome, but we're not going to need fancy tests or anything.

Check out the new templates you created. app/templates/welcome.hbs You'll notice that they are empty. Well, they have an {{outlet}} in there, but we don't need that because we aren't going to 'nest' routes here. We just need the one 'application-level' {{outlet}}. Change each template to say something. Follow my lead if you like:

welcome

<h1>Welcome</h1>

<figure>
  <img src='http://marciwashington.com/night/peonies.jpg' alt='Peonies: painting by Marci Washington'>
</figure>

You can put whatever you want on each route. It doesn't matter for this walkthrough - just put something.

about

<h1>About</h1>

<figure>
  <img src='http://marciwashington.com/marci2.jpg' alt='Portrait of Marci Washington'>
</figure>

<p>I grew up moving all over the California bay area. I moved to Oakland to attend the California College of the Arts and Crafts, where I received my BFA in 2002 and my MFA in 2008. I live and work in Berkeley, CA.</p>

<p>...</p>

<p>Drop me a line at <a href='mailto:marciwashington@gmail.com' target='email'>marciwashington@gmail.com</a></p>

flowers

<h1>flowers</h1>

<ul class='flower-list'>

  <li class='flower'>
    <figure>
      <img src='http://www.marciwashington.com/night/peonies.jpg' alt='Peonies 1: painting by Marci Washington'>
    </figure>
  </li>

  <li class='flower'>
    <figure>
      <img src='http://www.marciwashington.com/night/peonies.jpg' alt='Peonies 2: painting by Marci Washington'>
    </figure>
  </li>

  <li class='flower'>
    <figure>
      <img src='http://www.marciwashington.com/night/peonies.jpg' alt='Peonies 3: painting by Marci Washington'>
    </figure>
  </li>

  <li class='flower'>
    <figure>
      <img src='http://www.marciwashington.com/night/peonies.jpg' alt='Peonies 4: painting by Marci Washington'>
    </figure>
  </li>

  <li class='flower'>
    <figure>
      <img src='http://www.marciwashington.com/night/peonies.jpg' alt='Peonies 5: painting by Marci Washington'>
    </figure>
  </li>

  <li class='flower'>
    <figure>
      <img src='http://www.marciwashington.com/night/peonies.jpg' alt='Peonies 6: painting by Marci Washington'>
    </figure>
  </li>

</ul>

404

<h1>404 error</h1>

<p>Whoops! This route does not exist. Try another!</p>

<figure>
  <img src='http://marciwashington.com/spell/spell.JPG' alt='Painting: Spell'>
</figure>

application

<header class='site-header'>I'm the Header for Marci's Flowers</header>

<div class='outlet'>
  {{outlet}}
</div>

<footer class='site-footer'>I'm the Footer for Marci's Flowers</footer>

Save those. Great. But check out the website in the browser. Still, just the header and footer showing right? Yeah. Try http://localhost:4200/welcome

There it is.

How does it know to get that template? It's really just a naming convention. The route is named 'welcome' the template is named 'welcome' etc. It's the type of thing that Ember takes care of. But quickly check out the router.js

Router.map(function() {
  this.route('welcome');
  this.route('about');
  this.route('404');
  this.route('flowers');
});

This is how the router is mapped out.

Change a few things...

Router.map(function() {
  this.route('welcome', {path: '/'}); // now the root
  this.route('about');
  this.route('flowers');
  this.route('404', {path:'*'}); // anything that doesn't match a route
});

Now you can navigate to http://localhost:4200 and you'll hit welcome as the root route/template. Also, if you try and go to http://localhost:4200/jerks you'll find a 404 error route - because Marci doesn't like jerks.

This is all great... but we need 'links' to get to the pages. Those are usually in the header, right? Ember has a special 'handlebars helper' for handling the intricacies of links. (For a simple site, you could get away without using handlebars (the templating language) for anything but outlets and links)

Add this to your header

<header class='site-header'>

  <div class='branding'>
    Marci's flowers
  </div>

  <nav class='site-navigation'>
    <ul class='menu'>
      <li>
        {{#link-to 'welcome'}} {{!-- or 'application' is great --}}
          <span>Home</span>
        {{/link-to}}
      </li>
      <li>
        {{#link-to 'about'}}
          <span>About</span>
        {{/link-to}}
      </li>
      <li>
        {{#link-to 'flowers'}}
          <span>Flowers</span>
        {{/link-to}}
      </li>
    </ul>
  </nav>

</header>

Now you should be able to navigate the site! Very snappy, isn't it? But it's not very pretty... Marci and her flowers are lookin good, but I haven't added any styles yet. You can just use CSS if you want. There is already an app.css file there, but I'm going to use stylus.

To install stylus or scss or anything - you need to use the terminal again.
You'll have to stop the server first with controle>c. Then...

npm install ember-cli-stylus --save-dev

"npm, please install the package 'ember-cli-stylus' - but also, please save it in the package.json file and only as a development dependency."

Load load load. Cool. Now check around in your project files and you'll see a styles folder app/styles - create an app.styl file and add a little something to test that stylus is working.

$color = #7C0D15 // stylus variable declaration syntax

.branding
  font-size: 18px
  font-weight: bold
  color: $color

Now restart your server

ember serve

I'd love to teach you CSS, but I'm not going to do that here. Contact me and I'll reveal all of the mysteries. Instead, I'll just spend 5 minutes trying to make this look nice and push it up to the repo. I'm going to also install ember install ember-cli-autoprefixer just like I did the stylus. That way I don't have to think about -webkit- prefixes.

and... done.

OK. So, you have a website. It has 'pages.' It links between the pages. It doesn't reload the header and everything every time you do anything. It's fast. It has build tools already built in and they reload changes automatically in the browser, and everything is awesome. How do you get this thing live on the internet for people to see?

There are many ways. Of course, I'm going to show you the fastest. I like surge.sh

ember install ember-cli-surge

This will give you the surge command.

Once you are all ready...

ember surge

If you've never used surge, I think it will ask you for some username type stuff to sign up - but then it will build your application and deploy it. Wait a little bit... the command line will give you feedback. The first time is the slowest.

Here we go.

http://marcis-flowers.surge.sh

Live site on the web. The client always calls you 6 months later asking for the login because they never used the CMS anyway. Just charge for the copy changes. 😃

That's my story... Use Ember for EVERYTHING?

Well, not always - but don't count Ember out as too hard. You can use it just like this - and overtime, learn a little bit as your projects require more complexity. The next steps would be to break out the menu into a 'component' and probably to get a dynamic list of flowers feeding in and being looped over with an 'each' helper. When people say that learning a framework is hard, I think it's because they are simultaneously learning a lot of things - and that is what is hard. Ember is there to back you up with a great community and high-quality guides and more resources all the time. When you're ready to take things a step further... follow the Ember tutorial and check out the guides

There are some gotchas... even for something this simple. Maybe when more casual users get on board, they will be taken more seriously. This is a major goal of posts like this. The first one you'll notice will be on a long page. You'll scroll down really far on a list of items, and then you'll go to another page and be already scrolled down half way. This is wonderfull - (for example - on codementor's list of requests - when I return to the list - I'm at the beginning again and I've lost my place and it wastes my time) BUT not really a great default for a simple site... maybe we could opt in for specific routes only instead. You'll see what I mean one day - and you'll find this old link. Help suss out the edge cases and make Ember your framework. We need you.

Some resources that helped me out were Ember screencasts and also check out emberschool.com(big discount link). It's a high-quality course that describes each of Ember's concepts and takes you from beginner level, to creating your own (tiny) social network. It's fun, and when you're done, you'll have your own fully functioning application to show off. I highly recomend it.

There are some other excellent resources, but my primary point is that you can use Ember today and add to your understanding over time. If you've already been using Ember for a long time - and are reading this for some reason... I recommend taking the advanced course with Mike North on frontendmasters. Ember is free but don't let that blind you from it's value. Put some money into the people and courses and conferences.

If you're new to all of this 'web' stuff - and would like to learn more about Ember or HTML or CSS or JavaScript - or command lines or package managers or WordPress or local setups or pretty much anything (except react or Angular or rails) --- Let's chat about where you're at. I can share what I've learned to save you some time + get you where you want to be - faster. Ember's learning curve is getting smaller - but the glue and the es6 was all pretty confusing to me at first. Nothing beats talking to a human about a real application. Don't be shut-in.

@sheriffderek

Discover and read more posts from sheriffderek
get started
Enjoy this post?

Leave a like and comment for sheriffderek

11
8
8Replies
Udit Agarwal
5 months ago

So good to read

JeffreyBiles
6 months ago

Great article, and thanks for the EmberSchool link!

If you’re updating the article actively, it may be good to mention GlimmerJS (https://glimmerjs.com/)--) announced literally the day after you published this, it’s another good way to work Ember into a less-ambitious application.

sheriffderek
5 months ago

Glimmer - moving out of the college house, into it’s own apartment is certainly exciting - but it’s a bit ahead of the game with all the new @ syntax and might be more confusing to beginner in that way until Ember also officially solidifies the new look. I’ll be thinking about it going forward.

Mark Lummus
6 months ago

your 404 path did not work for me. had to use {path:’/*path’}, but otherwise works great!

I too fell into the trap thinking that Ember was too ambitious for a simple site - i’ve personally used jekyll for similar sites in the past, but now I think I will just use Ember.

sheriffderek
6 months ago

This made it all worth writing Mark.

Show more replies

Get curated posts in your inbox

Read more posts to become a better developer