undefined

I've used quite many CMS over time and Wordpress is one of my favorites. From a developers point of view, it let's you hook into it pretty easy. And from a users perspective, it's admin UI is simple enough, well designed and recognized by many people. Together with Advanced Custom Fields (must have wordpress plugin), Wordpress gives you an extremly easy way to create dynamic content with an super adjustable UI.

The problem is that you end up with a great, fully organized editor UI, but a front-end that has to be written in php, meaning you have to merge php logic with html. Spaghetti.

Also, Wordpress isn't known to be very fast, which is an even more important factor today when you create mobile websites.

Last, you lack control over your process. Lets say you want to flush some content before Wordpress begins to make database calls (which is particulary important when developing mobile first sites). You want to be able to know exactly when something can be flushed, and where to put the logic that takes a little more time to process.

There are, of course, some traditionall solutions to these challenges. Wordpress has some template engines (not many, but they exist). And to make Wordpress fast, you can always use some kind of cache, be it a plugin (WP Total cache etc) for smaller sites, or a full cache system (Varnish etc) for bigger solutions.

But if you want to gain some more benefits, as well as addressing the challenges above, you can use nodejs.

Node?

Node might not be the first thing that comes into mind, but it helps more than you might think. If we let Wordpress handle all admin UI, but write templates that render JSON instead of HTML, we can create a front node server that proxies Wordpress and gives us these benefits:

a. Use any javascript template engine we want (many to choose from). b. Cache any content we want, as long as we want, when we want. c. Control the flow. Flush when we want. Process things when we want. d. Almost no difference in Wordpress devlopment, the only difference beeing that you write your templates to output json instead og html

Since express makes it so easy to set up a server, we almost don't need to code at all. Simplified, these are the only steps you need to make to create a front end server in node:

  1. Set up wordpress as usual.
  2. Instead of creating index.php in your template folder that renders html, let it render json.
  3. Set up a nodejs server with express.
  4. Proxy all requests directly to worpress, but when you get thet answer, merge the json data with your template engine.
  5. Cache the result.

What need should work something like this:

Front end server diagram

Other benefits and some drawbacks

If you got a big team, this aproach also gives you a chance of developing the templates more parallell than traditional PHP develpoment. When you write a standard template for Wordpress, the logic get normally mixed up with HTML, which makes front end development more complicated and therefore might limit who you put on your development team.

Also, Wordpress has a semi-complex javascript loading mechanism wich you can ignore completelly since you can write your template engines how ever you want.

There are, obiously, some drawbacks. You won't be able to use any frontend plugins for wordpress, since you dont want to use anything that will render HTML. This is naturally a big drawback for many developers. For my part, I have realised that most of the plugins we use are adminitration plugins, not front-end plugins.

A bigger drawback might be that the introduction of another server creates more complexity. This is specially true for smaller sites, where this solution might be too much anyway.

For most of our projects, these drawbacks are an OK tradeof.

With a middleware

I created a small middleware to simplify the setup. It takes care of the proxing the calls and gives you a simple cache mechanism. It will also give you control over flushing the first bytes, and some other options, but it exemplifies how easy it is to set up a complete solution. I chose DoT as the template engine because of its speed, but any javascript template engine will do.

First install the middleware frnt, express, and express-dot (for DoT template engine):

npm install express express-dot frnt

Then, write something like this in server.js:

var frnt = require('frnt');
var fs = require("fs");
var path = require("path");
var express = require('express');
var app = express();
var doT = require('express-dot');

// Define where the public files are, in this example ./public
app.use(express.static(path.join(__dirname, 'public')));

// Make sure this is set before the frnt middleware, otherwise you won't
// be able to create custom routes.
app.use(app.router);

// Setup the frnt middleware with the link to the internal server
app.use(frnt.init({
    proxyUrl: "http://localhost:81", // The link to your wordpress site
    layouts: false // We simplify this example by not using layouts
}));

// define rendering engine
app.set('views', path.join(__dirname, "views"));
app.set('view engine', 'html' );
app.engine('html', doT.__express );

app.listen(8080); // listen to port 8080

This gives you the basic setup for a front-end server. You can, naturally, customize this with other template engines, custom routes, and more config options for frnt, but this illustrates how little code you need to get started.

The only thing left here is to make sure wordpress, or whatever system you use for your data, returns json for the same route as what you pass into your front end server.

Naturally we need to configure what result will be rendered by what template, and make sure that template exists, but thats easy a well:

So if the front-end server gets a request for

http://localhost/

It will request this from the wordpress server (with the setup above)

http://localhost:81/

And if you have a php template with the following code:

<?php

    $data = new stdclass();
    $data->post_title = "Start";
    $data->template = 'index'; // the template name to be read by frnt
    $data->posts = array();

    if (have_posts()) {
        while (have_posts()) {
            the_post();
            $post_item = new stdclass();
            $post_item->post_title = $post->post_title;
            $post_item->permalink = get_permalink($post->ID);
            array_push($data->posts, $post_item);
        }
    }

    header("content-type: application/json");
    echo json_encode($data);

frnt will look for a template called index.html and merge the data with the template.

With an index.html like this, its enough to render a site and keep a structured code base:

<!DOCTYPE HTML>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>FOO</title>
</head>
<body>
    <div class="main-list">
        <section class="blog-list">
            {{~it.posts: post}}
            <div class="article-holder post">
                <h2><a href="{{= post.permalink}}">{{= post.post_title}}</a></h2>
            </div>
            {{~}}
        </section>
    </div>
</body>
</html>

As you can see, its simple enough. We can keep Wordpress and its benefits, we use node to improve Wordpress, and we divide content, logic and layout very efficiently. And in the process, we get a frontend that is CMS agnostic. We could exchange the CMS to whichever we want, as long as it returns the same JSON structure.

All files for this example can be found here.