WordPress

& The Chamber of

Single Page Apps

Building a sample patronus viewer within a custom wordpress theme

goatronus

David Khourshid

  • @davidkpiano
  • github.com/davidkpiano

Daniel Walker

  • @laser_goat
  • github.com/lasergoat

The Problem

A client needs functionality too complex/custom

for an existing plugin or theme

BUT, you still want all the great

functionality of WordPress

SOLUTION

Within a WordPress theme,

show custom content

within a Single Page App

OUR EXAMPLE CODE

https://github.com/lasergoat/wordcamp-spa

BONUS: homepress

  • local development
  • alternative to VVV
  • vm for each project
  • github.com/lasergoat/homepress

BACKEND SETUP

  • Activate JSON-API Plugin
  • Make Custom Post Type(s)
  • Setup ACF

FRONTEND SETUP

  • Make Short-Tag for SPA
  • Install React or Angular
  • Make Fetch Calls to Backend

CUSTOM post type

functions.php

Text

(CPT)

(ACF)

Advanced custom fields

Attach ACF to post

Older versions of JSON-API don't include ACF meta data when you request a custom post

functions.php

Test api

GET: /api/get_posts/?post_type=patronus

This is the resource which your

javascript frontend will Fetch

NOTE ON API

If complex joins, searching, or other advanced functionality is required,

Custom post types are great for flat data with minimal functionality

use Laravel instead of CPTs

SHORT CODE

functions.php

<div id="app"></div>
<script src="path/to/bundle.js">
</script>

Our Bundle of Joy

  • One bundle.js file
  • Webpack
  • Browserify
  • JSPM
  • Rollup
  • Whatever

Iframes?

Probably.

Ilazy.

import React from 'react';
import ReactDOM from 'react-dom';

class App extends React.Component {
  
  render() {
    // poop out the app
  }
}

ReactDOM.render(<App />, document.getElementById('app'));

What are thooooose?

function mapPatronus(patronus) {
  return {
    id: patronus.id,
    visible: true,
    ...patronus.acf
  };
}
  • Each post is a patronus
  • Each patronus needs a unique id
  • visible = patron matches query
  • Get fields from patronus.acf
componentDidMount() {
  fetch('/api/get_posts/?post_type=patronus&count=99')
    .then((res) => res.json())
    .then((res) => {
      this.setState({
        patronuses: res.posts.map(mapPatronus)
      });
    });
}
  • Get patronuses from API
  • Convert them to JSON
  • Map each patronus using mapPatronus
  • Update app state to have these patronuses

JK. Be glad I'm not live-coding this.

Live-CODING Time!

WordCamp SPA

By Daniel Walker

WordCamp SPA

WordPress and the chamber of single page apps! We demonstrate how to make a simple Patronus Viewer app within a custom WordPress theme.

  • 2,665