laravel-admin/wordpress-helpers
Experimental helpers to run WordPress headlessly behind a Laravel frontend. Installs WordPress via Composer (wpackagist), sets plugin/theme paths, publishes public assets, and exposes /wordpress/wp-admin for setup plus custom post types/taxonomies.
Installation:
repositories and extra configurations to composer.json as specified.composer require laravel-admin/headless-wordpress.config/app.php.php artisan vendor:publish --tag="public".Initial Configuration:
.env is properly configured (e.g., APP_URL, database settings)./wordpress/wp-admin to complete WordPress setup (e.g., admin credentials, site title).First Use Case:
/wp-admin/edit.php?post_type=your_cpt.use LaravelAdmin\HeadlessWordpress\Facades\Wordpress;
$posts = Wordpress::posts()->where('post_type', 'your_cpt')->get();
@foreach($posts as $post)
<h2>{{ $post->post_title }}</h2>
<p>{{ $post->post_content }}</p>
@endforeach
Hybrid CMS + Laravel:
Route::get('/blog', function () {
return view('blog.index', [
'posts' => Wordpress::posts()->get()
]);
});
Custom Post Types (CPTs) as Data Sources:
/wp-admin/edit.php or plugins).$events = Wordpress::posts()
->where('post_type', 'events')
->where('post_status', 'publish')
->orderBy('event_date', 'ASC')
->get();
Taxonomy Integration:
$categories = Wordpress::terms()->where('taxonomy', 'event_category')->get();
$filteredEvents = Wordpress::posts()
->whereHas('terms', function ($query) {
$query->where('taxonomy', 'event_category')->where('term_id', 5);
})
->get();
Media Handling:
/wp-admin/upload.php).$featuredImage = Wordpress::posts()
->where('post_type', 'your_cpt')
->first()
->featured_media()
->url;
API-First Approach:
Route::get('/api/posts', function () {
return Wordpress::posts()->get();
});
class Event extends Model {
public function categories() {
return $this->belongsToMany(Term::class, 'term_relationships')
->where('taxonomy', 'event_category');
}
}
$posts = Cache::remember('wordpress_posts', now()->addHours(1), function () {
return Wordpress::posts()->get();
});
Route::middleware(['ip', 'admin'])->group(function () {
Route::prefix('wordpress')->group(...);
});
Outdated Package:
laravel/framework, wp-cli).Database Conflicts:
wp_ → wp_old_).File Permissions:
public/wordpress, public/uploads).chmod -R 755 public/wordpress and ensure storage/ is writable.Caching Headaches:
wp_cache) may conflict with Laravel’s cache.// In WordpressServiceProvider or a custom plugin
define('WP_CACHE', false);
Plugin/Theme Dependencies:
public/mu-plugins) for critical functionality to avoid conflicts.Query Logs: Enable WordPress query logging to debug slow queries:
// In a custom plugin or service provider
define('SAVEQUERIES', true);
Check logs in /wp-admin/tools.php or via global $wpdb; print_r($wpdb->queries).
Laravel + WordPress Logs:
storage/logs/laravel.log.error_log.Common Errors:
/wordpress/wp-admin/install.php).php artisan route:clear) and WordPress rewrite rules (/wordpress/wp-admin/options-permalink.php).Custom Query Builders: Extend the package’s query builder to support custom fields (ACF, Pods):
// Example: Add ACF support
Wordpress::extend(function ($query) {
$query->addSelect('post_meta.meta_value as acf_field')
->leftJoin('wp_postmeta as post_meta', 'posts.ID', '=', 'post_meta.post_id')
->where('post_meta.meta_key', 'like', 'acf_%');
});
Webhooks for Real-Time Updates: Use WordPress actions to trigger Laravel events:
// In a custom plugin
add_action('save_post', function ($postId) {
event(new \App\Events\WordpressPostUpdated($postId));
});
Headless Mode: Disable WordPress frontend rendering entirely by redirecting all requests to Laravel:
// In a custom middleware
public function handle($request, Closure $next) {
if ($request->is('wordpress/*')) {
abort(404); // Or redirect to Laravel
}
return $next($request);
}
Localization: Override WordPress translations in Laravel:
// In a service provider
add_filter('gettext', function ($translated, $text, $domain) {
if ($domain === 'default' && strpos($text, 'WordPress') !== false) {
return 'Laravel + WordPress';
}
return $translated;
}, 10, 3);
.env Variables:
Ensure these are set for WordPress:
WP_HOME=https://your-app.com
WP_SITEURL=https://your-app.com/wordpress
// In a custom plugin
add_action('wp_enqueue_scripts', function () {
wp_dequeue_script('jquery');
wp_enqueue_script('jquery', asset('js/jquery.min.js'), [], null, true);
}, 9999);
.gitignore to avoid bloating repositories:
public/wordpress/wp-config.php
public/uploads/
public/languages/
How can I help you explore Laravel packages today?