Rapid Prototyping with AngularJS and WordPress

Table of Contents:

  1. Introduction
  2. Background
  3. Why not just use WordPress
  4. The Tools
  5. Getting Started
  6. Fetching Live Data
  7. Bind to our page
  8. Summary
  9. Other Posts in this Series

Introduction

In this post I am going to show you how to build a rapid prototype web application using AngularJS on the front-end and WordPress on the back-end. This first article will just be a primer to get WordPress and your application communicating. It should take you no more than 1/2 an hour. In future posts I will get into more detail about structuring your dynamic application.

Background

You don’t often think of WordPress as a viable back-end for an AngularJS client-side web application. That’s exactly the solution I put into play when faced with a challenge a few months ago — build a scalable information portal with the following criteria:

  • two weeks to build it
  • scalable from 1 to many hundreds of pages
  • A/B testing “all the things” would become a big part of each page
  • the content, titles, images, navigation, layout, etc, would have to be edited easily and frequently
  • the barrier to entry for making the edits needs to be low

Why not just use WordPress?

For the purposes of fast and flexible A/B testing, I wanted to be able to change the layout dynamically via query strings, JSON config files and dynamic logic. Layout features, like sidebar left or right, form labels above or inside form fields, button style, shape and color, and much more, could all be targeted via query strings, config files and tools like Optimizely. This would be an unwieldy task in a WordPress theme (for me anyhow).

Also, I wanted to have control of how the content was presented without the marketing team having to worry about widgets, plugins, WYSIWYG page builders, etc… I wanted the users to be able to — in one place — input plain text (or markdown) and drop an image in here and there, and have the client side render the users efforts with flexibility. I also wanted the sites to have a fluid, seamless experience without jarring, full page reloads.

And finally, I wanted a micro-site that would include only what I need without all the crufty mark-up, libraries, in-line scripts and styles that can often accompany WordPress themes, plugins and WYSIWYG page builders.

The Tools

You’ll need an environment with the following:

Feel free to set up this environment in vagrant or some such sandbox. Or develop your front-end locally and fetch from a remote (or even pre-existing) WordPress install.

Getting Started

I won’t cover how to install Node.js, Bower, Grunt and Yeoman here. Let’s just assume that you’ve Googled it and know the answers. Just be sure that once you have Yeoman installed, you also have the angular generator as well.

  1. Create your new yo-angular project:
    $ cd ~ && mkdir myapp && cd $_
    $ yo angular
    
  2. Follow the set up instructions and configure your application as desired with the only real dependencies here being angular-routes and angular-sanitize.

  3. Spin up your new app and make sure it works:

    $ grunt serve
    

    You should see something like this:

    yo-generator-angular

  4. Now go ahead and install WordPress. Whether you install it locally or remotely, don’t install it at the root directory. Put it in a subfolder, like /wp/.

  5. Once WordPress is installed, go ahead an install the WP REST API plugin.

    wp-rest-api-plugin

  6. Add a couple lorem ipsum pages to WordPress to fetch in our Angular app.

Fetching Live Data

  1. Now let’s go back to our Angular app and fetch some data. Open app/scripts/controller/main.js which will look like this:

    yo-generator-angular-main-js

  2. In our .controller callback argument list, add $http

    .controller('MainCtrl', function ($http)
    
  3. Remove the boilerplate script:
    this.awesomeThings = [
        'HTML5 Boilerplate',
        'AngularJS',
        'Karma'
    ];
    
  4. And replace it with this (it’s important to note that recent versions of yeoman use ControllerAs in their $routeProvider so the MainCtrl will assume main as the context scope):
    // Instead of $scope, let's use this as main.
    // It's more common to use vm instead, but I use 
    // main here to help illustrate the connection.
    var main = this;
    
    $http.get('//yoursite.url/wp-json/wp/v2/pages?filter[name]=test-page)
    .then(getPostSuccess)
    .catch(getPostError);
    
    function getPageSuccess(response) {
        console.log('success: ,' response);
    }
    
    function getPageError(reason) {
        console.log('error: ,' reason);
    }
    

    This will fetch a page, filtering by name instead of id. If you look in the console you should see the returned object (or an error object). Have a look in this object, under data to see what parts you have available to you.

    Right away you should recognize data[0].content.rendered, data[0].excerpt.rendered and data[0].title.rendered are all components that will fit nicely into any page.

    yo-generator-angular-pages-console

Bind to our page

Now that we can fetch data, let’s bind that data to our page.

  1. First we need to set a couple of scope variables (using main). We’ll do this on the promise of fetching the data:
    function getPageSuccess(response) {
        console.log('success: ', response);
    
        // NEW CODE HERE
        if (response.data && response.data[0]) {
            if (response.data[0].title) {
                main.title = response.data[0].title.rendered;
            }
    
            if (response.data[0].content) {
                main.content = response.data[0].content.rendered;
            }
        } else {
            throw response;
        }
    
        console.log('main: ', main);
    }
    

    Now when you view the console you’ll see the main object contains title and content, just as you had written it in WordPress.

    yo-generator-angular-scope-variables

  2. Open your main view, app/views/main.html and attempt to bind the main variables to some markup.

    <div class="jumbotron">
        <h1>{{ main.title }}</h1>
    </div>
    
    <div class="row marketing">
        {{ main.content }}
    </div>
    

    Oops! The title looks ok, but the content looks like a string of escaped html content. Angular is not parsing any of the html in main.content.

    yo-generator-angular-escaped-html

  3. A safe way around this is to use the ngBindHtml directive instead of {{ }}:

    <div class="jumbotron">
        <h1 ng-bind-html="main.title"></h1>
    </div>
    
    <div class="row marketing" ng-bind-html="main.content">
    
    </div>
    
    

    Now that looks better.

    yo-generator-angular-success

Summary

In this post I showed you a basic connection between an Angular.js app and WordPress using Yeoman and WP REST API. Already, with the limited steps I have shown you, you can create a dynamic, modern SPA web application driven by a user editable content management system.

In future posts I will cover further details like partial views, dynamic navigation, site configuration, page specific configuration and more. I hope you are inspired to go out and build.

Other Posts in this Series

 

Adam Merrifield

 

2 thoughts on “Rapid Prototyping with AngularJS and WordPress

    1. Yes, I’ll get in to that in a few articles. There will be a two pronged approach, back end pre-rendering, as well as HTML5 history API with meta tags for escape fragments. And then their is the fact that Google just renders SPA’s now without issue.

Leave a Reply