Recently I was tasked with building an API with a Wordpress backend, to which some would say: just use the WP-API plugin. Now, that’s perfectly reasonable, but what if you want to use custom post types, and not use the JSON structure WP-API has decided upon? And what if you want better performance? My answer: Laravel + Wordpress.
If you’ve already tried to make one of these solutions, you’ll probably know that it’s not as easy as it sounds. Heck, that might even be why you’re here!
My solution is based on an environment where you have no say as to where your virtual host is directed (Laravel’s public-folder being the usual suspect), and using Laravel 5.1 (LTS), as this is the lowest common denominator.
I place Wordpress in the base directory of my site, and Laravel in a subfolder called “api”, leaving me with a structure like this:
Now that the files have been unpacked and structured, we’re off to code country!
There are basically three things you need to change to make Laravel work:
- The database config
- Add a base .htaccess file
- The primary route group
- The public index.php file
The database config is pretty much a given. You need to set up your .env-file with the correct database connection information, but what probably forget is that Wordpress operates with a database table name prefix (usually “wp_”), so you either need to hard-code that in the database config file (
api/config/database.php), or change the file to accept
the prefix as a environment variable, like I did:
Now I can set the
DB_PREFIX variable in my .env-file
The second thing you need to do, is add a base .htaccess file to the Laravel installation. You need to do this because Laravel is in a subdirectory, and needs all requests sent to the public folder. In your “api”-folder, add a .htaccess file with the following content:
The third thing you need to make Laravel work is add an encompassing route group, that informs Laravel that it’s operating in a subdirectory. To do that, just go to the route file (
api/app/Http/routes.php) and wrap all of your routes in a route group with the prefix “api” - like so:
The last thing you need, is to include Wordpress in Laravel’s public index.php file (
api/public/index.php). To do this, just add the following lines at the top of the file:
That’s basically what’s needed for Laravel to work in a Wordpress subdirectory.
Besides setting up wordpress to work with your database, you need to add some code. I know, it sucks. But it’s only one thing, well, one theme.
In you theme directory (
wp-content/themes) add a folder. I’ve called mine “api-theme”. Now you just to add three small files:
These files are needed for Wordpress to understand that this is a theme.
This is just basic setup for a theme, nothing fancy here.
This code just redirects the user to the backend, since we don’t need a frontend for our API.
This file is more serious. I spent hours figuring this one out.
Since Wordpress is our default access to the site, it will add a 404 header when we access the API. Not only that, but Laravel will crash from the added headers.
Now you can access both the Wordpress and the Laravel installation.
Of course you need to set up Laravel to actually be able to read the Wordpress data structure. I’ll add a post at a later time, explaining how to do that, but until then I’ll let you have a look at the model trait I’ve been working on to translate the Wordpress data structure into a more standard output: