Comparing Blade and Twig templates in Laravel

TLDR; Spoiler alert

About Blade

@extends('layouts.master')@section('content')
@foreach ($users as $user)
<p>This is user </p>
@endforeach
@endsection

About Twig

{% extends "layouts.master" %}{% block content %}
{% for user in users %}
<p>This is user {{ user.id }}</p>
{% endfor %}
{% endblock %}

Twig in Laravel

  • Loading view using the Laravel View factory (view(‘template’))
  • Using events for View Composers
  • Access to common functions/filters (input, auth, session etc)
  • Facade support

Blade vs. Twig

  • Both compile to plain PHP, for better performance
  • Both provide a syntax to easily output variables
  • Both have control-structures (if/for/while etc)
  • Both have escaping mechanism for safe output
  • Both have template-inheritance and sections
  • Different syntax for control structures
  • Different handling of escaping
  • Different handling of variables and variable access
  • Different ways to add functionality
  • Different perspective on security

Outputting variables

{{ user.username|e('css') }}{% autoescape 'js' %}
Everything will be automatically escaped in this block (using the JS strategy)
{% endautoescape %}

Accessing attributes

$user->name --> user.name
$user['name'] --> user.name

Control structures

@forelse ($user in $user)
@if(!$user->subscribed)
{{ $user->name }}
@endif
@empty
<p>No users found</p>
@endforelse
<?php $empty = true; foreach($user in $user): $empty = false; ?>
<?php if (!$user->subscribed) : ?>
<?php echo e($user->name); ?>
<?php endif; ?>
<?php endforeach; if ($empty): ?>
<p>No users found</p>
<?php endif; ?>
{% for user in users %}
{% if not user.subscribed %}
{{ user.name }}
{% endif %}
{% else %}
<p>No users found</p>
{% endfor %}

Template inheritance and sections

<!-- layouts/master.blade.php -->
<html>
<head>
<title>App Name - @yield('title')</title>
</head>
<body>
@section('sidebar')
This is the master sidebar.
@show
<div class="container">
@yield('content')
</div>
</body>
</html>
<!-- child.blade.php -->
@extends('layouts.master')
@section('title', 'Page Title')@section('sidebar')
@parent
<p>This is appended to the master sidebar.</p>
@endsection
@section('content')
<p>This is my body content.</p>
@endsection
<!-- layouts/master.twig -->
<html>
<head>
<title>App Name - {% block title %}{% endblock %}</title>
</head>
<body>
{% block sidebar %}
This is the master sidebar.
{% endblock %}

<div class="container">
{% block content %}{% endblock %}
</div>
</body>
</html>
<!-- child.twig -->
{% extends "layouts.master" %}
{% block title %}Page Title{% endblock %}{% block sidebar %}
{{ parent() }}
<p>This is appended to the master sidebar.</p>
{% endblock %}
{% block content %}
<p>This is my body content.</p>
{% endblock %}

Security and context

@foreach(User::where('active')->get() as $user)
{{ $user->name }}
@endforeach
{% for user in model.where('active').get() %}
{{ user.name }}
{% endfor %}

Extending functionality

<?php
// @upper($var)
Blade::directive('upper', function($expression) {
return "<?php echo strtoupper{$expression}; ?>";
});
<?php
//
$filter = new Twig_SimpleFilter('upper', function ($string) {
return strtoupper($string);
});

Performance

Other differences

So ..?

--

--

--

Webdeveloper from the Netherlands, mostly focused on PHP. Co-founder and lead developer @ Fruitcake.nl

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Barry vd. Heuvel

Barry vd. Heuvel

Webdeveloper from the Netherlands, mostly focused on PHP. Co-founder and lead developer @ Fruitcake.nl

More from Medium

Laravel: Why I Love Cache:remember(‘me’, fn () => ‘I Love Laravel’);

Use Laravel Queue To Create “Running On Background” Script Execution

Laravel Enum

Laravel 8