Acorn is a framework for integrating Laravel within WordPress
Write modern PHP in WordPress — Acorn brings Laravel’s developer experience where you need it
Integrate Laravel’s features into your WordPress projects for cleaner, more maintainable code with familiar patterns and tools.
~/Code/
$ composer require roots/acorn
$ wp acorn
USAGE: wp acorn [command] [options] [arguments]
make:command Create a new Artisan command
make:component Create a new view component class
make:composer Create a new view composer class
make:controller Create a new controller class
make:job Create a new job class
make:middleware Create a new HTTP middleware class
make:migration Create a new migration file
make:provider Create a new service provider class
make:queue-table Create a migration for the queue jobs database table
make:queue-table Create a migration for the queue jobs database table
make:seeder Create a new seeder class
migrate:fresh Drop all tables and re-run all migrations
migrate:install Create the migration repository
migrate:refresh Reset and re-run all migrations
migrate:reset Rollback all database migrations
migrate:rollback Rollback the last database migration
migrate:status Show the status of each migration
optimize:clear Remove the cached bootstrap files
package:discover Rebuild the cached package manifest
queue:work Start processing jobs on the queue as a daemon
route:cache Create a route cache file for faster route registration
route:clear Remove the route cache file
route:list List all registered routes
vendor:publish Publish any publishable assets from vendor packages
view:cache Compile all of the application's Blade templates
view:clear Clear all compiled view files
$ wp acorn optimize
INFO Caching framework bootstrap, configuration, and metadata.
config .............................................................. 9.30ms DONE
events ............................................................. 29.91ms DONE
routes .............................................................. 4.99ms DONE
views .............................................................. 50.15ms DONE
Blade templates in WordPress
Use Laravel’s powerful Blade templating engine throughout WordPress. Create cleaner, more maintainable templates with layouts, components, and directives. Render WordPress blocks, emails, and more with the template engine loved by PHP developers worldwide.
Rendering WordPress blocks with Blade
views/blocks/button.blade.php
<x-button
variant="{{ $variant }}"
class="{{ $classes }}"
href="{{ $href }}"
>
{{ $text }}
</x-button>
Example Blade template
views/layouts/app.blade.php
<div class="flex flex-col h-screen">
<div>
@include('sections.header')
</div>
<main>
@yield('content')
</main>
@include('sections.footer')
</div>
Eloquent models for WordPress data
Use Laravel’s powerful Eloquent ORM to interact with WordPress data. Create models for posts, users, and custom tables with relationships, scopes, and clean query syntax.
WordPress Post model
app/Models/Post.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
protected $table = 'posts';
protected $primaryKey = 'ID';
protected $fillable = [
'post_title',
'post_content',
'post_status',
'post_type',
];
public function author()
{
return $this->belongsTo(User::class, 'post_author');
}
public function meta()
{
return $this->hasMany(PostMeta::class, 'post_id');
}
public function scopePublished($query)
{
return $query->where('post_status', 'publish');
}
}
Using the model in a controller
app/Http/Controllers/PostController.php
<?php
// Get published posts with authors
$posts = Post::published()
->with('author')
->latest()
->paginate(10);
// Create new post
$post = Post::create([
'post_title' => 'Hello World',
'post_content' => 'Content here',
'post_status' => 'publish',
'post_type' => 'post',
]);
Laravel migrations for your WordPress projects
Use Laravel’s migration system to manage your WordPress database schema. Create, modify, and version your database structure with elegant PHP syntax.
Create & run migrations via WP-CLI
/srv/www/example.com
$ wp acorn make:migration
┌ What should the migration be named? ─────┐
│ create_example_table │
└──────────────────────────────────────────┘
INFO Migration [create_example_table.php] created successfully.
$ wp acorn migrate
INFO Running migrations.
create_example_table ...................... DONE
Migration file example
database/migrations/create_example_table.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class () extends Migration {
public function up()
{
Schema::create('example', function (Blueprint $table) {
$table->id();
$table->string('example');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('example');
}
};
Laravel routing in WordPress
Create virtual pages and custom endpoints without wrestling with WordPress rewrite rules. Define routes with clean syntax, middleware support, and named routes.
Registering routes
routes/web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;
Route::get('/welcome/', function () {
return view('welcome');
});
Route::get('/api/posts', [PostController::class, 'index']);
Route::get('/api/posts/{id}', [PostController::class, 'show']);
Error handling & logging
Capture and diagnose errors more effectively with Laravel’s exception handling and logging. Track issues in development and production with structured logs.
Advanced logging
example.php
<?php
use Illuminate\Support\Facades\Log;
Log::debug('👋 Howdy');
Log::info('Processing order', [
'order_id' => 123,
'user_id' => 42,
'total' => 99.99
]);
Log::error('Failed to send email', [
'recipient' => 'user@example.com',
'exception' => $e->getMessage()
]);
Background jobs & queues
Process heavy tasks asynchronously with Laravel’s queue system. Perfect for image processing, email sending, data imports, or any task that shouldn’t block WordPress requests.
Queue setup & processing
/srv/www/example.com
$ wp acorn make:queue-table
INFO Migration [create_jobs_table.php] created successfully.
$ wp acorn migrate
INFO Running migrations.
create_jobs_table .......................... DONE
$ wp acorn queue:work
INFO Processing jobs...
Background job example
app/Jobs/ProcessImageUpload.php
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class ProcessImageUpload implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct(
public int $attachmentId
) {}
public function handle(): void
{
$attachment = get_post($this->attachmentId);
$file = get_attached_file($this->attachmentId);
// Generate thumbnails
wp_generate_attachment_metadata($this->attachmentId, $file);
// Optimize image
$this->optimizeImage($file);
// Update post meta
update_post_meta($this->attachmentId, '_processed', true);
}
private function optimizeImage(string $file): void
{
// Custom image optimization logic
}
}
Custom WP-CLI commands
Extend WordPress with custom Artisan commands accessible via WP-CLI. Build powerful maintenance tools, data migration scripts, and automated tasks that integrate seamlessly with your WordPress workflow.
Creating custom commands
/srv/www/example.com
$ wp acorn make:command CleanupDraftsCommand
INFO Console command [app/Console/Commands/CleanupDraftsCommand.php] created successfully.
$ wp acorn wp:cleanup-drafts --days=7
INFO Cleaning up drafts older than 7 days...
INFO Deleted 23 old draft posts.
Command implementation
app/Console/Commands/CleanupDraftsCommand.php
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Models\Post;
class CleanupDraftsCommand extends Command
{
protected $signature = 'wp:cleanup-drafts {--days=30 : Days to keep drafts}';
protected $description = 'Clean up old draft posts';
public function handle(): int
{
$days = $this->option('days');
$this->info("Cleaning up drafts older than {$days} days...");
$count = Post::where('post_status', 'draft')
->where('post_modified', '<', now()->subDays($days))
->delete();
$this->info("Deleted {$count} old draft posts.");
return Command::SUCCESS;
}
}
Controllers for clean APIs
Build robust REST APIs and handle requests with Laravel controllers. Clean separation of concerns, validation, and response formatting for WordPress integrations.
Middleware for request filtering
Filter and transform requests before they reach your application. Handle authentication, rate limiting, CORS, and custom business logic with reusable middleware.
API controller
app/Http/Controllers/PostController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use App\Models\Post;
class PostController extends Controller
{
public function index(): JsonResponse
{
$posts = Post::published()
->with('author')
->latest()
->paginate(10);
return response()->json($posts);
}
public function store(Request $request): JsonResponse
{
$validated = $request->validate([
'title' => 'required|max:255',
'content' => 'required',
'status' => 'in:draft,publish'
]);
$post = Post::create([
'post_title' => $validated['title'],
'post_content' => $validated['content'],
'post_status' => $validated['status'] ?? 'draft',
'post_type' => 'post',
'post_author' => get_current_user_id(),
]);
return response()->json($post, 201);
}
}
Authentication middleware
app/Http/Middleware/AuthenticateAdmin.php
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class AuthenticateAdmin
{
public function handle(Request $request, Closure $next)
{
if (!is_user_logged_in()) {
return response()->json([
'message' => 'Authentication required'
], 401);
}
if (!current_user_can('manage_options')) {
return response()->json([
'message' => 'Admin access required'
], 403);
}
return $next($request);
}
}
Supported Laravel components
Sponsors
Help support our open-source development efforts
Subscribe for updates
Join over 8,000 subscribers on our newsletter to get the latest Roots updates and tips on building better WordPress sites
Looking for WordPress plugin recommendations, the newest modern WordPress projects, and general web development tips and articles?