микрозаймы онлайн займы на карту займы по паспорту

Controllers mais limpos com View Composers 16

Olá pessoal! Hoje vou falar de uma funcionalidade bem interessante do Laravel 4, chama-se View Composers.

Imagine a seguinte situação: Você tem uma loja de produtos, e sempre que acessa-la você gostaria de listar suas categorias. Existem algumas formas de fazer isso, eu, por exemplo usava o View::share para compartilhar uma variável com determinados métodos. É uma boa solução, mas e se pudessemos fazer isso sem sobrecarregar nosso querido Controller?

Laravel faz isso de uma forma limpa e organizada. Para exemplificar, vamos criar um sistema que lista produtos e categorias, não haverá relacionamento nem nada, coisa simples.

Primeiramente vamos à criação das tabelas Products e Categories:

Products
	id,
	category_id,
	name

Categories
	id,
	name

Com as tabelas criadas, criaremos os respectivos Models.

<!--?php <br ?-->// app/models/Product.php

class Product extends Eloquent {

}
<!--?php <br ?-->// app/models/Category.php

class Category extends Eloquent {

}

Para as nossas views eu criei uma pasta dentro de app/views chamada products e dentro dela um arquivo chamado index.blade.php.

@extends('templates.main')
@section('content')
    <div id="content">
        @foreach($products as $product)
            <h2>{{ $product->name }}</h2>
        @endforeach
    </div>
@stop

Nessa view eu estou estendendo o layout main dentro de app/views/templates/. Então vamos criar a pasta templates dentro de app/views e dentro dela criar o arquivo main.blade.php:

<html>
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

    <h1>Main Template</h1>

    <ul>
        @foreach ($categories as $category)

            <li>{{ $category->name }}</li>

        @endforeach
    </ul>

    @yield('content')
    
</body>
</html>

Notem que eu estou listando as categorias aqui. Vamos agora a criação da nossa action.

No Controller a sua escolha ( provavelmente ProductsController ) você criará uma action para buscar os produtos e entregar para a view, ele ficará mais ou menos assim:

...
public function index()
{
	$products = Product::all();
	return View::make('products.index', compact('products'));
}
// compact é uma função do php que gera uma array no formato array(“parametro” => $parametro)
...

Se você tentar rodar o sistema agora, provavelmente irá dar erro, dizendo que não encontrou a variável $categories, e é aqui onde entra o “pulo do gato”.

Já que o objetivo aqui é organização, vamos criar uma pasta dentro de app chamada viewComposers, dentro dela, vamos criar uma classe chamada CategoryComposer:

<?php
// app/viewComposers/CategoryComposer.php

class CategoryComposer {

    public function compose($view)
    {
        $categories = Category::all();

        $view->with(compact('categories'));
    }

}

Veja que essa é uma classe simples, com uma única função: compose que recebe como parâmetro uma $view;

Dentro dela estamos fazendo mais ou menos o que normalmente faríamos em um Controller comum.

Agora que criamos essa classe, precisamos dizer ao Laravel, que toda vez que usarmos o layout templates/main queremos que ele chame essa classe. Eu coloquei essa função dentro de app/routes.php:

View::composer('templates.main', 'CategoryComposer');

Agora, precisamos atualizar o nosso autoload, porque criamos um novo diretório dentro de app, então, vamos atualizar nosso composer.json e em seguida mapea-lo pelo composer.

"autoload": {
	"classmap": [
	  ...
		"app/viewComposers"
	]
},

E na linha de comando:

composer dump
// composer dump é um atalho para composer dump-autoload

Se tudo der certo você verá que agora nosso sistema está listando tanto as categorias quantos os produtos, com uma vantagem do código estar mais limpo e organizado.

Vale notar que o CategoryComposer criado é específico, porém se você precisa instanciar mais coisas para um mesmo Controller ( ou template ) você pode deixa-lo mais genérico ( ProductComposer por exemplo ) para não precisar criar muitas classes.

E isso é tudo pessoal, espero que tenham gostado!

Update: Pra quem quiser dar uma olhada no projeto inteiro funcionando, disponibilizei no github o projeto com ele funcionando.

  • Fabyo

    Muito bom!

  • fhferreira

    Bacana Diego, vlw por compartilhar… auxiliará em vários casos.

  • Bruno Kawakami

    To testando já huahauhau

  • Diego Felix

    Obrigado pessoal!

  • edyonil

    Salva no caso de menus dinâmicos também

    • Diego Felix

      Boa!

  • Fuhrmann

    Muito foda…valeu pela dica!

  • herique

    seria possivel disponibilizar o codigo????

    o meu num deu aqui não

    • Diego Felix

      É sim, vou colocar no github e deixo o link aqui.

      • herique

        SALVOU UMA VIDA EM 3…..2…..1….. HEHEHE

  • http://www.patrickmaciel.com.br Patrick Maciel

    O meu continua não dando certo.
    Não sei porque, simplesmente diz que a variável que estou enviando pra view, com o View Composer não existe.

    • http://brayanrastelli.com/ Brayan Rastelli

      Patrick, coloca la no fórum para ficar melhor do pessoal te ajudar, ok?

      Abs.

      • http://www.patrickmaciel.com.br Patrick Maciel

        Sim, já coloquei, você já respondeu e já está resolvido :)

        Muito obrigado.

    • Diego Felix

      Posta lá no fórum, como o Brayan disse, estamos aguardando =)

  • Filipe

    Obrigado por compartilhar.

  • Carlos Henrique Pinheiro

    o meu diz que não existe a classe