# Blade Template Engine: Eliminating Repetitive HTML

> The practical payoff of separating the view layer from logic: using Blade layouts, sections, and partials.

- Published: 2014-07-06
- Category: Framework & Library
- Tags: Laravel
- Reading time: 3 min read
- Source: https://www.muhammetsafak.com.tr/en/blog/blade-template-engine-eliminating-repetitive-html/
- Language: en-US
- Author: Muhammet Şafak

---
I'm still deep in [Laravel](/en/blog/getting-started-with-my-first-laravel-4-project/). This month I've been focused on the view layer. My old approach with PHP templates was straightforward: include `header.php` and `footer.php` on every page. That works fine on small projects, but as things grow, tracking which page includes what becomes a real chore.

**Blade** is Laravel's templating engine. Unlike raw PHP templates, it provides clean syntax for template inheritance and partials.

## Why a template engine?

In raw PHP templates, HTML and PHP code get tangled together. In a long page it's easy to get lost between `<?php foreach(...): ?>` and `<?php endforeach; ?>`. Blade makes this more readable with directives like `@foreach` and `@endforeach`. It also gives you a short syntax, `{{{ }}}`, for escaping output against XSS (Cross-Site Scripting).

With the old approach, writing `<?= $user->name ?>` gave me zero XSS protection — I was printing user-supplied data straight to the page. Blade's `{{{ $user->name }}}` syntax calls `htmlspecialchars()` for you, which boils escaping down to a single piece of syntax.

## Creating a master layout

First I create the base skeleton — the layout file: `app/views/layouts/main.blade.php`

```html
<!DOCTYPE html>
<html>
<head>
    <title>@yield('title') | My Site</title>
    <link rel="stylesheet" href="/css/app.css">
</head>
<body>
    @include('partials.menu')

    <div class="content">
        @yield('content')
    </div>

    @include('partials.footer')
</body>
</html>
```

`@yield('content')` defines a placeholder where child pages can inject their own content. I use `@include` to move repeated sections into separate files.

## Child views

`app/views/home.blade.php`:

```html
@extends('layouts.main')

@section('title', 'Home')

@section('content')
    <h1>Welcome</h1>
    <p>This is the home page.</p>

    @foreach($news as $item)
        <div class="news-item">
            <h2>{{{ $item->title }}}</h2>
            <p>{{{ $item->summary }}}</p>
        </div>
    @endforeach
@endsection
```

`@extends('layouts.main')` declares which layout this view uses. `@section` fills the `@yield` slots defined in that layout. The `{{{ $variable }}}` syntax escapes HTML special characters and produces safe output.

## Conditionals and loops

Blade directives map one-to-one with their raw PHP counterparts:

```html
@if($user->isLoggedIn())
    <a href="/logout">Logout</a>
@else
    <a href="/login">Login</a>
@endif

@forelse($comments as $comment)
    <p>{{{ $comment->body }}}</p>
@empty
    <p>No comments yet.</p>
@endforelse
```

`@forelse` renders the `@empty` block when the list is empty. I reach for this combination constantly; previously I'd write a separate `count($array) > 0` check.

## Partials

Moving repeated pieces into separate files keeps things tidy. I put the navigation into `app/views/partials/menu.blade.php`:

```html
<nav>
    <a href="/">Home</a>
    <a href="/about">About</a>
    @if(Auth::check())
        <a href="/dashboard">Dashboard</a>
    @endif
</nav>
```

Every page just writes `@include('partials.menu')` and Blade handles the rest.

## Passing data from the controller to the view

There are a few ways to pass variables from a controller to a view:

```php
// Using compact()
$news = News::all();
return View::make('home', compact('news'));

// Method chaining with with()
return View::make('home')->with('news', News::all());
```

Both produce the same result; `compact()` is more convenient when you're passing multiple variables at once.

## Running raw PHP expressions

Occasionally you need PHP that doesn't have a Blade directive. You can open a plain PHP tag inside the template:

```html
<?php $total = $price * $quantity; ?>

<p>Total: {{ $total }}</p>
```

I use this sparingly — business logic should not creep into the view layer. But for simple calculations it gets the job done.

## The escape hatch: rendering raw HTML

Blade's `{{{ }}}` syntax escapes HTML — and that's a good thing. But if you're storing HTML content in the database and need to render it as-is, you use the `{{ }}` syntax:

```html
{{ $article->content }}
```

This should only be used for content you fully trust. Rendering user-submitted input with `{{ }}` completely disables XSS protection. I learned this distinction on a CMS project: `{{ }}` was the right call for HTML articles coming from an editor, but using the same syntax for comment fields would have opened a security hole.

## Compared to the old approach

With the old `header.php` / `footer.php` pattern, every page needed two includes and I had to keep their interdependencies in my head. Blade's inheritance model inverts this: there's a central layout file, and child pages attach to it. Adding a new page is far cleaner.

After a few weeks of use, I appreciate the structure a template engine brings. The `@forelse` and `@include` combination alone has noticeably reduced repetitive code. And having escaping boiled down to a short `{{{ }}}` syntax means security is no longer a `htmlspecialchars()` call you have to "remember" each time.

Blade has one more feature worth mentioning: the `@stack` and `@push` directives let you inject page-specific CSS or JavaScript blocks into a designated slot in the layout. For example, if a page requires a specific JavaScript library, you can push it from that page's view into a `@stack('scripts')` slot defined just before the layout's `</body>` tag. Instead of bundling all JS into one file, you include page-specific scripts only when that page loads.
