Dynamic Pages with AngularJS and WordPress

Table of Contents:

Introduction

In part 1 of this AngularJS and WordPress series we wired up a Yeoman AnguarJS app to a WordPress back-end with WP REST API and rendered the title and content of our WordPress back-end as the main page of our AngularJS app. This was a great first start, but mapping our WordPress pages to AngularJS, page-for-page, isn’t terribly useful.

In this instalment I will show you how to dynamically render any page from WordPress based on the URL in our AngularJS app. This becomes useful when your team’s Content Creator creates new pages, we don’t have to add anything new to our front-end.

Let’s get started.

Pretty URL’s with HTML5 History API

First things first, we want our URL’s to clean. By default, AngularJS uses a # in the URL to determine what part of the application to render. But instead we can use the HTML5 History API mode to give us clean URL’s. To do this there are three basic steps; 1) enable the feature in AngularJS, 2) telling our connect server to redirect all requests to /index.html and 3) setting a base url in our index file. This will allow our application to handle all incoming requests.

Enable HTML5 History API

Open app/scripts/app.js and add $locationProvider to the config callback:

.config(function($routeProvider, $locationProvider) {

Then just below that line, add the following:

$locationProvider.html5Mode(true).hashPrefix('!');

Redirect all traffic

For this we need a new npm module, connect-modrewrite. In the terminal:

Set a base URL

Open app/index.html and add a base URL somewhere in the head tag:

<base href="/">

Before carrying on, now would be a good time to fire up your application to make sure your changes worked (or at least didn’t break anything). If everything was done correctly, you should be able to navigate to http://localhost:9000/about and see the following:

Catch-all Route

Now that we’re all set to use pretty URL’s, let’s set up a catch-all route that will handle any otherwise un-handled request and attempt to fetch a matching page from our API.

With yeoman, create a new route:

$ yo angular:route dynamic

This will add a new /dynamic route to our $routeProvider config, add a new dynamic.js controller to app/scripts/controllers and add a new dynamic.html view to app/views. In its current form, this will only handle requests to http://localhost:9000/dynamic. Go ahead and try it. The page should say, “This is the dynamic view.”

This is a great first step, but we want our catch-all route to handle any URL, so let’s replace /dynamic with an optional route parameter. In app/scripts/app.js:

Now we should be able to navigate to any un-handled route and have our dynamic view rendered. For instance, go to http://localhost:9000/foo-bar and you should still see the dynamic view.

Fetching Dynamic Data

We now have a catch-all route to handle any page request, but now we need something to show there. The place to do this is in the route’s resolve option. That way we can fetch the necessary data prior to rendering the page. This will prevent any flash of unstyled content (FOUC).

Go ahead and make any other page in WordPress, navigate to it, and you’ll see that automatically your AngularJS application knows how to fetch and render the data without making a new controller or view for it.

Summary

In this article we went over setting up your YeomanAngularJS app to use HTML5 History API. Then we made a catch-all route to deal with dynamic routes and finally bound those dynamic values to our view. You now have one route, one view and one controller that can handle as many pages as your WordPress site contains.

In future posts I will cover further details like dynamic navigation systems, site configuration, page specific configuration and more. Never stop building.