Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions _includes/head.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="description" content="{{ site.description }}">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="google-site-verification" content="R6NeN9Ns2jZ5cwR_MlvvZXlua_D6RLOPAoBLfbXgLOY" />

<title>{{ site.title }}{% if page.title %} - {{ page.title }}{% endif %}</title>
<meta name="description" content="{% if page.excerpt %}{{ page.excerpt | strip_html | strip_newlines | truncate: 160 }}{% else %}{{ site.description }}{% endif %}">
Expand Down
182 changes: 124 additions & 58 deletions _posts/2015-08-13-Angular2-CMS-with-Material-Design-Lite.markdown
Original file line number Diff line number Diff line change
@@ -1,106 +1,172 @@
---
layout: post
title: "Angular2 CMS with Material Design Lite"
title: "Angular2 CMS with Material Design Lite and ES6"
date: 2015-08-09 18:50:15
categories: [programming]
tags: [angular.js, angular2, javascript, javascript frameworks, es6, ecma2015, cms, material design, material design lite]
tags: [angular.js, angular2, javascript, javascript frameworks, es6, ecma2015, cms, material design, material design lite, typescript, traceur]
published: false
---
Building a system to manage content using latest web technology is what it's all about, right? Angular2 and Material Design Lite bring new life to this routine task. Let's explore!

### Installing dependencies
I wrote about [installing Angular2]({% post_url 2015-08-09-npm-install-angular2 %}). We compiled traceur.js from source and setup a header for an Angular2 app using ES6.

#### Angular2 (ES6 Style)
I wrote about [installing Angular2]({% post_url 2015-08-09-npm-install-angular2 %}). We compiled traveur.js from source and setup a header for an Angular2 app using ES6. We're just going to use [es6-shim](https://www.npmjs.com/package/es6-shim) this time around.
This time through, we'll grab down Typescript et al. and include our libs from CDNs. Let's install [typescript's package manager](https://www.npmjs.com/package/tsd) and other dependencies.

-----
{% highlight console %}
$ npm install -g tsd # typescript dependency manager
$ npm install -g typescript # typescript compiler
$ mkdir cms-frontend
$ cd cms-frontend
$ npm init
$ npm install angular2 --save
$ npm install es6-shim --save
$ tsd init
$ tsd install angular2 es6-promise rx rx-lite --save # from the quickstart
{% endhighlight %}
-----

We'll want to include this in our header, of course. Below is what your HTML should look like, roughly:
### Touching the index
To start, we want just index.html to include all of our dependencies.

-----
{% highlight javascript %}
<!-- cms-frontend/index.html -->
<html>
<head>
<title>My first Angular2 CMS!</title>
<link rel="stylesheet" href="style.css"></script>
<!-- es6-shim before angular2, javascript after styles -->
<script src="node_modules/es6-shim/es6-shim.js"></script>
<script src="node_modules/angular2/angular2.js"></script>
<link rel="stylesheet" href="/style.css">
<link rel="stylesheet" href="https://storage.googleapis.com/code.getmdl.io/1.0.4/material.indigo-pink.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">

<script src="https://storage.googleapis.com/code.getmdl.io/1.0.4/material.min.js"></script>
<script src="https://github.jspm.io/jmcriffey/[email protected]/traceur-runtime.js"></script>
<script src="https://jspm.io/[email protected]"></script>
<script src="https://code.angularjs.org/2.0.0-alpha.32/angular2.dev.js"></script>
</head>
<body>
<!-- we're gonna put some cool stuff in here -->
<script src="start.js"></script>
<cms-app></cms-app>
<script>System.import('cms-app');</script>
</body>
</html>
{% endhighlight %}
-----

#### Material Design Lite
We will be styling our CMS with Google's MDL because it's pretty and new. Let's install it with NPM because that gives us control of the SASS variables. If we want.
After we set the title, we include our stylesheets and scripts. Pretty straight-forward so far. I'm sure you can handle creating the style.css file :)

-------
{% highlight console %}
$ npm install material-design-lite --save
{% endhighlight %}
-------
If you are brave enough to be trying to install these dependencies via node, note that you'll need to configure paths for System.js

We also load our own style.css before any javascript to get the page to render correctly while the js loads in the bg.

Loading material.js first is good imho because there's a weird bug (currently?) where the [page jumps to the top](https://github.com/google/material-design-lite/issues/1224) and this allows the material.js layout rendering to happen fastest.

Traceur is going to let our ES6 magic happen. Even though Typescript is compiling it, apparently we still need traceur. This, I gathered from the quickstart. If I'm wrong, please correct me.

### Angular2 -- The Beginning

For now, let's just use the pre-compiled stylesheet. I'm not going to setup Gulp etc. in this post.
> System is a third-party open-source library that adds
> ES6 module loading functionality to browsers.

[ES6 modules](http://www.2ality.com/2014/09/es6-modules-final.html) are not [AMD](http://requirejs.org/docs/whyamd.html) or [CommonJS](http://requirejs.org/docs/commonjs.html). Instead, ES6 has built-in support for modules and as such requires its own loader. Looks like the quickstart guide picked System. We did too.

-----
{% highlight javascript %}
<head>
<title>My first Angular2 CMS!</title>
<!-- add material.css before style -->
<link rel="stylesheet" href="node_modules/material-design-lite/material.css"></script>
<link rel="stylesheet" href="style.css"></script>

<!-- add material.js et al. after styles so as not to impeed page rendering -->
<script src="node_modules/material-design-lite/material.js"></script>
<script src="node_modules/es6-shim/es6-shim.js"></script>
<script src="node_modules/angular2/angular2.js"></script>
</head>
<!-- cms-frontend/index.html -->
<body>
<cms-app></cms-app>
</body>
{% endhighlight %}
-----

#### YMMV
When done, your package.json should look like the following:
Note that we're loading in a "cms-app" module. Let's create cms-app.ts -- this is the file we'll compile down into our actual module in a bit.

------
-----
{% highlight javascript %}
{
"name": "cms-frontend",
"version": "1.0.0",
"description": "An Angular2 CMS Frontend",
"main": "index.html",
"scripts": {
"test": "I love you"
},
"keywords": [
"Angular2",
"love"
],
"author": "The universal self",
"license": "ISC",
"dependencies": {
"angular2": "^2.0.0-alpha.34",
"es6-shim": "^0.33.0",
"material-design-lite": "^1.0.3"
}
/* cms-frontend/cms-app.ts */
/// <reference path="typings/angular2/angular2.d.ts" />

import {Component, View, bootstrap} from 'angular2/angular2';

// Annotation section
@Component({
selector: 'cms-app'
})
@View({
template: '<h1>This is {{ name }}</h1>'
})

// Component controller
class CmsAppComponent {
name: string;

constructor() {
this.name = 'Angular2: CMS';
}
}

bootstrap(CmsAppComponent);
{% endhighlight %}
------
-----

Here we start by including the typescript definitions for angular2, allowing us to import the Component, View, and bootstrap functionality.

### Scaffolding the Angular2 App
I'm not shy to say I don't even know how to make a [module](https://docs.angularjs.org/guide/module) in Angular2. Are there modules in Angular2? Our [guide](http://www.sitepoint.com/writing-angularjs-apps-using-es6/) from the [previous post]({% post_url 2015-08-09-npm-install-angular2 %}) is definitely for Angular1. The guide is dead. Long live the... wait... we need a new guide!
Decorators are an Angular2 thing which describe how the whole component is placed into the page. We've got the @Component decorator defining our tag name, and we have the @View decorator describing what goes into the tag.

An ES6 class. I've aligned it with the tag name and the filename. Consistency is king, at the very least.

Our class can have a property and a constructor. ECMA2015 for the win! Our constructor just asigns a string to the name property. And that's our CMS... for now. So we bootstrap() the component by classname and we're off to the races.

### Typescript compiling
Let's start typescript compiler watching our new code for changes.

-----
{% highlight console %}
tsc --watch -m commonjs -t es5 --emitDecoratorMetadata cms-app.ts
{% endhighlight %}
----

### The first viewing
Quickly installing a local http server and booting it up...

-----
{% highlight console %}
$ npm install -g http-server
$ http-server
{% endhighlight %}
-----

Navigate to http://localhost:8080 and... wait there's nothing there! What?

Just kidding. You should actually see the text "This is Angular2: CMS" in beautiful Roboto Sans, 56px font size. Yes? Okay. No?! Check for console/network errors and make sure your header paths are correct.

Moving on.

### Skipping Login
This CMS will be wide-open. Locally, that is.

If you remember, we skipped auth when building our [REST API with Sails]({% post_url 2015-08-12-Sails-Javascript-REST-API-and-CRUD %}), also. It's easy enough to implement oauth using passport and track auth tokens along with other user information (like, for example, an admin flag). Maybe I'll do another article on adding oauth to an existing CMS and REST Api...

### Material Design Staffer Admin
We just want some basic MDL classes to give us a nice little starter-form. We're gonna put them right into our cms-app.ts view.

Our [API]({% post_url 2015-08-12-Sails-Javascript-REST-API-and-CRUD %}) has support for Staffers (aka `localhost:1337/staff`) and even has a convenient way for adding more during development (aka `localhost:1337/staff/create?name='any'&otherprop='more'`). Note that there is no schema -- a staffer is just a JSON object.

Let's setup a basic form. Just a [textfield](http://www.getmdl.io/components/#textfields-section) with a label and a [submit button](http://www.getmdl.io/components/#buttons-section).

-----
{% highlight javascript %}
/* cms-frontend/cms-app.ts */
@View({
template: `
<form action="#">
<div class="mdl-textfield mdl-js-textfield">
<input class="mdl-textfield__input" type="text" id="name" />
<label class="mdl-textfield__label" for="sample1">Text...</label>
</div>
<button class="mdl-button mdl-js-button mdl-js-ripple-effect">
Save Staffr
</button>
</form>
`
})
{% endhighlight %}
-----

55 changes: 55 additions & 0 deletions _posts/2015-08-29-ionic-isnt-it.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
layout: post
title: "Ionic, isn't it?"
date: 2015-08-29 21:57:00
categories: [programming]
tags: [angular.js, ionic, html5, hybrid apps, yeoman generators, cordova, javascript, javascript frameworks]
---

Making mobile apps is pretty fun if all you have to do is write css and javascript. [Angular](https://angularjs.org/) makes it more fun, and [Generator M](https://github.com/mwaylabs/generator-m) gets us off the ground [pdq](http://www.merriam-webster.com/dictionary/pdq).

## Setting up

1) Install Generator M
2) Make a new directory and generate app scaffolding within that. I like 'tabs' personally.
3) Tada! *note* we aren't stopping here...

Just run `gulp watch` and it will even pop open a local browser for you to see your new app in development (resize your browser to phone-size for best experience :)

## Change things

I'll give you a brief overview of where stuff is and you can change it a little before building your app.

`app/*` and the main module `app/main/*` are where all the cool stuff is. Assets, controllers, templates, styles, etc.

The main index (i.e. app/index.html) loads in our javascript dependencies, application module, and lays out the header and tab based navigation.

Tab templates are in `app/main/templates` -- you start out with list, list details, debug, and tabs.

List is the homepage -- this and other routing is specififed by the angular ui config in main.js. Note the 'otherwise' route.

More details about [where stuff is](https://github.com/mwaylabs/generator-m#file-structure) can be found in the Generator M docs.

## More Options

When making changes, note that there is a [grid system](http://ionicframework.com/docs/components/#grid) (and many other cool [components](http://ionicframework.com/docs/components/)) provided by Ionic. You can also just use [Flexbox](http://www.smashingmagazine.com/2015/03/harnessing-flexbox-for-todays-web-apps/) to lay out your elements -- who really needs a grid system anymore?

Also, I highly encourage exploring the [testing integration](https://github.com/mwaylabs/generator-m#testing) and adding in [protractor](http://angular.github.io/protractor/#/) tests..

## Compiling and Installing

Add the platform of your choice to ionic, build for it, emulate it, and install it on your phone. We're done :)

Here's some helpful commands:
```
gulp build
ionic platform add android
ionic build android
ionic emulate android
```

## Summary

AngularJS can power a mobile app, as well as a web page. Ionic integrates Angular and Cordova quite nicely. Yeoman generators are what you want for speed of setup.

testing is your friend.