Laravel + WordPress Part 2: The Laravel Part

Now that we have WordPress all set up, and secured, we can move on to setting up the Laravel portion of the process. 

If you haven’t read Part 1, you can read it here.

Now that we have WordPress all set up and secured, we can move on to setting up the Laravel portion of the project.

Setting up the laravel part

Now that you have WordPress installed in your public > blog folder, we can set up the connections in your Laravel project.

Open config > database.php and add the snippet below with the details set to your database’s info.

'wordpress' => [
    'driver'    => 'mysql',
    'host'      => 'localhost',
    'database'  => 'your_db_name',
    'username'  => 'your_user',
    'password'  => 'your_password',
    'charset'   => 'utf8',
    'collation' => 'utf8_unicode_ci',
    'prefix'    => 'wp_',
    'strict'    => false,
    'engine'    => null,
],

Two things to call attention to in the snippet above. First, is the name of the connection. I called it ‘wordpress’, but you can all it whatever you like. Second, is the ‘prefix’ key. If you are using WordPress, all tables have the ‘wp_’ prefix on them, so putting this in here is VERY important, so that you don’t have to type ‘wp_’ a bazillion times if you are pulling info from your blog to other pages as I do both here and at Patternography.

Now that we have our database connection set up, there is an optional step to follow. If you are planning on pulling the entirety of post_content anywhere, we need to add the functions.php file to our composer.json, then run composer update in your project. This makes the wpautop() function available to our project.

If you are not going to be using the entirety of a blog post’s content anywhere, you can skip this step.

"autoload": {
    [...],
    "files": [
        "public/blog/wp-includes/formatting.php"
    ]
},

Now that we have all of this set up, we’re ready to roll. Make the controller and corresponding view files in your project if you haven’t already.

FullPostController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\DB;

class FullPostController extends Controller
{

    public function index()
    {
        $post = DB::connection('wordpress')
            ->table('posts')
            ->join('users', 'posts.post_author', '=', 'users.ID')
            ->select(array('posts.post_title', 'posts.post_content',
               'users.display_name', 'posts.post_name'))
            ->where('post_status', '=', 'publish')
            ->orderby('post_date', 'desc')
            ->first();

        $post_content = wpautop($post->post_content);

        return view('home', compact('post', 'post_content'));
    }

}

In the code above, the aim is to collect data to display one blog post’s title, author, and content in a view. This is where the name of the database connection is important. If you don’t specify the connection by name in DB::connection, you will use your default DB credentials which will fail since your blog isn’t in your standard DB for the project.

The $post variable then stores the return of the eloquent query from your wordpress connection, then the $post_content variable applies WordPress’ formatting to the post_content returned in the $post object. You then send both variables to your view, which we explore below.

fullpattern.blade.php

<div id="home-post">
    @if($post && $post_content)

        <h2>
            <a href="/blog/{{ $post->post_name }}">
                {{ $post->post_title }}
            </a>
        </h2>

        <div id="author">by: {{ $post->display_name }}</div>
        <div>
            {!! $post_content !!}
        </div>

        <div id="go-to-post">
            <a href="/blog/{{ $post->post_name }}">
                <h5> >>> </h5>
            </a>
        </div>

    @endif
</div>

Check that the variable exists, and has content, then get the title, author display name, post content, and the url you’ll be using. In this example, there is no looping because I only get the singular most recent blog post from the database to be on the page, but looping is possible here (and will be shown later in the post). If you are going to use pretty urls, be sure to turn on that functionality in WP settings.

A Note on Pretty URLS

I’m using the pretty urls on Patternography, though I am not on NextJen Mobile. I need to revisit pretty urls at a later date, because they work fine in production on PTY, but not on NJM, and I currently don’t have the bandwidth to figure out why.

If you are testing this using homestead on your local machine, you will not be able to use pretty urls. You do not have access to what you need to in homestead to be able to make them work.

This next example will use the standard URLs and show how to use excerpts. If you are going to use excerpts, you need to turn on excerpts for posts, and then you’ll need to suppress the excerpt from showing on the actual blog, unless you want it there, but I chose to suppress it via CSS.

ExcerptController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\DB;

class BlogController extends Controller
{
    public function summaryPosts()
    {
        $posts = DB::connection('wordpress')
            ->table('posts')
            ->select(array('posts.post_title', 'posts.post_excerpt',
               'posts.post_name', 'posts.ID'))
            ->where(array(['post_status', '=', 'publish'],['post_type', '=', 'post']))
            ->orderby('post_date', 'desc')
            ->take(4)
            ->get();

        return view('blog/summary-posts', compact('posts'));
    }
}

Much like the previous example, we need to get the information to display. You’ll see that instead of post_name we get ID to build the plain URLs to the post(s), and the post_excerpt. I use ->take(4) to get the newest four blog posts instead of every blog post I’ve ever written.  Because I can control the excerpt given, I don’t apply the wpautop() function to the excerpt. I know that I will only ever use the first paragraph, no matter how small it is, in my excerpt so I don’t need the formatting of an entire post.

excerpt.blade.php

<div>

    @if(isset($posts) && !empty($posts))

        @foreach($posts as $post)
            <div>
                <h4><a href="/blog/?p={{ $post->ID }}"><strong>{{ $post->post_title }</strong></a></h4>
                <p>{{ $post->post_excerpt }}... <a href="/blog/?p={{ $post->ID }}"> <em>read more ></em> </a></p>
            </div>
        @endforeach

    @endif

</div>

Like in the previous example, we check the $posts variable is there and not empty before proceeding. In this example we use a @foreach loop to create the view for the user, and show all four post excerpts. You’ll also notice that for the URL to the post, we do a little more work, and add the /?p= before dropping in the post ID. This is instead of using post_name that you use for pretty urls.

Now, I’m not sure why pretty URLs works in Patternography and not here on NextJen Mobile, but I’m guessing it has something to do with migrating between servers, and I missed something when I moved NJM to its current home. But you can bet I’ll write about it if I figure it out, I just don’t have the energy to take down my production site for the hours it would take to troubleshoot for something as small as this.

Suppressing excerpt on main blog pages

Because I use the first paragraph of each post as the excerpt, it would obviously be very repetitive to have the excerpt right under the title of the post and then immediately be the first thing you read again. If you are using your own theme, just add this to the styles.css you created with that theme. If you are not using your own theme, you can directly edit the CSS in your theme, but any changes you make will be wiped out after any updates. Making a child theme is a better long term solution, but you are welcome to do whatever suits you best.

.entry-summary {
    display: none;
}

one last note

You may have, at this point, realized I haven’t said anything about routing. You’re right, I didn’t. WordPress handles all of its own routing, and when you land on your /blog, you’ve left Laravel and landed in WordPress. Due to this, there is no need to add a /blog route to your laravel project. Even though I know this to be the case, it still wigs me out a bit to not have the route there.

I think that pretty much covers everything you need to incorporate WordPress into a Laravel project!

Happy Coding!

 

One thought on “Laravel + WordPress Part 2: The Laravel Part”

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.