Hi everybody!

Updated Mar 3rd 2015: Are you using Laravel 5? Check these changes!

Updated May 11th 2014: Using Corcel project

Currently I am working on a project where I had to make some choices about technologies and how work with them together. First this project will be developed using Wordpress only. It's a College Group site, where we had to work with 13 schools around the world and each one must has the control of your own content.

This could be made with Wordpress, but I think when the site is not so small maybe you can use another CMS or Framework, because I particularly prefer to work with MVC. So because some decisions inside the company we decided to use Wordpress Admin Panel, that is a very good, use its architecture and its database. So Wordpress will be used to the application back-end, with user control, user permission, etc.

To the front-end we decided to work with Laravel. To query information from the Wordpress database we've used the wordpress functions inside Laravel, so it's much better to work with a MVC Wordpress.

Installing Wordpress and Laravel

Let's install Laravel first using Composer. This will take some while.

composer create-project laravel/laravel

So we have now our Laravel folder structure with everything installed. Now let's install a fresh installation of Wordpress inside Laravel. Here you have to options:

  1. Install Wordpress as a sub-dir of public Laravel folder, like /public/wordpress. So to access your Wordpress Admin you have to go to something like http://example.com/wordpress/wp-admin.
  2. Install Wordpress as a sub-dir of the Laravel's root, like /wordpress. So you will have /app and /wordpress in the same position. For this you have to create another VirtualHost to point to Wordpress installation. You can setup a subdomain lik wp.example.com and poit it to /laravel/folder/wordpress. This way you can access the Admin going to http://wp.example.com/wp-admin.

Removing the Wordpress front-end

For security issues go to /wordpress/index.php file and put this first, to redirect to the Admin login page:

header("Location: ./wp-admin");
exit();

So, when you visit http://wp.example.com or http://example.com/wordpress you are redirected to the Wordpress Admin login page.

Connect Laravel to Wordpress

Now we have to include Wordpress inside Laravel. It's easier than you think. Just edit the public/index.php Laravel file and include the follow before anything:

/*
|--------------------------------------------------------------------------
| Wordpress
|--------------------------------------------------------------------------
|
| Integrate Wordpress with Laravel core
|
*/

define('WP_USE_THEMES', false);
require __DIR__.'/../wordpress/wp-blog-header.php';

Now you can use Wordpress functions with Laravel. Yes, like a piece of cake!!!

Querying Posts

Let's suppose you need to get some posts and show to the view file:

// app/controllers/SchoolController.php

class SchoolController extends BaseController
{
    public function index()
    {
        $query = new WP_Query(array(
            'post_type' => 'school',
            'posts_per_page' => 20,
            'order' => ASC,
            'orderby' => 'post_title',
        ));

        $posts = $query->get_posts();

        return View::make('school.index')->with('schools', $posts);
    }
}

Laravel 5 changes

If you’re using Laravel 5 when you create a WP_Query instance you should receive the error Call to undefined function App\Http\Controllers\WP_Query(). This is because you’re inside App\Http\Controllers namespace, made by default by Laravel 5. Just use new \WP_Query (with the backslash), forcing to call the class without any namespace.

…Continuing…

Maybe you need some Wordpress features but you have to use it from your theme's folder. If you don't know how to create a Wordpress Theme, check this post.

For example, in my project I had to create a "About" page for each school. So I create pages with taxonomies called "SchoolName". After, I create a page with the "About" title and select the "São Paulo's School" term in my taxonomy "SchoolName". But all schools will have the same page structure, right? So I have to create a template page inside my Wordpress theme's folder. This way I can have custom fields to this page and all schools will have the About page looking like the same.

So, create a custom theme, adding a style.css file and a index.php file and activating it from the Wordpress panel. After that create a new file called about.php. Inside it put:

<?php /* Template Name: About page */ ?>

So I created a Template called "About page" and when creating the "About" page I select the "About page" template name too. Now my page has a custom taxonomy and a template name.

Now let's query some pages.

Getting Pages

Now if you have to get information about some page, like "About" page. Remember here that the permalinks from Wordpress won't be used. We are going to use only the Laravel routes and URL's. We are using Wordpress only to fill the database and use its Admin Panel.

/**
 * Getting page from Wordpress
 */

// Getting page by ID
$page = get_post(1234);

// Getting page by slug
$query = new WP_Query(array(
    'post_type' => 'page',
    'posts_per_page' => 1,
    'name' => 'about', // here the 'about' is the page slug you stored in wordpress when creating the page
));
$page = array_shift($query->get_posts()); // first post returned

// Getting page by template name
$templateFileName = 'about.php'; // here you must use the PHP FILE we've created in the theme folder
$query = new WP_Query(array(
    'post_type' => 'page',
    'my-taxonomy-name-here' => 'my-term-slug-here',
    'posts_per_page' => 1,
    'meta_key' => '_wp_page_template',
    'meta_value' => $templateFileName,
));
$page = array_shift($query->get_posts());

So, that's it. Now you can use the power of Laravel with the facilities of Wordpress. So, if you're creating a website and need more organisation to your files you have use both to make your life easier.

You can too use custom database tables to work only with Laravel, using Models, etc. You can join both worlds and have a better final result.

Using Wordpress Corcel

Some time ago I started to create a project based on Eloquent ORM (from Laravel) and Wordpress. The project is hosted at Github and you can get more info here.

You can install it using Composer. Just add jgrossi/corcel in your composer.json file and be happy.

There are much work to do but currently you can use some cool features, like:

Getting posts

// All published posts
$posts = Post::published()->get();
$posts = Post::status('publish')->get();

// A specific post
$post = Post::find(31);
echo $post->post_title;

Working with custom post types

// using type() method
$videos = Post::type('video')->status('publish')->get();

// using your own class
class Video extends Corcel\Post
{
    protected $postType = 'video';
}
$videos = Video::status('publish')->get();

Custom post type and custom fields (meta data)

// Get 3 posts with custom post type (store) and show its title
$stores = Post::type('store')->status('publish')->take(3)->get();
foreach ($stores as $store) {
    $storeAddress = $store->address;
}

Pages

// Find a page by slug
$page = Page::slug('about')->first(); // OR
$page = Post::type('page')->slug('about')->first();
echo $page->post_title;

If you want to contribute with this project you're very welcome. Ideas are welcome too.

Thank you for reading.