Any HTML template with blog section -> Functioning Blog
In this tutorial, we’ll transform any HTML template site you can buy off of themeforest into a functioning laravel based blog system. This is not a beginner tutorial, so I won’t explain every line of code. My previous tutorial is a beginner tutorial. (Give me a little bit and I’ll organize it, I promise).
Project Overview:
- We’ll use one admin template and one public view template. The admin template is called CoreUI Bootstrap. You can download it here. https://coreui.io/product/free-bootstrap-admin-template/
- The free HTML template is called MegaKit. It’s completely free. You can use this template for thistutorial, or a pre-developed HTML site of your choice.
https://themewagon.com/themes/free-bootstrap-4-html-5-business-website-template-megakit/
- Here is the UML diagram
2. Create The Laravel Project
composer create-project laravel/laravel blog
3. Open the blog directory with your code editor and terminal. Then create Post Model and Controller
php artisan make:model Post -m -c
4. This is the Post Migration File
<?phpuse Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;return new class extends Migration
{
public function up()
{
Schema::create(‘posts’, function (Blueprint $table) {
$table->id();
$table->string(‘title’);
$table->text(‘content’)->default(“”);
$table->enum(‘status’, [‘draft’, ‘published’])->default(‘draft’);
$table->string(‘slug’)->unique();
$table->boolean(‘is_comment_authorize’)->default(false);
$table->string(‘excerpt’)->default(“”);
$table->boolean(‘is_in_trash’)->default(false);
$table->timestamps();
$table->foreignId(‘user_id’)->constrained(‘users’)->cascadeOnUpdate()->cascadeOnDelete();
});
}public function down()
{
Schema::dropIfExists(‘posts’);
}
};
6. Create the Comment Model and Controller
php artisan make:model Comment -m -c
7. Create comments table migration file:
<?phpuse Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;return new class extends Migration
{
public function up()
{
Schema::create(‘comments’, function (Blueprint $table) {
$table->id();
$table->string(‘name’);
$table->string(‘email’);
$table->text(‘comment’);
$table->boolean(‘is_approved’)->default(false);
$table->boolean(‘is_in_trash’)->default(false);
$table->foreignId(‘post_id’)->constrained(‘posts’)->cascadeOnUpdate()->cascadeOnDelete();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists(‘comments’);
}
};?>
8. Make Image model and controller:
php artisan make:model Image -m -c
9. Create Image migration files
<?phpuse Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create(‘images’, function (Blueprint $table) {
$table->id();
$table->string(‘path’);
$table->foreignId(‘post_id’)->constrained(‘posts’)->cascadeOnUpdate()->cascadeOnDelete();
$table->timestamps();
});
}/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists(‘images’);
}
};
10. Make BlogCategory model and controller
php artisan make:model BlogCategory -m -c
11. Create BlogCategory migrations file:
<?phpuse Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create(‘blog_categories’, function (Blueprint $table) {
$table->id();
$table->string(‘name’);
$table->string(‘desc’);
$table->string(‘slug’);
$table->timestamps();
});
}/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists(‘blog_categories’);
}
};
12. Association Between Post and Category
As the association between post and category is many to many relationships, we should create a migration for the intermediate table without the model and controller.
php artisan make:migration create_blog_category__posts_table
13. blog_category__posts_table migration
<?phpuse Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create(‘blog_category__posts’, function (Blueprint $table) {
$table->timestamps();
$table->integer(‘post_id’)->unsigned();
$table->integer(‘blog_id’)->unsigned();
});
}/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists(‘blog_category__posts’);
}
};
Post Model (app/Models/Post)
<?phpnamespace App\Models;use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;use App\Models\Image;
use App\Models\User;
use App\Models\Comment;
use App\Models\BlogCategory;
class Post extends Model
{
use HasFactory;
protected $fillable=[
‘title’,’content’,’post_date’,’post_update’,’status’,’slug’,’is_comment_authorize’,’excerpt’,’is_in_trash’, ‘user_id’
];public function feature_image()
{
return $this->hasOne(Image::class);
}public function comments()
{
return $this->hasMany(Comment::class);
}public function post()
{
return $this->belongsTo(User::class);
}public function BlogCategory()
{
return $this->belongToMany(BlogCategory::class);
}public function author() {
return $this->belongsTo(User::class, ‘user_id’);
}
}
BlogCategory model
<?phpnamespace App\Models;use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Models\Post;class BlogCategory extends Model
{
use HasFactory;
protected $fillable=[
‘name’,’desc’,’slug’
];public function Post(){
return $this->belongToMany(Post::class);
}
}
User Model
<?phpnamespace App\Models;// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;use App\Models\Post;class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
‘name’,
‘email’,
‘password’,
];/**
* The attributes that should be hidden for serialization.
*
* @var array<int, string>
*/
protected $hidden = [
‘password’,
‘remember_token’,
];/**
* The attributes that should be cast.
*
* @var array<string, string>
*/
protected $casts = [
‘email_verified_at’ => ‘datetime’,
];public function post() {
return $this->hasMany(Post::class);
}
}
Image Model
<?phpnamespace App\Models;use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;use App\Models\Post;class Image extends Model
{
use HasFactory;protected $fillable = [
‘path’, ‘post_id’
];public function feature_image()
{
return $this->belongTo(Post::class);
}
}
Comment Model
<?phpnamespace App\Models;use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Models\Post;class Comment extends Model
{
use HasFactory;
protected $fillable=[
‘name’,’email’,’comment’,’comment_at’,’is_approuve’,’is_in_trash’,’post_id’
];public function comments() {
return $this->belongsTo(Post::class);
}
}
Reminder to Self: Add Code Explanations later for readers.