Angular 2 and WordPress Theme Setup

October 1, 2016 by Stuart Kuentzel

Note: This has been updated to reflect the final release of Angular 2.0 and WordPress incorporating the API into their core. The full source code can be viewed on GitHub.

Today, we’ll be building a simple WordPress theme using Angular 2.0, the Angular CLI, and the WP REST API 2 plugin. The CLI is still in beta, but WordPress just recently incorporated the API into their core. No plugin needed.

This is the first of a string of posts on building with WordPress and Angular 2. For today, our project will simply show a list of posts.

The goal is to create a WordPress theme that runs an app and displays content created in the WordPress admin area.

This tutorial starts from a running install of WordPress somewhere, either locally or on a server. We’ll be downloading a bunch of packages via npm. Everything else we’ll be building from the ground. Let’s dive right in.

CLI Magic

We’ll start by getting the Angular CLI running. This is a new feature rolled out with Angular 2, and it’s super powerful. Head over to their GitHub to read full documentation and more info about installation.

Fire up your terminal and run npm install -g angular-cli@latest. This means it will be install globally on your machine, and you can use it anywhere.

Once it’s installed, in the terminal cd to a folder you want your project to live. If you’re not too familiar with command line stuff, no fret, in Finder open the folder you want your project to live and launch terminal from there.

Once you’re in the folder you want your project to live, in the terminal run ng new wpng2. We’re telling the CLI to create a new Angular 2 project named ‘wpng2’. In the terminal, run cd wpng2. Now we’re inside of our project and ready to use the CLI. If you feel like it, run ng serve and open localhost:4200. You’ll see your bare bones app hanging out there.

Exploring the New Project

Open the project we just created in a text editor of your preference. The CLI has set up a lot of stuff for us, including all of our configs, the src for our application, and necessary dependencies. Also included is an e2e folder for testing the app, which is beyond the scope of this tutorial. We’ll be mostly working in the src folder.

If we open up the src folder, you’ll find some config files necessary for us to use TypeScript, as well as our index.html, which is the base of the Angular 2 app. Inside of index.html, you’ll see an HTML element <app-root>Loading...</app-root>. Our Angular 2 app is looking for that, and is going to load our entire app inside of it.

You’ll also find an app folder. This is where we’re going to be building all the different pieces of our app. As we work through, you’ll get a firmer grasp of how these pieces create the application.

Adding WordPress to the Mix

If you’re familiar with WordPress theme development, you might know there are 3 necessary files to create a WP theme. We’re going to add those to the root of our wpng2 project. First, create an index.php file. You might be thinking, “why do that? Inside of the src folder is already an index.html file”. Well, you thought right. We’re creating this just to satisfy WordPress, so we can activate the theme. We’re going to require index.html inside of index.php. Inside of index.php write…

index.php

<?php require get_template_directory()."/dist/index.html"; ?>

Yup, that’s it. We’re pulling everything from /dist/index.html and putting it into our WordPress index.php file. Right now we don’t have a dist folder in our project, but once we compile our app from TypeScript into JavaScript, the CLI is going to create a dist folder where our compiled app lives.

Moving on, we’ll create the WordPress-required style.css and functions.php, also in the root.

style.css

/*
Theme Name: wpng2
Author: Stuart Kuentzel
Author URI: http://doppiaeast.com
*/

functions.php

<?php

?>

This is a bit against the norm, usually we load all of our css and javascript files in functions.php. We can still use functions.php if we want, but we’re going to let Angular 2 load all of the app dependencies we need.

Now, we’re all set up for the theme. Just make sure, in your WP admin area, that you have the WP REST API 2 plugin downloaded and activated. (Update: If you have at least WordPress 4.7, no plugin needed) This is what the app is going to be pinging for data.

Setting Up Posts

Let’s set up an area to display posts. Inside of /src/app go ahead and make a new folder called posts. Inside of that, we’re going to create a post class. This is done to keep our code clean and organized. In the terminal, run ng g class /posts/post.

Next, we’re going use the CLI to generate a new component inside of this folder to show a list of posts. Run ng g component /posts/post-list. In your text editor, check the posts folder we just created. You’ll see that the CLI has created a folder for us called post-list, which includes the necessary files for a component in Angular 2.

At this point you might be asking, “ok, ok, but what’s a component?”. If you are familiar with Angular 1, you can think of them kind of like a controller. If you’re not familiar with Angular at all, no probs. Our “components” are modular little pieces of code that perform specific functions. This way our code is organized in a way that if something breaks, we know where to look to find it. It’s awesome.

We’re working with a lot of new stuff here, so let’s take a sec to explore what the CLI just gave us. The post-list folder contains 4 files.

post-list
| - post-list.component.css
| - post-list.component.html
| - post-list.component.spec.ts
| - post-list.component.ts

Starting from the top… as you might guess, post-list.component.css is going to be where the styles live for the component.

Next we have post-list.component.html. This is where the template for our component will live. It’s what the user will see.

After that we have post-list.component.spec.ts, which can be used for testing if you’re so inclined.

Last, we have post-list.component.ts. This is where the functionality of our component will live. In this tutorial, we’ll be focusing mostly on post-list.component.ts and post-list.component.html.

Routing

We want to show our post-list as soon as a user hits the index page. In order to do that, we have to configure our router. We want our post list to take control of the app as soon as the user hits the homepage. In previous versions of the CLI, it had already set up the routing files we need, but as of beta.17, no routing file exists when you create a new project. So let’s create one. In the /app folder, create a file called app-routing.module.ts.

// app-routing.module.ts

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { PostListComponent } from './posts/post-list/post-list.component';

const routes: Routes = [
  {
    path: '',
    component: PostListComponent,
    pathMatch: 'full'
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  providers: []
})
export class Wpng2RoutingModule { }

What we’re doing here is importing the PostListComponent we just created, and saying that it will take control of the application when it matches an empty path. Note, at the very bottom there, we’re exporting it as Wpng2RoutingModule.

We’re going to have to now include our routing module in the app itself. In app.module.ts, add…

// app-routing.module.ts

...

import { Wpng2RoutingModule } from './app-routing.module';

@NgModule({
  declarations: [
    AppComponent,
    PostListComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    Wpng2RoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

We’re importing the routing module at the top with the rest of our imports, and inside of @NgModule, we’re adding it to our list of imports.

Finally, we’ll have to add a router-outlet where the navigating will take place. Inside of app.component.html, add…

app.component.html

// app.component.html

<h1>
  {{title}}
</h1>
<router-outlet></router-outlet>

Now, if you run ng serve from your command line and open localhost:4200 in your browser, you should see both “app works!” followed by “post-list works!”.

That’s all great, but how do we change that? Still in the /app folder, open up app.component.ts. Inside, change the title variable to whatever you want…

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'Doppia East';
}

Now open app.component.html. You’ll see {{title}}. This is one of the ways Angular binds data. We’re setting the variable inside of the component, and the value is displayed in the template.

Creating a Service

In Angular 2, a service handles the logic behind getting the data. After we get the data, we pass it into our component. This keeps everything clean, and allows us to “share services” between components. For example, whenever we want to get posts from WordPress, we have a service to make the API call and return the post.

Let’s have the CLI create a service in the posts folder for us. If ng serve is still running, stop it by using ctrl + c. Then run ng g service /posts/posts. Now in our posts folder, we have a new file called posts.service.ts.

// posts.service.ts

import { Injectable } from '@angular/core';

@Injectable()
export class PostsService {

  constructor() { }

}

The CLI generated this basic service for us, but we’re going to have to do some work to get data back from the WP API. First, let’s import some more stuff we’ll need to use in the posts service…

// posts.service.ts

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';

import { Observable } from 'rxjs/Observable';

import 'rxjs/add/operator/map';

import { Post } from './post';

...

Now that we’ve imported everything we need, we’ll write the functionality behind getting some posts from the API.

// posts.service.ts

...

private postsUrl = "{YOUR-SITE-NAME}/wp-json/wp/v2/";

constructor(private http: Http) { }

getPosts(): Observable<Post[]> {

    return this.http
      .get(this.postsUrl + 'posts')
      .map((res: Response) => res.json());

}

This is saying, when we call the getPosts function inside of this service, it’s going to hit the WP API and return some posts. Remember when we created that Post class to keep things organized? We’re telling our code that when this function is called, we’ll return an array of Posts. You can take a look at different calls you can make to the API on the WP API 2 website.

Using the Service

Now that we’ve created a service, we need to call it in our post-list component. At the moment, post-list.component.ts looks like this…

// post-list.component.ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-post-list',
  templateUrl: './post-list.component.html',
  styleUrls: ['./post-list.component.css']
})
export class PostListComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

The CLI did a nice job setting up a bare-bones component, but we’ll need to do some work. Let’s import some stuff we need for the component to work the way we want…

// post-list.component.ts

import { Component, OnInit } from '@angular/core';
import { Post } from '../post';
import { PostsService } from '../posts.service';

@Component({
  selector: 'app-post-list',
  templateUrl: './post-list.component.html',
  styleUrls: ['./post-list.component.css'],
  providers: [PostsService]
})

...

We’re importing our Post class and the PostsService we just created. Also, inside of the @Component, we’re adding a new line called providers. This is basically telling the component where it’s getting its data from.

Finally, we’ll tell our component to return posts through the posts service.

// post-list.component.ts

...

export class PostListComponent implements OnInit {

  posts: Post[];

  constructor( private postsService: PostsService ) { }

  getPosts(){
    this.postsService
      .getPosts()
      .subscribe(res => {
        this.posts = res;
      });
  }

  ngOnInit() {
    this.getPosts();
  }

}

At the top, we’re creating a variable and telling it to expect a list of posts, with the class of Post. Inside of our constructor, we’re creating an instance of our service. Next, we’re creating the getPosts function for this component. Inside of that, we’re using the getPosts function inside of our service. When posts are returned, we’re tying the returned posts to the posts variable we created above. Finally, on ngOnInit, which fires when the component is loaded, we called the getPosts function.

Listing the Posts

Lastly, we need to show the list of posts to the user. Inside of post-list.component.html, add…

// post-list.component.html

<ul>
  <li *ngFor="let post of posts">
    {{ post.title.rendered }}
  </li>
</ul>

This is Angular’s way of looping through everything inside of our posts variable we made in the post-list component. Now if you run ng serve and go to localhost:4200 in your browser, if you’ve created any posts in the WordPress admin area, you’ll see a list of their names.

If you want to see what other data the API has given back, just open up your browser’s inspector, check the Network tab, click ‘posts’ and preview. You’ll see a list of objects (posts). By clicking into them, you can explore all the data the API has provided.

Building It

This is all awesome on localhost, but how do we get our theme/app uploaded to WordPress and working?

Now, we’re going to have to tell the CLI to build our app. In the CLI, run ng build --prod --deploy-url="/wp-content/themes/{THEME_DIRECTORY_NAME_ON_SERVER}/dist/". For me, my theme name is “wpng2”, so I’ll run ng build --prod --deploy-url="/wp-content/themes/wpng2/dist/". This is going to compile our entire app and all of its dependencies, and output it to a folder called dist in the root directory. That’s it!

In Filezilla or whatever FTP you use, navivate to /wp-content/themes/ and create a directory called wpng2. All you have to do is upload index.php, style.css, functions.php, and the /dist folder to your newly created wpng2 folder. Go into your admin area and activate that shit, and you’ve got a live web app running on WordPress! We covered a ton of ground!

In the next article, we’ll be clicking into posts, loading the content, and changing the URL to match the selected post. In the meantime, build something cool!

© 2018