Blog EspecializaTi
Carlos Ferreira Por: Carlos Ferreira Comentar

Laravel Blade

Laravel Blade

O Laravel tem o seu próprio mecanismo de template, chamado de Blade. É simples, poderoso, repleto de recursos e fácil de aplicar.

Um ponto importante do blade se comparado a outros mecanismos de template, é que o Blade não restringe o uso do PHP, mas fornece recursos que facilitam a interpretação do mesmo. E também, os arquivos de blade são compilados e armazenados em cache, logo isso significa que o carregamento fica mais leve, e não gera sobrecarga na aplicação.

Os arquivos de template do blade devem possuir a extensão .blade.php

O diretório padrão de armazenamento dos arquivo é em resources/views/

As configurações de view do laravel ficam no arquivo config/view.php, nesse arquivo é possível alterar o diretório padrão dos arquivos do Blade, e também é possível alterar até mesmo onde ficam armazenado os arquivos compilados das views.

 
 

Impressões:

Você pode passar variáveis para as views dessa forma:

#controller
$name = 'Carlos';
$lastName = 'Ferreira';
return view('path.name-view', ['name' => $name, 'lastName' => $lastName]);

O primeiro parâmetro da função view() estamos especificando que vamos usar a view que está em resources/views/path/name-view.blade.php

Já o segundo parâmetro podemos passar um array com as variáveis que vamos enviar para a views. Uma forma mais enxuta de fazer a mesma implementação é trocar o array pela função compact() do PHP:

$name = 'Carlos';
$lastName = 'Ferreira';
return view('path.name-view', compact('name', 'lastName'));

Você pode fazer a impressão na view dessa forma:

Olá {{ $name }} {{ $lastName }}!

O blade usa a diretiva {{ }} pra fazer a impressão de variáveis.

// Convenhamos que isso:
{{ $name }}

// É mais usual que isso:
<?=$name?>

// Ou isso:
<?php echo $name;?>

Um ponto importante da impressão com {{ }} é que já aplica algumas métricas de segurança, em especial contra ataques XSS. Porque aplica a função do PHP htmlspecialchars, que converte os caracteres HTML.

Caso tenha certeza do que vai imprimir, e que isso NÃO contém um código malicioso, pode usar pra fazer a impressão {!! $varName !!}

Você pode fazer um experimento para ficar mais claro, veja a diferença das suas impressões:

#controller
$varName = '<script>alert("Sou um ataque XSS?")</script>';
return view('path.name-view', compact('varName'));

#view
{{ $varName }}

{!! $varName !!}

A primeira impressão vai imprimir exatamente o valor da variável, já o segundo caso mostra o título. Veja o código fonte da página e analise a diferença (CTRL + u).

Outra altertiva muito útil para a impressão com {{ }} é validar se a variável existe, porque se fizer a impressão de uma variável não definida vai gerar erro, caso queira evitar isso e só imprimir o valor da variável caso ela exista pode fazer assim:

{{ $varName or 'Default Value' }}

Dessa forma de a variável $varName não foi passada para a view vai exibir o valor default, que no caso é: Default Value

A partir da versão 5.7 o operador “or” foi substituído por “??”

 

Renderização de JSON

Embora não seja uma prática muito usual, talvez em algum momento seja necessário passar um variável para o JavaScript, e vamos supor que seja um Array. Nesse caso precisamos implementar dessa forma:

<script>
    let nameVar = <?php echo json_encode($arrayName); ?>;
</script>
Nesse caso precisamos fazer o json_encode do nosso array. Porém o blade tem uma diretiva que simplifica isso, e é exatamente a diretiva <b>@json</b>
<script>
    let nameVar = @json($arrayName);
</script>

 
 

Blade & Frameworks JavaScript:

Muitos Frameworks JavaScript também utilizam {{ }} para fazer interpolation de seus valores, nesse caso você pode usar o símbolo @ para informar ao Blade que essa expressão deve permanecer intocável. Exemplo:

@{{ name }}

Nesse caso o Blade remove o “@” e deixa a expressão {{ name }}, assim o Framework JS por trás faz o interpolation da variável name. O blade simplesmente ignora essa estrutura.

Agora se tiver várias variáveis e estruturas JS, fica mais fácil usar a diretiva @verbatim do que o símbolo @

@verbatim
    <div class="content">
        Olá {{ name }}!
    </div>
@endverbatim

 
 

Templates e Herança:

Outro recurso que não pode faltar em um sistema de template é a opção de templates. Esse recurso permite centralizar o layout padrão em um ou mais arquivos, e estender desses arquivos para reaproveitar o layout em diferentes views, assim minimizando a quantidade de códigos escritos.

Definir um layout

Crie a view que será o template em resources/views/layouts/app.blade.php, com o seguinte conteúdo:

<html>
    <head>
        <title>@yield('title') - EspecializaTi</title>
    </head>
    <body>
        <header>
            @section('sidebar')
                Sidebar
            @show
        </header>

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

        <footer>
            Rodapé
        </footer>
    </body>
</html>

Observe as diretivas @yield, @section e @show

A diretiva @section define uma sessão no template, como por exemplo uma sidebar. Nesse formato que trabalhamos usando as diretivas @section e @show podemos definir uma sidebar default, mas também podemos acrescentar conteúdo dinamicamente nas views que estenderem desse template.

A diretiva @yield pode ser usada para exibir um conteúdo dinâmico. Nesse exemplo o conteúdo das nossas views serão inseridas dinamicamente através da identificação da diretiva @yield

Estendendo do template

Uma vez que definimos o nosso template agora podemos estender dele e definir o seu conteúdo, ou seja, o título, o conteúdo e opcionalmente o sidebar.

Crie um novo arquivo de view em resources/views/example.blade.php com o seguinte conteúdo:

@extends('layouts.app')

@section('title', 'Teste')

@section('sidebar')
    @parent

    <p>Adicionando esse conteúdo extra no sidebar</p>
@endsection

@section('content')

<h1>Algo</h1>
<p>Conteúdo vem aqui</p>

@endsection

Observe as diretivas usadas até o momento @extends, @section, @endsection, @parent

A diretiva @extends é usada para indicar qual o arquivo de template que essa view vai herdar (extender). No caso indicamos layouts.app porque nosso arquivo está view está em resources/views/layouts/app.blade.php

Lembra da diretiva no template @yield com o identificador “content“? @yield(‘content’)

Pra definir o conteúdo nessa diretiva a partir da view que estendeu do template basta usar a diretiva @section passando o nome do identificado que vai substituir @section(‘content’), e a diretiva @endsection é usada para marcar o fim dessa sessão.

Ou seja, o que colocar entre @section(‘content’) e @endsection vai substituir no template onde está @yield(‘content’)

No caso do título da página como é algo muito simples nem precisa de indicar o inicio e fim da sessão, podemos simplificar passando no segundo parâmetro da diretiva @section o valor do título:

@section('title', 'Teste')

Ainda nos resta a @section(‘sidebar’). Se não não usar essa seção na view vai exibir apenas o conteúdo default definido no template layouts.app

Porém tem alguns trocadilhos nessa sessão que podemos explorar, como por exemplo:

@section('sidebar')
    <p>Nova Sidebar</p>
@endsection

Se passar dessa forma vai substituir o conteúdo default (padrão) da sidebar layouts.app, por esse novo conteúdo.

Porém, caso queia apenas acrescentar um novo conteúdo a sidebar para distinguir alguma informação pode combinar a diretiva @parent, porque dessa forma vai manter o conteúdo default de layouts.app e acrescentar o novo conteúdo definido na view filha:

@section('sidebar')
    @parent

    <p>Apenas incrementando!</p>
@endsection

 
 

Componentes e Slots:

Componentes e Slots possuem uma certa semelhança com templates, porém, é uma maneira mais simples de criar conteúdos reutilizáveis com papéis bem definidos, um exemplo clássico é trabalhar com alerts do bootstrap.

Pra exemplificar vamos criar um arquivo de view em resources/views/components/alert.blade.php, com o seguinte conteúdo:

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

A variável $slot vai conter o conteúdo injetado ao utilizar esse nosso novo componente.

Outra opção interessante também é injetar mais de um valor ao usar um componente, como por exemplo, um título. Vamos customizar o nosso component resources/views/components/alert.blade.php para receber um título dinâmico:

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

    {{ $slot }}
</div>

Agora que o component está criado podemos reutiliza-lo, quantas vezes for necessário. No arquivo resources/views/example.blade.php vamos usar o component (componente) que está em resources/views/components/alert.blade.php:

@extends('layouts.app')

@section('title', 'Teste')

@section('sidebar')
    @parent

    <p>Adicionando esse conteúdo extra no sidebar</p>
@endsection

@section('content')

    <h1>Algo</h1>
    <p>Conteúdo vem aqui</p>

    @component('components.alert')
        @slot('title')
            Título
        @endslot

        Conteúdo que vai ser injetado na variável $slot
    @endcomponent

@endsection

A diretiva @component permite criar blocos reutilizáveis.

Outra alternativa para components é definir valores opcionais, ou seja, variáveis que podemos ou não ser passadas ao componente. Para testar altere o componente resources/views/components/alert.blade.php:

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

    {{ $slot }}

    <div class="footer-alert">
        {{ $footer or '' }}
    </div>
</div>

Veja que criamos uma sessão adicional que imprime o valor da variável $footer caso exista. Para passar o valor dessa variável $footer no momento de usar o componente podemos fazer assim:

@component('components.alert', ['footer' => 'footer alert'])
[...]

Reforçando, é importante deixar o valor da variável $footer como opcional {{ $footer ?? ” }}, porque caso use esse component e não informe o valor dessa variável ocorreria um erro.

 

Criar um aliás para o component:

Nosso componente ficou em um subdiretório em views para ficar bem organizado. Porém sempre que precisamos usar o nosso componente alert precisamos indicar o path (caminho) “components.alert”. O laravel permite criar um aliás para utilizar de forma mais simplificada. Na classe AppServiceProvider (app/Providers/AppServiceProvider.php) no método boot() defina o aliás para o nosso component, chamando ele de “alert”:

// Não esquece: use Illuminate\Support\Facades\Blade;
Blade::component('components.alert', 'alert');

Agora que criamos o aliás para o nosso component podemos utilizá-lo da seguinte forma:

@alert(['footer' => 'footer alert'])
    @slot('title')
        Título
    @endslot

    Conteúdo que vai ser injetado na variável $slot
@endalert

Pra finalizar o exemplo, caso queira definir o tipo de alert dinamicamente, pode alterar o component resources/views/components/alert.blade.php:

<div class="alert alert-{{ $type or 'danger' }}">
    [...]
</div>

E pra passar esse tipo, pode fazer assim:

@alert(['footer' => 'footer alert', 'type' => 'success'])
    [...]
@endalert

 
 

Estrutura de Controle:

O sistema de template blade do Laravel também dispõe de diretivas de controle, como: @if, @elseif, @else, e @endif

Exemplo:

@if (isset($varName))
    A variável existe com o valor: {{ $varName }}
@elseif (isset($varName) && $varName != 'EspecializaTi')
    A variável existe, porém o valor é diferente de EspecializaTi
@else
    Ops! A variável não existe!
@endif

Esse mesmo exemplo acima pode ser reescrito com a diretiva @isset, veja:

@isset($varName)
    A variável existe com o valor: {{ $varName }}
@else
    Ops! A variável não existe!
@endisset

Também é possível verificar o valor da variável está vazio (empty) com a diretiva @empty

@empty($varName)
    A variável está vazia
@else
    Ops! Tem conteúdo na variável.
@endempty

O blade também possui a diretiva @unless, ela tem uma lógica diferente do @if. A diretiva @unless verificar se o valor é false.

Exemplo:

@unless (isset($varName))
    A variável não existe!
@else
    A variável existe
@endunless

Diretivas de autenticação

O blade também provê as diretivas @auth e @guest, que podem ser usadas para verificar se o usuário está autenticado, ou não.

Exemplo:

@auth
    <p>Olá {{ auth()->user()->name }}!</p>
@else
    <a href="{{ route('login') }}">Login</a>
@endauth

// Verifica se não está autenticado:
@guest
    <a href="{{ route('login') }}">Login</a>
@else
    <p>Olá {{ auth()->user()->name }}!</p>
@endguest

Caso necessário é possível especificar o guard usando as diretivas @auth e @guest:

@auth('admin')
    Olá admin!
@endauth

@guest('admin')
    Ops! Não é o admin!
@endguest

NOTA: Guard será abordado mais detalhadamente no capitulo sobre autenticação.

E claro, não pode faltar a diretiva @switch, veja o exemplo:

@switch($varName)
    @case('EspecializaTi')
        Olá Empresa EspecializaTi!
        @break

    @case('Carlos')
        Olá Usuário Carlos!
        @break

    @default
        Olá Convidado!
@endswitch

 
 

Loops:

O blade também tem diretivas para tratar estruturas de repetição.

Vamos ao primeiro exemplo com as diretivas @for e @endfor

@for ($i = 0; $i < 10; $i++)
    O valor da variável é {{ $i }}
@endfor

Também é possível interar um array, com as diretivas @foreach e @endforeach

Exemplo:

<ul>
    @if (count($users) > 0)
        @foreach ($users as $user)
            <li>{{ $user->name }}</li>
        @endforeach
    @else
        <li>Nenhum usuário</li>
    @endif
</ul>

Esse mesmo exemplo acima pode ser reescrito de uma forma mais simples, usando as diretivas @forelse e @endforelse

Exemplo:

<ul>
    @forelse ($users as $user)
        <li>{{ $user->name }}</li>
    @empty
        <li>Nenhum usuário</li>
    @endforelse
</ul>

Também não pode faltar a diretiva @while e @endwhile

@php
    $i = 0;
@endphp
@while ($i < count($users))
    <p>{{ $users[$i]->name }}</p>
    @php
        $i++;
    @endphp
@endwhile

NOTA: A diretiva @php e @endphp serão abordada mais adiante, ainda nesse capitulo.

A variável $loop

Loops de repetição no Blade dispõe da variável $loop, e essa variável dispõe de diversos truques (recursos), um dos mais interessantes é o first e last, com eles é possível detectar o primeiro índice do loop e o último, vamos ao exemplo:

<table class="table table-striped">
    <thead class="thead-dark">
        <tr>
            <th scope="col">#</th>
            <th scope="col">Nome</th>
            <th scope="col">E-mail</th>
        </tr>
    </thead>
    <tbody>
    @foreach ($users as $user)
        @if ($loop->first)
            <tr class="table-primary">
        @elseif ($loop->last)
            <tr class="table-info">
        @else
            <tr>
        @endif

            <td>{{ $user->id }}</td>
            <td>{{ $user->name }}</td>
            <td>{{ $user->email }}</td>
        </tr>
    @endforeach
    </tbody>
</table>

A variável $loop contém diversas outras propriedades muito úteis:

  • $loop->first – Primeiro registro do loop
  • $loop->last – Último registro do loop
  • $loop->index – Indice do loop, inicia com 0
  • $loop->iteration – Interação do loop atual, inicia com 1
  • $loop->remaining – Quantidade de iterações que ainda restam no loop
  • $loop->count – A quantidade itens no array que estão sendo iterados
  • $loop->depth – O nível de aninhamento do loop atual.
  • $loop->parent – Quando em um loop aninhado, a variável de loop do pai.

 
 

Includes:

Claro algo que não pode faltar em um bom sistema de template é a opção de incluir sub-views. Para o isso Blade disponibiliza da diretiva @include

Para exemplificar vamos criar uma nova view em resources/views/includes/shared.blade.php:

<div>
    Sub-view
</div>

Para incluir essa view em qualquer outra basta utilizar a diretiva @include indicando o path (caminho), assim:

@include('includes.shared')

Um ponto importante sobre sub-views é que as variáveis disponíveis na view que incluiu, também estarão disponíveis nela. Ou seja, se tiver uma ou mais variáveis disponíveis na view resources/views/example.blade.php ao incluir a view resources/views/includes/shared.blade.php nela, as mesmas variáveis também estão acessíveis.

Também é possível passar variáveis (valores) dinâmicamente para a nossa sub-view. Para exemplificar vamos na view resources/views/includes/shared.blade.php e deixar assim:

<div class="{{ $class or 'default' }}">
    Sub-view
    <p>{{ $varName }}</p>
</div>

Agora para incluir podemos passar a valor ‘class‘, caso necessário:

@include('includes.shared', ['class' => 'custom'])

Se tentar incluir um arquivo de view que não existe o Laravel vai gerar um erro, claro. Caso você queira incluir um arquivo de view que pode ou não existir, pode fazer usar a diretiva @includeIf:

@includeIf('includes.shared', ['class' => 'custom'])

Para incluir a primeira view que existir, podemos passar um Array com os path (caminhos) das views:

@includeFirst(['includes.view', 'includes.shared'], ['class' => 'custom'])

Caso queira incluir uma sub-view apenas se atender uma certa condição, podemos usar a diretiva @includeWhen, nesse exemplo teremos uma view em resources/views/includes/comment.blade.php, e só vamos incluir caso o usuário esteja logado:

@includeWhen(auth()->check(), 'includes.comment')

 

Renderização de Collections

Vamos pensar em um exemplo bastante prático, um menu com vários submenus. Uma das formas de trabalhar esse menu através de views loops de repetição. E é exatamente dessa forma que vamos trabalhar, e depois vamos utilizar a diretiva @each para facilitar.

Para exemplificar teremos uma variável chamada $menus com todos os itens do menu, com os seus subitens:

$menus = [
    [
        'name' => 'Home',
        'url' => '/',
        'sub-menu' => []
    ], [
        'name' => 'Contato',
        'url' => '/contato',
        'sub-menu' => []
    ], [
        'name' => 'Categorias',
        'url' => '/categorias',
        'sub-menu' => [
            [
                'name' => 'JavaScript',
                'url' => '/categoria/javascript',
                'sub-menu' => []
            ], [
                'name' => 'Android',
                'url' => '/categoria/android',
                'sub-menu' => []
            ], [
                'name' => 'PHP',
                'url' => '/categoria/php',
                'sub-menu' => [
                    [
                        'name' => 'CSRF',
                        'url' => '/categoria/php/csrf',
                        'sub-menu' => []
                    ], [
                        'name' => 'XSS',
                        'url' => '/categoria/php/xss',
                        'sub-menu' => []
                    ], [
                        'name' => 'SQL Injection',
                        'url' => '/categoria/php/sql-injection',
                        'sub-menu' => []
                    ], [
                        'name' => 'PHP Injection',
                        'url' => '/categoria/php/php-injection',
                        'sub-menu' => []
                    ], [
                        'name' => 'Session hijacking',
                        'url' => '/categoria/php/session-hijacking',
                        'sub-menu' => []
                    ],
                ],
            ],
        ],
    ],
];

Como o objetivo é montar o menu usando as tags ul e li, vamos nesse caso criar um novo arquivo de view em resources/views/includes/menus/menu.blade.php

Nesse arquivo menu.blade.php temos acesso a variável $menus

Nesse arquivo vamos verificar se existe itens no array de menu para montar o menu, caso não exista vamos exibir uma mensagem em uma view, caso contrário, ou seja, caso exista registros (valores no array) vamos exibir:

@if (count($menus) > 0)
    <ul>
    @foreach ($menus as $menu)
        @include('includes.menus._partials.item', $menu)
    @endforeach
    </ul>
@else
    @include('includes.menus.empty')
@endif

Precisamos criar duas views, a primeira é a resources/views/includes/menus/empty.blade.php com uma mensagem informando que não existem itens no menu:

Sem menu

Lembrando que é opcional criar essa view empty.blade.php, vai de cada caso.

A próxima view que vamos criar é exatamente a view resources/views/includes/menus/_partials.item.blade.php

Essa view tem um propósito maior, além de exibir as opções

  • ela também será recursiva, ou seja, como nosso menu tem a posição “sub-menu” que recebe um array com o sub-menu, vamos reutilizar essa mesma view para exibir as opções disponíveis do sub-menu, caso tenha sub-menu:

    <li>
        <a href="{{ $menu['url'] }}">{{ $menu['name'] }}</a>
    </li>
    @if (count($menu['sub-menu']) > 0)
        <ul>
        @foreach($menu['sub-menu'] as $menu)
            @include('includes.menus._partials.item', $menu)
        @endforeach
        </ul>
    @endif
    

    Observe que estamos verificar se a quantidade de registros no array $menu[‘sub-menu’] é maior do zero, caso seja, é porque esse item do menu existe um sub-items, ou seja, sub-menus.

    Se testar agora vai notar que ficou 100% montado o nosso menu, com cada sub-menu.

    Mas, podemos melhorar ainda mais esse nosso exemplo. Podemos excluir a view resources/views/includes/menus/menu.blade.php e no arquivo de template onde inclui essa view trocar a diretiva @include, pela diretiva @each, dessa forma:

    @each('includes.menus._partials.item', $menus, 'menu', 'includes.menus.empty')
    

    O primeiro parâmetro da diretiva é a view que monta a <li></li>, o segundo é o array com os registros, o terceiro é o nome da variável com o nome de cada registro, normalmente o nome da variável com os registro no singular, e o quarto e opcionalmente último parâmetro é uma view com a mensagem default caso a variável $menus esteja vazia.

    O nosso menu continua funcionando perfeitamente, mas a diretiva @each consegue de forma muito inteligente substituir a view menu.blade.php, deixando nosso exemplo muito mais enxuto e funcional.

     
     

    Stacks:

    Outro recurso muito útil do Blade é o Stacks, com esse recurso é possível “injetar” dinamicamente recursos em diferentes views.

    Um exemplo disso é quando temos vários arquivos por exemplo .js, mas, um arquivo específico será usado em apenas 2 views. Nesse caso, não faz sentido algum inserir esse arquivo .js no template, porque dessa forma ele ficaria sendo carregado em toda a aplicação, e de forma desnecessária. A solução para resolver esse problema e carregar esse arquivo .js nas views que realmente precisam, usando Stacks. Antes de fechar a tag <body> do template insira a diretiva:

    @stack('scripts')
    

    Ao fazer isso nada muda no template. Agora para inserir dinamicamente um novo arquivo de .js que está em public/js/custom.js em uma view especifica, podemos fazer dessa forma:

    @push('scripts')
        <script src="{{ url('js/custom.js') }}"></script>
    @endpush
    

    Dessa forma toda vez que essa view for renderizada será adicionado dinamicamente o script na página.

    A partir da versão 5.6 o Laravel incluiu a diretiva @prepend, com essa diretiva é possível inserir os scripts dinâmicamente, e antes dos demais. Exemplo:

    @push('scripts')
        <script src="{{ url('js/custom.js') }}"></script>
    @endpush
    
    @prepend('scripts')
        <script src="{{ url('js/custom.js') }}"></script>
    @endprepend
    

     
     

    Blade Service Injection:

    Para exemplicar os benefícios desse recursos vamos imaginar um exemplo real, temos um menu no template, e nele tem as categorias que vem do banco de dados:

    <ul class="menu">
        <li><a href="{{ route('home') }}">Home</a></li>
        <li>
            <a href="#">Categorias</a>
            <ul>
                @foreach ($categories as $category)
                    <li>
                        <a href="{{ route('category.show', $category->slug) }}">
                            {{ $category->name }}
                        </a>
                    </li>
                @endforeach
            </ul>
        </li>
        <li><a href="{{ route('home') }}">Contato</a></li>
    </ul>
    

    Como esse menu está no template vamos precisar que toda view passe a variável $categories para a view, caso contrário teremos um erro. Temos um grande problema em mãos!

    Uma das soluções nesse caso é utilizar o recurso de Service Injection do Blade.

    A diretiva @inject recebe dois argumentos, o primeiro é um nome da variável, e o segundo é o service container, que é uma classe que será instânciada e atribuída na variável do primeiro argumento. Para exemplificar no template crie dessa forma:

    @inject('resources', 'App\Services\ResourcesService')
    

    Agora crie um novo arquivo de classe em app/Services/ chamado CategoriesService.php, com o seguinte conteúdo:

    namespace App\Services;
    
    use App\Models\Category;
    
    class ResourcesService
    {
        
        public function categories()
        {
            return Category::all();
        }
    
    }
    

    Agora para recuperar as categorias, basta fazer $resources->categories(), isso porque $resources é um objeto da classe ResourcesService. Nosso menu fica dessa forma:

    @inject('resources', 'App\Services\ResourcesService')
    
    <ul class="menu">
        <li><a href="{{ route('home') }}">Home</a></li>
        <li>
            <a href="#">Categorias</a>
            <ul>
                @foreach ($resources->categories() as $category)
                    <li>
                        <a href="{{ route('category.show', $category->slug) }}">
                            {{ $category->name }}
                        </a>
                    </li>
                @endforeach
            </ul>
        </li>
        <li><a href="{{ route('home') }}">Contato</a></li>
    </ul>
    

     
     

    Diretivas Personalizadas:

    Um ponto interessante do Blade é que ele possibilita criar suas próprias diretivas, e com isso criar recursos customizados para te atender melhor.

    Para exemplicar criar uma diretiva que imprime o @ antes do valor.

    Mas, por que esse exemplo?

    Porque caso você tente imprimir uma variável dessa forma vai gerar erro @{{ $username }}

    Sabemos que quando a diretiva @{{}} é usado para imprimir valores de variáveis JS. Para conseguir imprimir colocando o @ antes do valor da variável precisamos fazer isso: {{ ‘@’ . $username }}. Esse código fica bem estranho, confesso. Por esse motivo vamos criar um diretiva chamada por exemplo pc (Print Custom) que vai imprimir o valor de uma variável colocando o @ antes.

    No provider AppServiceProvider (app/Providers/AppServiceProvider.php) no método boot() vamos criar a nossa diretiva chamada pc dessa forma:

    // Não esquece: use Illuminate\Support\Facades\Blade;
    Blade::directive('pc', function ($value) {
        return "<?php echo '@' . $expression; ?>";
    });
    

    Pronto! Uma vez que a diretiva foi definida agora podemos usá-la sempre que for necessário em nossas views blade. Assim:

    @pc($username)
    

     

    IFs customizados

    Também podemos criar IFs personalizados. Para exemplificar vou usar o próprio exemplo da documentação do Laravel, que é um exemplo bastante útil.

    No provider AppServiceProvider (app/Providers/AppServiceProvider.php) no método boot() podemos definir nosso if personalizado:

    // Não esquece: use Illuminate\Support\Facades\Blade;
    Blade::if('env', function ($environment) {
        return app()->environment($environment);
    });
    

    Agora nas views blade podemos utilizar essa nova diretiva condicional dessa forma:

    @env('local')
        // Ambiente local
    @elseenv('testing')
        // Ambiente de teste
    @else
        // Aplicação em produção
    @endenv
    

    Particularmente uso essa diretiva para inserir algum script adicional em produção, como por exemplo, um script externo de algum chat, ou algum pixel de vendas do Facebook, e etc.

     
     

    Outras Opções do Blade:

    Caso seja necessário documentar na view alguma funcionalidade podemos trabalhar com comentários, para isso podemos fazer dessa forma:

    {{-- Comentário de código, não vai aparecer no HTML --}}
    

    Outro recurso é caso seja necessário fazer alguma PEQUENA verificação na view, para isso o blade dispõe da diretiva @php e @endphp
    Não é muito recomendado o uso dessa diretiva, apenas use em casos extremos, e realmente necessários.

    Um exemplo, se tivemos uma lista de produtos sendo exibida na view, e esses produtos podem ou não ter imagens associadas, nesse caso podemos definir o path da imagem dinamicamente, exemplo:

    @foreach ($products as $product)
    
        @php
            $path = url('imgs/default.png');
    
            if ($product->image)
                $path = url("storage/products/{$product->image}");
        @endphp
        
        <img src="{{ $path }}" alt="{{ $product->name }}" class="img-product">
    
        {{ $product->name }}
    
    @endforeach
    

    Nesse pequeno exemplo utilizar a diretiva @php pode ser mais viável do que fazer @if e @else para validar se a imagem existe e repetir a tag

     

  • Carlos Ferreira

    Sobre o Autor:

    Carlos Ferreira

    Carlos Ferreira é Analista de Sistemas Experiente, Empreendedor, Fundador da empresa EspecializaTi. Certificações: Comptia Linux +, LPI, Novell Certification.

    Todos os direitos reservados © 2018 - EspecializaTi. É proibida a reprodução total ou parcial deste conteúdo.