Laravel integration
How to use Bootstrap 5 with Laravel - free starter
This guide will provide you with a free template for a Laravel application, with MySQL database and Bootstrap 5 front-end.
Prerequisites
Before starting the project make sure to install the following utilities:
Creating a new Laravel application
Let's create a fresh Laravel application so that we can go through all the steps together. For this tutorial we'll be using MySQL database.
Step 1
Creating Laravel project.
You can initialize a MDB GO starter. Simply run the following command:
Note: If you don't have MDB CLI installed yet, you can do it with NPM: npm install -g mdb-cli
.
Now log in with your MDB account, type: mdb login
.
If you don't have account yet you can create one using mdb register
command.
mdb backend init php-free-laravel
Step 2
Creating a MySQL database.
In order to create a new database you need to run the following command.
mdb database init -db mysql8
- Create a new user
- Provide username, password, database name and description.
CLI will display your username, password, database name and connections string. You will need this data in the next step. Now you can go to phpMyAdmin where you will be able to handle the administration of the MySQL database.
Note: the password must contain at least one uppercase letter, one lowercase letter, one number, one special symbol and have minimum length of 8.
Step 3
After initialization just go to the newly created project directory and open the .env
file.
After that edit the config values that start with DB_
.
You should make use of credentials that's been shown to you in the previous step.
In my case the updated values look like this:
DB_CONNECTION=mysql
DB_HOST=mysql.db.mdbgo.com
DB_PORT=3306
DB_DATABASE=your_database_name
DB_USERNAME=your_username
DB_PASSWORD=your_password
Step 4
Create a table.
Go to phpMyAdmin, log in, and add a table, which name will be a plural form of created model. For example on purpose of this tutorial: tasks. Then create a three columns: id (type: int + auto increment), name (type: text) and description (type: text).
Step 5
Navigate to you project direction and install Laravel dependencies using Composer.
php-free-laravel
is the name from MDB GO starter (you can change whatever you like).
composer install
Note: If after this process you got an error bound installation - try
composer install --ignore-platform-req=ext-fileinfo
or composer update --ignore-platform-reqs
.
To Do App with MDB
Step 1
Create a model. You can use built in Laravel pre-made function: php artisan make:model Task
,
where Task
is your custom name (you can change it whatever you like).
Nevertheless this model should being inserted in app/Models
directory and looks like this:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Task extends Model
{
use HasFactory;
public $timestamps=false;
}
Step 2
Now create a controller for handling an endpoints. You can use built in Laravel pre-made function: php artisan make:controller TaskController
, where TaskController
is your custom name (you can change it whatever you like). Nevertheless this controller should being inserted in app/Http/Controllers
directory and looks like this:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Task;
class TaskController extends Controller
{
function addTask(Request $req) {
$task=new Task;
$task->id=$req->id;
$task->name=$req->name;
$task->description=$req->description;
$result=$task->save();
return redirect()->back();
}
function editTask(Request $req) {
$task= Task::find($req->id);
$task->name=$req->name;
$task->description=$req->description;
$result=$task->save();
return redirect()->back();
}
function deleteTask($id) {
$task=Task::find($id);
$result=$task->delete();
return redirect()->back();
}
}
Step 3
Add routes for newly created controller in api.php
file (found in routes
folder in root directory).
use App\Http\Controllers\TaskController;
...
Route::get('task/{id}', [TaskController::class, 'getTask']);
Route::post('task', [TaskController::class, 'addTask']);
Route::put('task', [TaskController::class, 'editTask']);
Route::delete('task/{id}', [TaskController::class, 'deleteTask']);
Step 4
One more route must be set inside web.php
.
use App\Http\Controllers\TaskController;
...
Route::get('/', function () {
$tasks = \App\Models\Task::all();
return view('welcome' , ['tasks' => $tasks]);
});
Step 5
Now all we need is to write some code in resources/views/welcome.blade.php
.
This is the layout of the page and the place where all the requests will be sent from.
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Material Design for Bootstrap - Laravel</title>
<!-- Font Awesome -->
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.2/css/all.css" />
<!-- Google Fonts Roboto -->
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap"
/>
<!-- MDB -->
<link rel="stylesheet" href="css/mdb.min.css" />
<!-- Styles -->
<style>
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}a{background-color:transparent}[hidden]{display:none}html{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}*,:after,:before{box-sizing:border-box;border:0 solid #e2e8f0}a{color:inherit;text-decoration:inherit}svg,video{display:block;vertical-align:middle}video{max-width:100%;height:auto}.bg-white{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.bg-gray-100{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.border-gray-200{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.border-t{border-top-width:1px}.flex{display:flex}.grid{display:grid}.hidden{display:none}.items-center{align-items:center}.justify-center{justify-content:center}.font-semibold{font-weight:600}.h-5{height:1.25rem}.h-8{height:2rem}.h-16{height:4rem}.text-sm{font-size:.875rem}.text-lg{font-size:1.125rem}.leading-7{line-height:1.75rem}.mx-auto{margin-left:auto;margin-right:auto}.ml-1{margin-left:.25rem}.mt-2{margin-top:.5rem}.mr-2{margin-right:.5rem}.ml-2{margin-left:.5rem}.mt-4{margin-top:1rem}.ml-4{margin-left:1rem}.mt-8{margin-top:2rem}.ml-12{margin-left:3rem}.-mt-px{margin-top:-1px}.max-w-6xl{max-width:72rem}.min-h-screen{min-height:100vh}.overflow-hidden{overflow:hidden}.p-6{padding:1.5rem}.py-4{padding-top:1rem;padding-bottom:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.pt-8{padding-top:2rem}.fixed{position:fixed}.relative{position:relative}.top-0{top:0}.right-0{right:0}.shadow{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.text-center{text-align:center}.text-gray-200{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.text-gray-300{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.text-gray-500{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.text-gray-600{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.text-gray-700{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.text-gray-900{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.underline{text-decoration:underline}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.w-5{width:1.25rem}.w-8{width:2rem}.w-auto{width:auto}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}@media (min-width:640px){.sm\:rounded-lg{border-radius:.5rem}.sm\:block{display:block}.sm\:items-center{align-items:center}.sm\:justify-start{justify-content:flex-start}.sm\:justify-between{justify-content:space-between}.sm\:h-20{height:5rem}.sm\:ml-0{margin-left:0}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:pt-0{padding-top:0}.sm\:text-left{text-align:left}.sm\:text-right{text-align:right}}@media (min-width:768px){.md\:border-t-0{border-top-width:0}.md\:border-l{border-left-width:1px}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:1024px){.lg\:px-8{padding-left:2rem;padding-right:2rem}}@media (prefers-color-scheme:dark){.dark\:bg-gray-800{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.dark\:bg-gray-900{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.dark\:border-gray-700{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.dark\:text-white{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.dark\:text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}}
</style>
</head>
<body class="antialiased">
<?php
$APP_URL = "$_ENV[APP_URL]";
?>
<div class="container mt-5">
<div class="row pt-5">
<div class="col text-center">
<button class="btn btn-primary" data-mdb-modal-init data-mdb-target="#addTaskModal" data-mdb-ripple-init >ADD TASK</button>
</div>
</div>
<div class="row mt-3 p-5" style="min-height: 40vh;">
<div class="col d-flex justify-content-center align-items-center">
<ul class="list-group list-group-light taskList" style="min-width: 22rem;">
<?php foreach ($tasks as $task) { ?>
<li class='list-group-item d-flex justify-content-between align-items-center gap-5'>
<div>
<div class="fw-bold taskName"> <?=$task->name?> </div>
<div class="fw-bold taskDescription"> <?=$task->description?> </div>
</div>
<form method="post" action="{{$APP_URL}}:8000/api/task/{{$task->id}}">
<button type="button" class="editBtn btn btn-light btn-floating me-2" id="{{$task->id}}" data-mdb-ripple-init >
<span class="fas fa-pen text-primary" title="edit" data-mdb-modal-init data-mdb-target="#editTaskModal"></span>
</button>
<input type="hidden" name="_method" value="DELETE">
<button type="submit" class="deleteBtn btn btn-light btn-floating" id="${taskData[i].id}" data-mdb-ripple-init >
<i class="fas fa-trash text-danger" title="delete"></i>
</button>
</form>
</li>
<?php } ?>
</ul>
</div>
</div>
<div class="modal fade" id="addTaskModal" tabindex="-1" aria-labelledby="addTaskModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="addTaskModalLabel">Add task</h5>
<button type="button" class="btn-close" data-mdb-dismiss="modal" aria-label="Close"></button>
</div>
<form id="addTaskForm" action="{{$APP_URL}}:8000/api/task" method="post">
<div class="modal-body">
<div class="form-outline mb-4" data-mdb-input-init>
<input name='name' type="text" id="nameInput" class="form-control" />
<label class="form-label" for="form7Example1">Name</label>
</div>
<div class="form-outline mb-4" data-mdb-input-init>
<input name="description" type="text" id="descInput" class="form-control" />
<label class="form-label" for="form7Example2">Email address</label>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-mdb-dismiss="modal" data-mdb-ripple-init > Close </button>
<button type="submit" class="btn btn-primary modalConfirmBtn" data-mdb-ripple-init >Confirm</button>
</div>
</form>
</div>
</div>
</div>
<div class="modal fade" id="editTaskModal" tabindex="-1" aria-labelledby="editTaskModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="editTaskModalLabel">Edit Task</h5>
<button type="button" class="btn-close" data-mdb-dismiss="modal" aria-label="Close"></button>
</div>
<form id="editTaskForm" action="{{$APP_URL}}:8000/api/task" method="post">
<input type="hidden" name="_method" value="PUT">
<div class="modal-body">
<input id="editIdInput" name="id" type="number" value='0' class='d-none'>
<div class="form-outline mb-4" data-mdb-input-init>
<input name='name' type="text" id="editNameInput" class="form-control" />
<label class="form-label" for="editNameInput">Name</label>
</div>
<div class="form-outline mb-4" data-mdb-input-init>
<input name="description" type="text" id="editDescInput" class="form-control" />
<label class="form-label" for="editDescInput">Description</label>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-mdb-dismiss="modal" data-mdb-ripple-init > Close </button>
<button type="submit" class="btn btn-primary modalConfirmBtn" data-mdb-ripple-init >Confirm</button>
</div>
</form>
</div>
</div>
</div>
</div>
<script type="text/javascript" src="js/mdb.umd.min.js"></script>
<script type="module">
const editTaskModal = document.querySelector('#editTaskModal');
const editTaskForm = document.querySelector('#editTaskForm');
const editBtns = document.querySelectorAll('.editBtn');
const editIdInput = editTaskForm.querySelector('#editIdInput')
editBtns.forEach((button) => {
button.addEventListener('click', () => {
editIdInput.value = button.id;
const taskName = button.closest("li").querySelector('.taskName').innerText;
const taskDesc = button.closest("li").querySelector('.taskDescription').innerText;
editTaskForm.querySelector('#editDescInput').value = taskDesc
editTaskForm.querySelector('#editNameInput').value = taskName
})
})
</script>
</body>
</html>
Finally, we can run app using php artisan serve
.
Publish your app
Now you can publish your project on MDB GO using the following command:
Note: If you don't have MDB CLI installed yet, you can do it with NPM: npm install -g mdb-cli
.
Now log in with your MDB account, type: mdb login
.
If you don't have account yet you can create one using mdb register
command.
mdb publish -p php-laravel
Note Since we need to install dependencies and run your app, it may take a few moments until it will be available under the provided URL.
Optimization
If you want to further optimize your application please visit:
Backend features
Laravel:
This example was created with Laravel-starter. By creating new endpoints, we could pass or receive data from this application.
Frontend features
MDB UI KIT:
To create the project we used our ui kit, with which we can build basic views very quickly.
Views and Layouts:
In this project we used the welcome.blade.php
file created by Laravel where we placed our
MDB
components. We have successfully integrated the backend with the
MDB Standard package and can send basic requests to the Laravel application.