Introdução ao Laravel Framework – Parte 06: View
✌😎 Saudações, devs!
No último post falamos sobre controladores. Agora vamos falar sobre views, que é a camada da aplicação que provê uma interface gráfica do usuário.
🚀 Bora!
O que são views?
No padrão arquitetural MVC (Model-View-Controller), as views são as populares “telas”, ou mais tecnicamente falando, as interfaces gráficas do usuário (GUI – Graphical User Interface).
Em uma aplicação web as views são normalmente construídas usando a tríade front-end, ou seja, HTML para estruturar o conteúdo, CSS para estilização e Javascript para o comportamento.
Quando uma view é criada sem o uso de padrões de projeto e/ou boas práticas de codificação, ela se torna confusa e de difícil manutenção.
Isso ocorre porque normalmente injetamos código da linguagem server-side em páginas HTML, objetivando tratar laços de repetição, atribuição de dados e outras operações de exibição de dados. Veja o código a seguir:
<?php
foreach($products as $prod) {
?>
<p> <?= $prod->name ?> </p>
<?php
}
?>
O código exibido mostra um laço de repetição em uma página HTML usando código PHP embutido. Dá pra perceber que o código fica confuso e nada semântico, certo? Agora, imagine um código mais complexo.
Para resolver esse e outros problemas o Laravel usa um motor de template chamado Blade.
Blade: o template engine do Laravel
Um template engine (motor de template), também conhecido como view engine (motor de view), é um mecanismo que permite escrever views mais semânticas usando uma sintaxe própria e mais simples, ou seja, não se utiliza a sintaxe PHP.
A principais vantagens desse tipo de ferramenta é que ela deixa o código mais legível, além de proporcionar reusabiliade por meio de herança.
O uso de um template engine não impede que a página seja definida por meio de frameworks responsivos, como o Bootstrap, por exemplo.
O Laravel usa um motor de template chamado Blade: https://laravel.com/docs/8.x/blade
O mesmo código mostrado anteriormente ficaria assim no Blade:
@foreach($products as $prod)
<p> {{ $prod->name }} </p>
@endforeach
Atenção para a sintaxe Blade:
- Comentários no Blade usam a sintaxe
{{-- comentário aqui --}}
- A sintaxe double mustache (bigode duplo:
{{ }}
) é usada para exibir dados ou o resultado de expressões.
Criando uma view simples
No Laravel, as views devem ficar na pasta /resources/views. As views devem possuir a extensão “.blade.php”.
Vamos ao nosso exemplo:
Crie um novo arquivo na pasta /resources/views com o nome product.blade.php. O código da view criada será:
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
{{-- the function env get the environment variables from .env file --}}
<title>{{ env('APP_NAME') }}</title>
</head>
<body>
<h1>Lista de Produtos</h1>
</body>
</html>
Agora abra o arquivos de rotas (routes/web.php) e adicione o seguinte código para retonar a view criada:
Route::get('/product', function(){
return view('product');
});
Na figura a seguir é mostrado a view sendo exibida:
Views e Controllers
Como visto nos posts anteriores, o arquivo de rotas deve se limitar a direcionar a requisição a um controlador. Logo, o ideal é que o controlador seja o responsável por retonar as views ao cliente.
Para isso, abra o arquivo de rotas (routes/web.php) e adicione ou edite a rota product como o código a seguir:
Route::get('/product', [ProductController::class, 'index']);
Depois, abra o controlador de produtos (app/Http/Controllers/ProductController.php) e adicione ou edite o método index() de acordo com o código a seguir:
public function index()
{
return view('product');
}
A função view() retorna as views, considerando como pasta pasta raiz o local padrão resources/views. Assim, você pode criar estruturas de subpastas para organizar melhor as views que farão parte da sua aplicação.
Passando dados para a view
No padrão arquitetural MVC as views devem exibir os dados da camada model. Portanto, antes de retornar as views, precisamos informar quais dados ela irá exibir.
No código a seguir, o controlador, responsável por retonar a view ao cliente, passa o array products para a view products usando o método with().
Esse método consiste em informar um par chave-valor, onde a chave é o nome da variável que será passada para a view e o valor é a variável que será passada. Por questões de legibilidade, recomenda-se manter o mesmo nome na view e no controller.
public function index()
{
return view('product')->with('products', $this->products);
}
O método with pode ser encadeado, ou seja, é possível usá-los diversas vezes, passando vários valores, como no exemplo a seguir:
public function index()
{
return view('product')
->with('products', $this->products)
->with('user')-> $this->user)
->with('favorites', $this->getFavorites());
}
Exibindo dados passados pelo controller
O código a seguir é a view adaptada para mostrar a variável product, caso ela exista. Note que a sintaxe Blade possui diretivas para estruturas condicionais e laços de repetição, além de outras diretivas que veremos adiante.
<h1>Produtos</h1>
<ul>
@if(isset($products))
@foreach ($products as $prod)
<li> {{ $prod }} </li>
@endforeach
@else
<h3>Não há produtos!</h3>
@endif
</ul>
Reutilização de views
Como dito anteriormente, uma das principais vantagens de utilizar template engines está na reutilização de código.
Isso significa que podemos criar uma view contendo a base do nosso layout, com menus, rodapés e outros elementos fixos, e definir em quais espaços o conteúdo será específico para cada view da nossa aplicação.
Vamos a exemplo! 🚀
Crie um arquivo chamado base.blade.php na pasta resources/views. O código dele deve ser o seguinte:
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>{{ env("APP_NAME") }}</title>
</head>
<body>
<div id="container">
<header>
<h1>Cabeçalho do Layout</h1>
</header>
<nav>
<h3>Barra de navegação</h3>
</nav>
<div id="content" style="background-color: beige; min-height: 300px">
{{-- inject specific code here --}}
@yield('content')
</div>
<footer>
<small>Rodapé do layout</small>
</footer>
</div>
</body>
</html>
Observe a linha 19. O diretiva yield do blade cria áreas cujo código será injetado nas views específicas, como veremos a seguir. Nesse exemplo foi criado uma área “injetável” chamada “content”.
Abra a view de produtos (resources/views/products.blade.php) e atualize para o código a seguir. Atenção: Esse é o único código que deve ser mantido.
{{-- inherits the base view --}}
@extends('base')
{{-- inject the code in content section --}}
@section('content')
<h1>Produtos</h1>
<ul>
@if (isset($products))
@foreach ($products as $prod)
<li> {{ $prod }} </li>
@endforeach
@else
<h3>Não há produtos!</h3>
@endif
</ul>
@endsection
A diretiva extends faz com que a view estenda (ou herde) a view base. Por sua vez, a diretiva section injeta o código específico da view. A figura a seguir mostra a view renderizada.
Conclusão
O motor de template do Laravel Framework é o Blade, que permite criar views usando uma sintaxe própria, sem usar a sintaxe PHP. O resultado são views mais legíveis, estruturadas e reutilizáveis.
Existem outros motores de template que podem ser usados com o Laravel. Entretanto, o Blade deve ser a primeira escolha, por ser o padrão do framework e estar em constante atualização.
Conheça outros motores de template baseados em PHP: https://ourcodeworld.com/articles/read/847/top-7-best-open-source-php-template-engines
O Blade permite a integração com outros frameworks, como por exemplo, o Bootstrap, para a construção de views mais elegantes e padronizadas.