Blog de Notícias

Laravel Blade

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:

1

2

3

4

#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:

1

2

3

$name = 'Carlos';

$lastName = 'Ferreira';

return view('path.name-view', compact('name', 'lastName'));

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

1

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

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

1

2

3

4

5

6

7

8

// 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:

1

2

3

4

5

6

7

8

#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:

1

{{ $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:

1

2

3

4

5

6

7

<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:

1

@{{ 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 @

1

2

3

4

5

@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:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

<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:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

@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:

1

@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:

1

2

3

@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:

1

2

3

4

5

@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:

1

2

3

<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:

1

2

3

4

5

<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:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

@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:

1

2

3

4

5

6

7

8

9

<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:

1

2

@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”:

1

2

// 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:

1

2

3

4

5

6

7

@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:

1

2

3

<div class="alert alert-{{ $type or 'danger' }}">

    [...]

</div>

E pra passar esse tipo, pode fazer assim:

1

2

3

@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:

1

2

3

4

5

6

7

@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:

1

2

3

4

5

@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

1

2

3

4

5

@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:

1

2

3

4

5

@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:

1

2

3

4

5

6

7

8

9

10

11

12

@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:

1

2

3

4

5

6

7

@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:

1

2

3

4

5

6

7

8

9

10

11

12

@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

1

2

3

@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:

1

2

3

4

5

6

7

8

9

<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:

1

2

3

4

5

6

7

<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

1

2

3

4

5

6

7

8

9

@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:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

<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:

1

2

3

<div>

    Sub-view

</div>

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

1

@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:

1

2

3

4

<div class="{{ $class or 'default' }}">

    Sub-view

    <p>{{ $varName }}</p>

</div>

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

1

@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:

1

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

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

1

@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:

1

@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:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

$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:

1

2

3

4

5

6

7

8

9

@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:

     

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    <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:

    1

    @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:

    1

    @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:

    1

    2

    3

    @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:

    1

    2

    3

    4

    5

    6

    7

    @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:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    <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:

    1

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

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

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    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:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    @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:

    1

    2

    3

    4

    // 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:

    1

    @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:

    1

    2

    3

    4

    // 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:

    1

    2

    3

    4

    5

    6

    7

    @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:

    1

    {{-- 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:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    @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