Less than *ambitious* websites with Ember.js
What is involved in building a website in 2017?
Building "a website" can mean many different things. Some people curate content on the SquareSpace platform and change the logo a bit - or customise a Tumblr blog theme. 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 simple or very complex/dynamic sites or - use a static-site generator to spit out lean HTML pages. Some people write standard HTML pages or got excited about a PHP or JavaScript framework. More and more of us are building 'web-applications' - or "websites that do things."
TL;DR - Too long? Don't read it. - OR consider that you may have a distorted view of time - take a deep breath - and allow yourself to relax for a bit.
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 is also not. The client(person) 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. I want others to be able to jump in and contribute. 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 this 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. However, every time you click a link on a site like that - that whole process has to happen again. This means when you land on the initial page–when you click about–when you click contact and so on - each subsequent page will be searched for, read over, reinterpreted, 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 that page linking inside the site and only updates the unique parts of the page that have changed. I want to keep track of what the visitor has and hasn't interacted with so I can make smart decisions about delivering the right content for them.
The site needs to look and feel great. I'm definitly going to use CSS preprocessor. I love writing CSS and I love using Stylus to do that. Things like stylus 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' throughout the application. 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 do not 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. If you love doing all that stuff - you don't need to read further. 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(for me). 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?
For the site I'm outlining - I'll need templates for the content, some scripts to allow interaction and change the data, 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 the Ember ecosystem)
- a built-in asset pipeline to handle CSS and JavaScript preprocessing and concatenation (it uses a modern es2015 javascript module system)
- a solid 'router' for handling the state of the application (what page you're on and other data).
- plus 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 - or visit the Emberjs guides.
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."
UPDATE: (you can just do this now)
ember install ember-cli-stylus
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
......
I'm working full-time now - with Perpetual Education on their new learning platform. Check it out! It's by far the best way to learn design and development for the least money and the fastest results - and it's really fun. Seriously.
Free advice sessions: no strings attached - just a real human who wants to help you become a great designer.
Interesting article, I’ve thought of doing the same thing for simple websites but the question is: How performant would a website built this way be?
Nothing is going to be as fast as just an HTML page with no CSS or JavaScript — but it all depends on what you want. If you want to make a fancy transition - or pull in data from many places - or any other snappy login type stuff - you’re going to add complexity pretty quickly anyway. I’ve never had a problem loading any sites on my phone… but live in a place where high-speed internet is the norm. Making a fun little brochure website for your portfolio - or neighborhood business is going to be completely different than building a really important banking application in Africa. It’s also about time and also maintaining a website. Is a Linux / PHP WordPress site more performant? It depends. Is it easier to maintain? No. It’s all about trade-offs. In general… I’m getting to the point where I’d rather not program anything anymore. haha. There are many tools to gauge performance. You should read this: https://madhatted.com/2017/6/16/building-a-progressive-web-app-with-ember : )
So good to read
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.
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.