Creating a Laravel CRUD application that interacts with WordPress through its REST API using JWT authentication offers a robust solution for managing WordPress content from an external application.
In this tutorial, we’ll explore the process of integrating Laravel’s CRUD operations with WordPress’s RESTful API, securing the communication using JSON Web Tokens (JWT). You will see the complete guide to create WordPress posts, list posts and their update operations with Laravel.
WordPress’s REST API provides a way to access and modify WordPress content externally, while JWT authentication ensures secure and authenticated communication between Laravel and WordPress.
Read More: How To Upgrade My Laravel Project to Latest Version?
Let’s get started.
WordPress Configuration
Set up a WordPress setup and configure the REST API with JWT authentication Using plugins like “JWT Authentication for WP REST API“
>> Install this plugin and activate.
Configure the JWT Secret Key
The JWT needs a secret key to sign the token this secret key must be unique and never revealed.
To add the secret key edit your wp-config.php file and add a new constant called JWT_AUTH_SECRET_KEY
define('JWT_AUTH_SECRET_KEY', 'your-top-secret-key');
Configure CORS Support
To enable the CORs Support edit your wp-config.php file and add a new constant called JWT_AUTH_CORS_ENABLE
define('JWT_AUTH_CORS_ENABLE', true);
Generate JWT Auth Token (Use in Calling APIs)
Once you install plugin, you will get a route by which we can get JWT authentication token value. But we need to pass username and password while calling that.
Auth API URL,
http://example.com/wp-json/jwt-auth/v1/token
Example,
Copy JWT Auth token value for calling REST APIs.
Read More: How To Integrate ChatGPT API in Laravel 10 Tutorial
Laravel Installation
Open terminal and run this command to create a laravel project.
composer create-project laravel/laravel myblog
It will create a project folder with name myblog inside your local system.
To start the development server of laravel –
php artisan serve
URL: http://127.0.0.1:8000
Assuming laravel already installed inside your system.
Application Basic Variables Settings
Open .env file from project folder,
WP_JWT_AUTH_TOKEN="eyJ0eXAiOiJKV1QiLCJhbGciO..."
WP_JSON_POST_URL="https://yourwordpresssite.com/wp-json/wp/v2/posts"
Change your keys values according to your application.
Resource Routes Setup
Open web.php file from /routes folder.
//... use App\Http\Controllers\PostController; Route::resource('posts', PostController::class); //...
Setup CRUD Controller
Back to project terminal and run this command into it,
php artisan make:controller PostController
It will create a PostController.php file inside /app/Http/Controllers folder.
Controller file contains these methods for,
- index(): To list all posts
- create(): To open layout to create post
- store(): To save post data to wordpress database
- edit(): Open edit layout to update post
- update(): Update method to update existing data of post
- destroy(): Delete post method
Open file and write this code into it,
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Http; class PostController extends Controller { // Page: Post list public function index() { $response = Http::get(getenv("WP_JSON_POST_URL")); if ($response->successful()) { $posts = $response->json(); $postArr = collect($posts)->map(function ($post) { return [ 'id' => $post['id'], 'title' => $post['title']['rendered'], 'content' => $post['content']['rendered'], // Add more fields as needed ]; })->toArray(); return view('post-list', compact('postArr')); } else { // Handle error if the request was not successful $error = $response->status(); // Get the HTTP status code // You can also fetch error messages or details using $response->body() } } // Page: Post create public function create(){ return view('post-create'); } // Function: Post create public function store(Request $request) { $request->validate([ 'title' => 'required', 'content' => 'required', 'status' => 'required', ]); $response = Http::withHeaders([ 'Authorization' => 'Bearer '.getenv("WP_JWT_AUTH_TOKEN"), // Replace with your authentication method and token 'Content-Type' => 'application/json', ]) ->post(getenv("WP_JSON_POST_URL"), [ 'title' => $request->title, 'content' => $request->content, 'status' => $request->status, // Set the post status (publish, draft, etc.) // Add other post fields as needed ]); // Check the response if ($response->successful()) { $post = $response->json(); // Retrieve the created post data return redirect()->route('posts.index')->with('success','Post has been created successfully.'); } else { // Handle errors $error = $response->json(); return redirect()->route('posts.create')->with('error','Failed to create post'); } } // Page: Update post public function edit(Request $request) { $postId = $request->post; $url = getenv("WP_JSON_POST_URL") . "/" . $postId; $response = Http::get($url); if ($response->successful()) { $post = $response->json(); // Process the retrieved post data as needed return view('post-edit',compact('post')); } else { // Handle the error response return $response->status(); } } // Function: Update post public function update(Request $request) { $request->validate([ 'title' => 'required', 'content' => 'required', 'status' => 'required', ]); // ID of the post to update $postId = $request->post; // Replace with the actual post ID you want to update // Data to be updated (example: updating the post title) $updateData = [ 'title' => $request->title, // Replace with the new title 'content' => $request->content, 'status' => $request->status ]; $response = Http::withHeaders([ 'Content-Type' => 'application/json', 'Authorization' => 'Bearer '.getenv("WP_JWT_AUTH_TOKEN"), ])->put( getenv("WP_JSON_POST_URL") . "/" . $postId, $updateData); if ($response->successful()) { // Post updated successfully $updatedPost = $response->json(); return redirect()->route('posts.index')->with('success','Post Has Been updated successfully'); } else { // Handle error if the request was not successful $error = $response->status(); // Get the HTTP status code return redirect()->route('posts.index')->with('error','Failed to update post'); } } public function destroy(Request $request) { // ID of the post to delete $postId = $request->post; // Replace with the actual post ID you want to delete $response = Http::withHeaders([ 'Content-Type' => 'application/json', // Add authorization headers if needed for authentication 'Authorization' => 'Bearer '.getenv("WP_JWT_AUTH_TOKEN"), ])->delete(getenv("WP_JSON_POST_URL") . "/" . $postId); if ($response->successful()) { // Post deleted successfully $deletedPost = $response->json(); return redirect()->route('posts.index')->with('success','Post has been deleted successfully'); } else { // Handle error if the request was not successful $error = $response->status(); // Get the HTTP status code return redirect()->route('posts.index')->with('success','Failed to delete post'); } } }
Next, we need to create front-end view files for CRUD operation.
Setup CRUD Blade Layout Views
Create these blade template files inside /resources/views folder,
- post-list.blade.php
- post-create.blade.php
- post-edit.blade.php
Read More: How To Validate Image Upload in Laravel 10 Example
Open each file and write these code
Post list template file: “post-list.blade.php”,
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Laravel CRUD Using WordPress REST API with JWT Tutorial</title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"> </head> <body> <div class="container mt-2"> <div class="row"> <div class="col-lg-12 margin-tb"> <div class="pull-left"> <h3>Laravel CRUD Using WordPress REST API</h3> </div> <h4 class="text-center">Post List</h4> <div class="pull-right mb-2" style="float: right;"> <a class="btn btn-success" href="{{ route('posts.create') }}">Create Post</a> </div> </div> </div> @if ($message = Session::get('success')) <div class="alert alert-success"> <p>{{ $message }}</p> </div> @endif <table class="table table-bordered"> <thead> <tr> <th>ID</th> <th>Post Title</th> <th>Post Content</th> <th width="280px">Action</th> </tr> </thead> <tbody> @foreach ($postArr as $post) <tr> <td>{{ $post['id'] }}</td> <td>{{ $post['title'] }}</td> <td>{{ substr($post['content'], 0, 100) }}</td> <td> <form action="{{ route('posts.destroy',$post['id']) }}" method="Post"> <a class="btn btn-primary" href="{{ route('posts.edit',$post['id']) }}">Edit</a> @csrf @method('DELETE') <button type="submit" onclick="return confirm('Are you sure want to delete?')" class="btn btn-danger">Delete</button> </form> </td> </tr> @endforeach </tbody> </table> </div> </body> </html>
Create Post template file: “post-create.blade.php”,
It will give us an interface such as for Title, Content and Status to create post.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Laravel CRUD Using WordPress REST API with JWT Tutorial</title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"> </head> <body> <div class="container mt-2"> <div class="row"> <div class="col-lg-12 margin-tb"> <div class="pull-left"> <h3>Laravel CRUD Using WordPress REST API</h3> </div> <h4 class="text-center">Add Post</h4> <div class="pull-right" style="float: right;"> <a class="btn btn-primary" href="{{ route('posts.index') }}"> Back</a> </div> </div> </div> @if(session('status')) <div class="alert alert-success mb-1 mt-1"> {{ session('status') }} </div> @endif <form action="{{ route('posts.store') }}" method="POST"> @csrf <div class="row"> <div class="col-xs-12 col-sm-12 col-md-12"> <div class="form-group"> <strong>Title:</strong> <input type="text" name="title" class="form-control" placeholder="Post Title"> @error('title') <div class="alert alert-danger mt-1 mb-1">{{ $message }}</div> @enderror </div> </div> <div class="col-xs-12 col-sm-12 col-md-12"> <div class="form-group"> <strong>Content:</strong> <input type="text" name="content" class="form-control" placeholder="Post Content"> @error('content') <div class="alert alert-danger mt-1 mb-1">{{ $message }}</div> @enderror </div> </div> <div class="col-xs-12 col-sm-12 col-md-12"> <div class="form-group"> <strong>Status</strong> <select name="status" class="form-control"> <option value="">-- Status --</option> <option value="draft">Draft</option> <option value="publish">Publish</option> </select> @error('status') <div class="alert alert-danger mt-1 mb-1">{{ $message }}</div> @enderror </div> </div> <button type="submit" class="btn btn-primary ml-3">Submit</button> </div> </form> </div> </body> </html>
Update Post template file: “post-edit.blade.php”,
It will give us an interface such as for Title, Content and Status to update post.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Laravel CRUD Using WordPress REST API with JWT Tutorial</title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"> </head> <body> <div class="container mt-2"> <div class="row"> <div class="col-lg-12 margin-tb"> <div class="pull-left"> <h3>Laravel CRUD Using WordPress REST API</h3> </div> <h4 class="text-center">Edit Post</h4> <div class="pull-right" style="float: right;"> <a class="btn btn-primary" href="{{ route('posts.index') }}"> Back</a> </div> </div> </div> @if(session('status')) <div class="alert alert-success mb-1 mt-1"> {{ session('status') }} </div> @endif <form action="{{ route('posts.update',$post['id']) }}" method="POST"> @csrf @method('PUT') <div class="row"> <div class="col-xs-12 col-sm-12 col-md-12"> <div class="form-group"> <strong>Title:</strong> <input type="text" name="title" value="{{ $post['title']['rendered'] }}" class="form-control" placeholder="Post Title"> @error('name') <div class="alert alert-danger mt-1 mb-1">{{ $message }}</div> @enderror </div> </div> <div class="col-xs-12 col-sm-12 col-md-12"> <div class="form-group"> <strong>Content:</strong> <input type="text" name="content" value="{{ $post['content']['rendered'] }}" class="form-control" placeholder="Content"> @error('address') <div class="alert alert-danger mt-1 mb-1">{{ $message }}</div> @enderror </div> </div> <div class="col-xs-12 col-sm-12 col-md-12"> <div class="form-group"> <strong>Status:</strong> <select name="status" id="status" class="form-control"> <option value="">-- Status --</option> <option {{ $post["status"] == "draft" ? "selected" : "" }} value="draft">Draft</option> <option {{ $post["status"] == "publish" ? "selected" : "" }} value="publish">Publish</option> </select> @error('address') <div class="alert alert-danger mt-1 mb-1">{{ $message }}</div> @enderror </div> </div> <button type="submit" class="btn btn-primary ml-3">Submit</button> </div> </form> </div> </body> </html>
Application Testing
Run this command into project terminal to start development server,
php artisan serve
URL: http://127.0.0.1:8000/posts
Lists Post,
It will list all posts of wordpress.
Create Post,
When you click on Create Post button, it will open layout to create post.
Update Post,
When you click on Edit button in List Post page, it will open layout to update post with existing data
Delete Post
When click on Delete button of List Post page,
WordPress backend admin panel for Posts data,
That’s it.
We hope this article helped you to learn about Laravel CRUD Using WordPress REST API with JWT Tutorial Example in a very detailed way.
Online Web Tutor invites you to try Skillshike! Learn CakePHP, Laravel, CodeIgniter, Node Js, MySQL, Authentication, RESTful Web Services, etc into a depth level. Master the Coding Skills to Become an Expert in PHP Web Development. So, Search your favourite course and enroll now.
If you liked this article, then please subscribe to our YouTube Channel for PHP & it’s framework, WordPress, Node Js video tutorials. You can also find us on Twitter and Facebook.