DRY Up Your HTML With Laravel 7 Blade Components

May 14, 2020
Written by
Shane Rosenthal
Contributor
Opinions expressed by Twilio contributors are their own
Reviewed by

DRY Up Your HTML With Laravel 7 Blade Components

In the latest iteration of Laravel, developers were introduced to a new syntax for creating Blade Components. If you’re unfamiliar, a blade is the templating engine in Laravel that allows you to use plain PHP in your view. The components, or reusable code created using this logic, allows you to easily follow the DRY or “Don’t Repeat Yourself” principle. Creating a Blade component once means that you can reuse the code anywhere in your application.

Twitter screenshot

The improvements made in Laravel 7 promise to speed up your development time by allowing you to create new, class-based Blade components for your front end markup.

Previous Implementations of Blade Components

Since Laravel 5.4, developers have had the option to use the @component syntax in their markup to reference reusable sections of code known as components. Consider the following example for creating an alert:

<!-- /resources/views/alert.blade.php -->

<div class="alert alert-danger">
    {{ $slot }}
</div>

This code would generate the alert component, using any HTML supplied to it in the $slot placeholder.

To reference this component and use it in your code, the following @component directive would be called:

@component('alert')
    <strong>Whoops!</strong> Something went wrong!
@endcomponent

As mentioned above, the HTML <strong>Whoops!</strong> Something went wrong! would be injected into the $slot variable.

What's New in Laravel 7?

Now that you have a feel for how components have been implemented for the past few years,  let's take a dive into the enhancements, changes, and benefits of the new x- syntax!

Let's demo a simple panel in Laravel 7. You can use either a new or existing installation of Laravel, but this tutorial will assume that your installation at least contains the welcome blade located at resources/views/welcome.blade.php

To begin, open your terminal and run the new Artisan command for generating components:

$ php artisan make:component Panel

This command creates two new files; one in app\View\Components\Panel.php and the other in resources\views\components\panel.blade.php.

The newly generated files will serve as a "shell" for your panel. Once you’ve completed the next steps, you’ll be able to call the component in your app like so:

<x-panel title="Update Your Info!" class="max-w-2xl">
        
</x-panel>

In short, the new syntax creates a class and view that generates a new HTML component of type <x-panel>, where panel references the name of our blade.

Putting It Together

Open app\View\Components\Panel.php in your favorite integrated development environment (IDE). In the constructor, pass the string $title variable and make it a public property as follows:

/**
* @var string
*/
public $title;

/**
* Create a new component instance.
*
* @param string $title
*/
public function __construct(string $title)
{
   $this->title = $title;
}

What’s interesting about the new syntax is that any public property on our Component classes are accessible in the component markup.

Now open resources\views\components\panel.blade.php to modify the HTML of the component.

NOTE: I used TailwindCSS for styling my panel markup.

<div {{ $attributes->merge(['class' => 'p-6 rounded-lg shadow-lg']) }}>
   <div class="text-xl text-orange-500">{{ $title }}</div>
    <div class="mt-4">
        {{ $slot }}
    </div>
</div>

In the top <div> the $attributes->merge() function allows developers to set some default stylings for their component. Here we are using it to add your own stylings.

Notice that the syntax is echoing out the $title property defined in the Panel class, and also providing a $slotto add custom content into the panel.

Testing

To test these update, open the welcome.blade.php or an available blade template and add the following code:

<x-panel title="Update Your Info!" class="max-w-2xl">
    <h1>I AM IN THE SLOT</h1>
</x-panel>

It should look similar to the screenshot below:

Example blade component

Notice how the width is overridden by the class attribute we added directly to the component. Awesome! Now you have a panel component you can use anywhere in your app!

Why Is This Better?

On the surface, this doesn't look like much of an improvement over the traditional Blade components. Truthfully, we could have achieved this with just one file using the old syntax. However, when you consider the fact that we are using a class to render data, your eyes open up to other possibilities.

Look back at the Panel class. What if we wanted to inject some data from some external class or even inject a function? All of this is possible now! Take a look:

/**
* Create a new component instance.
*
* @param SomeService $service
* @param string $title
*/
public function __construct(SomeService $service, string $title)
{
   $this->title = $title;
   $this->service = $service;
}
public function doSomething()
{
   return $this->service->getSomeData();
}

Now this function doSomething() can be used directly in your blade component:

<div {{ $attributes->merge(['class' => 'p-6 rounded-lg shadow-lg']) }}>
    <div class="text-xl text-orange-500">{{$title}} - {{doSomething()}}</div>
    <div class="mt-4">
        {{$slot}}
    </div>
</div>

Conclusion

In this tutorial, you learned how to use the new Blade component syntax in Laravel 7. You could extend this further by implementing this logic with a form or introducing anonymous components for when you don't need a full class or inline components. Stay tuned!

Shane D. Rosenthal is an AWS Certified and experienced full-stack developer that has worked with Laravel since 2013. He is open for consultation regarding Laravel and VueJS applications and AWS architecture and can be reached via: