Using the Blade Engine to Remove PHP
.blade.php
In order to use the Blade templating engine, your file names need to end in .blade.php
. Where are they located? In the same directory that we have been working on this whole time: resources/views
.
One such blade file that we created in the previous article is resources/views/cars/index.blade.php
. It currently outputs a list of my favorite cars wrapped in a ul
list.
<ul>
<li>2003 Chevy Corvette</li>
<li>2007 Chevy Corvette</li>
<li>1999 Nissan Skyline GT-R</li>
<li>2021 Nissan GT-R</li>
<li>2022 Porsche 911 GT3</li>
<li>1994 Toyota Supra 2JZGTE</li>
<li>1989 Nissan 240SX Hatchback</li>
<li>2019 Subaru WRX STi</li>
<li>1998 Dodge Viper GTS-R</li>
</ul>
We want to be able to pass a list of cars as an array to our blade
view and have the view loop through it and display it on the screen. So let’s do that.
Create a new route: /cars/favorite
. This route will return a new blade
view after it passes it an array of vehicle data.
<?php
// ...
Route::get('/cars/my/favorites', function() {
return view('cars/favorite', [
'cars' => [
"2003 Chevy Corvette",
"2007 Chevy Corvette",
"1999 Nissan Skyline GT-R",
"2021 Nissan GT-R",
"2022 Porsche 911 GT3",
"1994 Toyota Supra 2JZGTE",
"1989 Nissan 240SX Hatchback",
"2019 Subaru WRX STi",
"1998 Dodge Viper GTS-R",
]
]);
});
Our route calls the cars/favorite
view, which doesn’t exist yet. Let’s create it.
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Favorite Cars</title>
<!-- Fonts -->
<link href="https://fonts.bunny.net/css2?family=Nunito:wght@400;600;700&display=swap" rel="stylesheet">
<!-- 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{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity))}.bg-gray-100{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity))}.border-gray-200{--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-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{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.text-center{text-align:center}.text-gray-200{--tw-text-opacity: 1;color:rgb(229 231 235 / var(--tw-text-opacity))}.text-gray-300{--tw-text-opacity: 1;color:rgb(209 213 219 / var(--tw-text-opacity))}.text-gray-400{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity))}.text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity))}.text-gray-700{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity))}.text-gray-900{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-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{--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity))}.dark\:bg-gray-900{--tw-bg-opacity: 1;background-color:rgb(17 24 39 / var(--tw-bg-opacity))}.dark\:border-gray-700{--tw-border-opacity: 1;border-color:rgb(55 65 81 / var(--tw-border-opacity))}.dark\:text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity))}.dark\:text-gray-400{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity))}.dark\:text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity))}}
</style>
</head>
<body class="p-6">
<h1>Here's a list of my favorite cars</h1>
<ul>
<!-- This is where our list of cars will go -->
</ul>
</body>
</html>
cars
, so we should have access to the $cars
array. We can inject pure PHP into this and var_dump
the $cars
array.<ul>
<!-- This is where our list of cars will go -->
<?php
var_dump($cars);
?>
</ul>
foreach
loop.<ul>
<!-- This is where our list of cars will go -->
<?php
foreach ($cars as $car) {
echo "<li>" . $car . "</li>";
}
?>
</ul>
Looks like PHP code mixed in with HTML. Not what we want to see. Let’s look at the rendered page.
How would we do this with Blade?
The Blade directive for a PHP foreach loop is simply @foreach
. To end the foreach loop, you use @endforeach
.
<ul>
@foreach($cars as $car)
<li>{{ $car }}</li>
@endforeach
</ul>
So much cleaner. We loop through each of the $cars
and output the value of $car
. The {{ }}
is what allows the variable to be evaluated. It’s pretty much like saying echo
with the exception that it also automatically sends the data through PHP’s htmlspecialchars
function to prevent XSS attacks.
If you refresh your page, you won’t notice a difference. The HTML that was generated is identical, but you can’t deny that the code looks much cleaner now.
Next
That’s it for this quick intro. We’ll continue looking at Blade in detail in the next article, where we’ll cover:
- Displaying Data
- Displaying Unescaped Data
- If Statements
- Switch Statements
- Loops
- The Loop Variable
- Including Subviews
See you next time.
Laravel Series
Continue your Laravel Learning.
Organize Your Views Better With Subdirectories
Laravel – P7: View Subdirectories and Checks
We know how to grab URL parameters and return them from our route, but how do we pass arguments to the view?
Using the Blade Engine to Remove PHP
Laravel – P8: Blade Introduction
Blade is a templating engine that allows you to write some front-end friendly code. The last thing we want to see is PHP wrapped up inside of the views.
Discussing Blade Directives
Laravel – P9: Displaying Data In Blade
What we really wanted to achieve was introduce what Blade is, understand that there are Blade Directives. These directives make our lives easier and not PHP.