Tạo project laravel bằng câu lệnh Chạy thử web demo với lệnh cài đặt lại cấu hình database trong file .env cài đặt thêm laravel-admin vào địa chỉ http://127.0.0.1:8000/admin/ đăng nhập với tài khoản username/password = admin/admin tạo migration bảng category Nội dung của
Tạo project laravel bằng câu lệnh
composer create-project laravel/laravel example-app
Chạy thử web demo với lệnh
cd example-app
php artisan serve
cài đặt lại cấu hình database trong file .env
cài đặt thêm laravel-admin
composer require encore/laravel-admin
php artisan vendor:publish --provider="Encore\Admin\AdminServiceProvider"
php artisan admin:install
vào địa chỉ http://127.0.0.1:8000/admin/ đăng nhập với tài khoản username/password = admin/admin
tạo migration bảng category
php artisan make:migration create_category_table
Nội dung của bảng category sẽ như sau
public function up()
{
Schema::create('category', function (Blueprint $table) {
$table->increments("id");
$table->string("name", 200);
$table->integer("parent_id")->unsigned()->nullable();
$table->foreign("parent_id")->references("id")->on("category")->onDelete("set null");
$table->string("type")->default("cate"); // cate or tag
$table->timestamps();
});
}
tạo bảng posts nội dung bản posts sẽ như sau
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->string('title', 255);
$table->string('image', 512)->nullable();
$table->string('description', 4000)->nullable();
$table->text('content')->nullable();
$table->integer('category_id')->unsigned()->nullable();
$table->foreign("category_id")->references("id")->on("category")->onDelete("set null");
$table->string("category_other", 200)->nullable();
$table->string('keyword', 200)->nullable();
$table->tinyInteger('status')->default(1)->comment("0 là đang chờ, 1 là xuất bản");
$table->timestamps();
});
}
chạy tạo migrate bảng
php artisan migrate
muốn rollback lại migrate trước đó ta chạy lệnh
php artisan migrate:rollback
muốn cập nhật thêm dữ liệu trường dữ liệu ta chạy lệnh ví dụ với bảng posts
php artisan make:migration update_posts_table --table=posts
Tạo model bằng các lệnh
php artisan make:model Category
php artisan make:model Posts
sửa nội dung model Category
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
use HasFactory;
protected $table = 'category';
public $timestamps = true;
}
sửa nội dung model Posts
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Posts extends Model
{
use HasFactory;
protected $table = 'posts';
public $timestamps = true;
}
Tạo autoload bằng cách thêm vào composer.php chỗ autoload đoạn code
"files": [
"app/Helper/common.php"
]
Tạo file app/Helper/common.php
Thêm nội dung vào common.php hàm
function to_slug($str)
{
if(!$str) return '';
$unicode = array(
'a' => 'á|à|ả|ã|ạ|ă|ắ|ặ|ằ|ẳ|ẵ|â|ấ|ầ|ẩ|ẫ|ậ',
'd' => 'đ',
'e' => 'é|è|ẻ|ẽ|ẹ|ê|ế|ề|ể|ễ|ệ',
'i' => 'í|ì|ỉ|ĩ|ị',
'o' => 'ó|ò|ỏ|õ|ọ|ô|ố|ồ|ổ|ỗ|ộ|ơ|ớ|ờ|ở|ỡ|ợ',
'u' => 'ú|ù|ủ|ũ|ụ|ư|ứ|ừ|ử|ữ|ự',
'y' => 'ý|ỳ|ỷ|ỹ|ỵ',
'A' => 'Á|À|Ả|Ã|Ạ|Ă|Ắ|Ặ|Ằ|Ẳ|Ẵ|Â|Ấ|Ầ|Ẩ|Ẫ|Ậ',
'D' => 'Đ',
'E' => 'É|È|Ẻ|Ẽ|Ẹ|Ê|Ế|Ề|Ể|Ễ|Ệ',
'I' => 'Í|Ì|Ỉ|Ĩ|Ị',
'O' => 'Ó|Ò|Ỏ|Õ|Ọ|Ô|Ố|Ồ|Ổ|Ỗ|Ộ|Ơ|Ớ|Ờ|Ở|Ỡ|Ợ',
'U' => 'Ú|Ù|Ủ|Ũ|Ụ|Ư|Ứ|Ừ|Ử|Ữ|Ự',
'Y' => 'Ý|Ỳ|Ỷ|Ỹ|Ỵ',
);
foreach ($unicode as $nonUnicode => $uni) {
$str = preg_replace("/($uni)/i", $nonUnicode, $str);
}
return strtolower(preg_replace(
array('/[^a-zA-Z0-9\s-]/', '/[\s-]+|[-\s]+|[--]+/', '/^[-\s_]|[-_\s]$/'),
array('', '-', ''),
strtolower($str)));
}
Thêm vào Model/Category.php nội dung auto tạo slug
public static function boot()
{
parent::boot();
static::creating(function (Category $item){
$item->slug = to_slug($item->name);
});
}
Thêm vào app/Admin/routes.php 2 dòng
$router->resource("bai-viet", PostController::class);
$router->resource("danh-muc", CategoryController::class);
Thêm ckeditor vào project
composer require laravel-admin-ext/ckeditor
php artisan vendor:publish --tag=laravel-admin-ckeditor
config/admin.php thêm nội dung
'extensions' => [
'ckeditor' => [
//Set to false if you want to disable this extension
'enable' => true,
// Editor configuration
'config' => [
]
]
]
Nội dung của file PostController.php
namespace App\Admin\Controllers;
use App\Http\Controllers\Controller;
use App\Models\Category;
use App\Models\Posts;
use Encore\Admin\Controllers\ModelForm;
use Encore\Admin\Facades\Admin;
use Encore\Admin\Form;
use Encore\Admin\Grid;
use Encore\Admin\Layout\Content;
use Encore\Admin\Show;
class PostController extends Controller
{
use ModelForm;
public function index()
{
return Admin::content(function (Content $content) {
$content->header('Quản lý bài viết');
$content->body($this->grid());
});
}
public function edit($id)
{
return Admin::content(function (Content $content) use ($id) {
$content->header('Sửa cửa bài viết');
$content->body($this->form($id)->edit($id));
});
}
public function create()
{
return Admin::content(function (Content $content) {
$content->header('Tạo bài viết');
$content->body($this->form());
});
}
/**
* Make a grid builder.
*
* @return Grid
*/
protected function grid()
{
return Admin::grid(Posts::class, function (Grid $grid) {
$grid->id('ID')->sortable();
$grid->title('Tiêu đề')->sortable();
$grid->image('Ảnh đại diện')->image();
$grid->description("Mô tả")->display(function ($stt){
return $stt;
});
$grid->created_at("Ngày tạo")->display(function ($date){
return date('H:i:s d/m/Y', strtotime($date));
});
$grid->status("Trạng thái")->display(function ($status){
return $status ? "Phê duyệt" : 'Chưa phê duyệt';
});
$grid->model()->orderBy('id', 'desc');
$grid->filter(function($filter){
$filter->like('title', 'Tiêu đề');
$filter->equal('status', 'Bài đã duyệt')->select([0=>"Bài chưa duyệt", 1=>"Bài đã duyệt"]);
});
});
}
protected function form($id = null)
{
return Admin::form(Posts::class, function (Form $form) use ($id) {
$arrCate = (new Category)->listCate();
$form->text('title', 'Tiêu đề')->rules('required', ['required' => 'Bạn phải nhập trường này']);
$form->textarea('description', 'Mô tả');
$form->image("image");
$form->ckeditor('content', 'Nội dung');
$form->select('category_id', 'Danh mục')->options($arrCate);
$form->multipleSelect('category_other', "Danh mục khác")->options($arrCate);
$form->multipleSelect('keyword', "Từ khoá");
$form->switch("status")->default(true);
$form->saved(function (Form $form) {});
});
}
public function show($id)
{
return Admin::content(function (Content $content) use ($id) {
$content->body(Admin::show(Posts::findOrFail($id), function (Show $show) {
$show->id('ID');
$show->title('Tiêu đề');
$show->descrition('Mô tả');
$show->content('Nội dung')->display(function ($data){
return $data;
});
$show->image('Ảnh đại diện')->image();
}));
});
}
public function destroy($id)
{
}
}
Nội dung của file CategoryController.php
namespace App\Admin\Controllers;
use App\Http\Controllers\Controller;
use App\Models\Category;
use Encore\Admin\Controllers\ModelForm;
use Encore\Admin\Facades\Admin;
use Encore\Admin\Form;
use Encore\Admin\Grid;
use Encore\Admin\Layout\Content;
use Encore\Admin\Show;
class CategoryController extends Controller
{
use ModelForm;
/**
* Index interface.
*
* @return Content
*/
public function index()
{
return Admin::content(function (Content $content) {
$content->header('Quản lý danh mục');
$content->body($this->grid());
});
}
/**
* Edit interface.
*
* @param $id
* @return Content
*/
public function edit($id)
{
return Admin::content(function (Content $content) use ($id) {
$content->header('Sửa danh mục');
$content->body($this->form($id)->edit($id));
});
}
/**
* Create interface.
*
* @return Content
*/
public function create()
{
return Admin::content(function (Content $content) {
$content->header('Tạo danh mục');
$content->body($this->form());
});
}
/**
* Make a grid builder.
*
* @return Grid
*/
protected function grid()
{
return Admin::grid(Category::class, function (Grid $grid) {
$grid->id('ID')->sortable();
$grid->name('Tên danh mục');
$grid->parent_id('Danh mục cha')->display(function ($parent) {
return (Category::find($parent)) ? Category::find($parent)->name : '';
});
$grid->slug('Đường dẫn');
$grid->model()->orderBy('id', 'desc');
$grid->filter(function($filter){
$filter->like('name', 'Tên danh mục');
});
});
}
/**
* Make a form builder.
*
* @return Form
*/
protected function form($id = null)
{
return Admin::form(Category::class, function (Form $form) use ($id) {
$form->text('name', 'Tên danh mục')->rules('required', ['required' => 'Bạn phải nhập trường này']);
$arrCate = (new Category)->listCate();
$form->select('parent_id', 'Danh mục cha')->options($arrCate);
$form->saved(function (Form $form) {});
});
}
public function show($id)
{
return Admin::content(function (Content $content) use ($id) {
$content->body(Admin::show(Category::findOrFail($id), function (Show $show) {
$show->id('ID');
$show->id('name');
}));
});
}
public function destroy($id)
{
}
}
Thêm vào app/Models/Posts.php 2 nội dung
public function getCategoryOtherAttribute($value)
{
return explode(',', $value);
}
public function setCategoryOtherAttribute($value)
{
$this->attributes['category_other'] = implode(',', $value) ? ','.implode(',', $value) .',' : '';
}
public function getKeywordAttribute($value)
{
return explode(',', $value);
}
public function setKeywordAttribute($value)
{
$this->attributes['keyword'] = implode(',', $value) ? ','.implode(',', $value) .',' : '';
}
config/filesystem.php 'disks' điền thêm nội dung
'admin' => [
'driver' => 'local',
'root' => public_path('uploads'),
'url' => env('APP_URL').'/uploads',
'visibility' => 'public',
]
Có thể download source code tại đây