GHIJK
<<< Back to the blog

Import posts from WordPress to Statamic

it me
Published on
Warning: This post is over a year old. I don't always update old posts with new information, so some of this information may be out of date.

One of the best things about Statamic is that you have the 💪 of Laravel at your disposal.This makes the task of importing posts from something like WordPress incredibly simple.

I'm spending around 4 hours a week right now with a client coaching them re-platforming their CMS from WordPress to Statamic.

While we've been focused on the template and partial structure initially, the subject of data migration arose at the end of the week.

There were a couple of options open to us with Statamic 2. You could use the WordPress Import addon, or indeed the native Statamic Importer. Neither of those is available to Statamic 3 currently.

Of course, you could opt to spin up a Statamic 2 site, import the posts there and then follow the migration path to Statamic 3 using the Migrator package. There's perhaps an hour or so worth of configuration in that instance.

However, we can do better, and make things easier for us using a Laravel package called Corcel.

Corcel is a collection of PHP classes built on top of Eloquent ORM (from Laravel framework), that provides a fluent interface to connect and get data directly from a WordPress database.

Using Corcel with Statamic

First things, first are we need to install the Corcel package into our Statamic instance

composer require jgrossi/corcel && php artisan vendor:publish --provider="Corcel\Laravel\CorcelServiceProvider"

With the Corcel package installed, we next want to configure the WordPress database that we want to connect to and this can be done inside config/database.php for the Laravel app.

Inside that file, we find an array of database settings as well as an array of database connections. Around line 94 is where we'll define our WordPress database connection and it'll look something like this

'corcel' => [
    'driver'    => 'mysql',
    'host'      => '127.0.0.1',
    'database'  => 'wordpress',
    'username'  => 'root',
    'password'  => 'password',
    'charset'   => 'utf8',
    'collation' => 'utf8_unicode_ci',
    'prefix'    => 'wp_',
    'strict'    => false,
    'engine'    => null,
],

Of course, you'll need to modify these settings to match your own WordPress database settings.

That's all that's needed to create a connection between WordPress and Statamic.

Handling the import of WordPress posts to Statamic

There are a number of ways you can handle the import of the posts but I'm going to use a Laravel command php artisan make:command ImportWP - this stubs our command app/Console/Commands/ImportWP.php

We want to change the signature on line 16 protected $signature = 'import:wp'; - this is what we'll use to trigger our import from the terminal.

Next, we'll change line 23 (really just for informational purposes when we run php artisan) to read protected $description = 'Import posts from WordPress';

The meat of our command will reside within our handle() method. Firstly, we want to get all of the published WordPress posts

$posts = Post::published()
    ->get();

We need to ensure that we also have the Post model from the Corcel package on line 5

use Corcel\Model\Post;

When I'm running something from the command line, I like to have some kind of indication of progress and so I use a progress bar

$bar = $this->output->createProgressBar(count($posts));

$bar->start();

From here, I'll iterate over my WordPress posts

foreach ($posts as $post) {
    $entry = Entry::make()
        ->collection('blog')
        ->slug($post->post_name)
        ->date($post->post_date)
        ->data([
            'title' => $post->title,
            'content' => $post->post_content,
        ]);

    $entry->save();

    $bar->advance();
}

Here we're using Statamic's Entry facade that we import on line 7 use Statamic\Facades\Entry;

I'm mapping entries from WordPress into a blog collection and setting the slug, date, title and content based on what the $post contains.

$entry->save(); is what creates our Statamic markdown file and then $bar->advance(); increases our progress indicator.

Putting everything together, our command looks like this

<?php

namespace App\Console\Commands;

use Corcel\Model\Post;
use Illuminate\Console\Command;
use Statamic\Facades\Entry;

class ImportWP extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'import:wp';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Import posts from WordPress';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $posts = Post::published()
            ->get();

        $bar = $this->output->createProgressBar(count($posts));

        $bar->start();

        foreach ($posts as $post) {
            $entry = Entry::make()
                ->collection('blog')
                ->slug($post->post_name)
                ->date($post->post_date)
                ->data([
                    'title' => $post->title,
                    'content' => $post->post_content,
                ]);

            $entry->save();

            $bar->advance();
        }

        $bar->finish();

        return 'done';
    }
}

That's as much as I need for my import and I can now run php artisan import:wp

You should now have a collection of Markdown files at /content/collections/blog/

Wrapping up

The Corcel package has a lot of features. It can handle authors, taxonomies and even Advanced Custom Fields.

If you're interested in migrating your website from WordPress to Statamic, get in touch and perhaps we can work together.

Thanks for reading.

Tagged: 

statamiclaravel
Leave me a message. If you like what you read here, there's a great chance we could be a good fit. If it's something I don't do, I'll likely know someone who does.
GHIJK