Atributo View


1Visão geral

O Temma fornece um atributo que permite especificar a visão usada por um controlador em geral e/ou por uma ação específica.


2Definição da visão

2.1Definição da visão: princípio

O atributo recebe um primeiro parâmetro opcional null|false|string $view, usado para especificar a visão a ser utilizada.

Esse parâmetro pode ser vazio ou nulo; nesse caso, é usado o valor defaultView definido no arquivo etc/temma.php (se esse valor não estiver definido, é usada a visão Smarty).

O parâmetro também pode ser definido como false, o que desativa a renderização da visão.

Se a string passada como parâmetro começar com o caractere til (~), isso significa que o restante da string contém o nome de uma visão padrão fornecida pelo Temma. Nesse caso, o prefixo \Temma\Views\ é adicionado.
Por exemplo: ~Json será interpretado como \Temma\Views\Json


2.2Definição da visão: exemplos

Para fazer com que todas as ações de um controlador usem a visão JSON:

use \Temma\Attributes\View as TµView;

#[TµView('~Json')]
class MyController extends \Temma\Web\Controller {
    // ...
}

Para fazer com que uma ação específica use a visão RSS (as demais ações continuam usando a visão padrão normalmente):

use \Temma\Attributes\View as TµView;

class MyController extends \Temma\Web\Controller {
    // Usa a visão RSS
    #[TµView('~Rss')]
    public function myAction() {
        // ...
    }

    // Usa a visão padrão
    public function myOtherAction() {
        // ...
    }
}

Para fazer com que todas as ações usem a visão JSON, exceto uma ação específica que usa a visão RSS, e outra que usa a visão padrão:

use \Temma\Attributes\View as TµView;

// define a visão JSON para este controlador
#[TµView('~Json')]
class MyController extends \Temma\Web\Controller {
    // esta ação usa a visão JSON
    public function firstAction() {
        // ...
    }

    // esta ação também usa a visão JSON
    public function secondAction() {
        // ...
    }

    // esta ação usa a visão RSS
    #[TµView('~Rss')]
    public function thirdAction() {
        // ...
    }

    // esta ação usa a visão padrão
    #[TµView]
    public function fourthAction() {
        // ...
    }
}

Para desativar a renderização de visão para uma ação:

use \Temma\Attributes\View as TµView;

class MyController extends \Temma\Web\Controller {
    // nenhuma visão é executada após esta ação
    #[TµView(false)]
    public function sayHello() {
        print('Hello');
    }
}

3Negociação de conteúdo

3.1Negociação de conteúdo: princípio

O atributo pode receber um segundo parâmetro opcional null|bool|string|array $negotiation, usado para ativar a negociação de conteúdo. Quando ativada, a visão usada é adaptada ao tipo de conteúdo solicitado pelo cliente.

Se o parâmetro for definido como true, o atributo ativa automaticamente a visão Smarty, JSON, CSV, RSS ou iCal, dependendo do que o navegador enviar no cabeçalho Accept.

Se o parâmetro for uma string, ela deve conter uma lista de valores (separados por vírgula) aceitos no cabeçalho Accept (ou aliases, veja abaixo), para os quais o atributo ativará automaticamente a visão correspondente.

Se o parâmetro for uma lista, ela deve conter valores aceitos no cabeçalho Accept (ou aliases, veja abaixo), para os quais o atributo ativará automaticamente a visão correspondente.

Se o parâmetro for um array associativo, suas chaves devem ser valores aceitos no cabeçalho Accept (ou aliases, veja abaixo), e os valores devem ser nomes de objetos de visão.

Tipo MIME Alias Visão
text/html html Smarty
application/xhtml+xml xhtml Smarty
application/json json JSON
text/csv csv CSV
application/rss+xml rss RSS
text/calendar calendar iCal

3.2Negociação de conteúdo: exemplos

Para adaptar automaticamente a visão à requisição do cliente:

use \Temma\Attributes\View as TµView;

#[TµView(negotiation: true)]
class MyController extends \Temma\Web\Controller {
    // ...
}

Para enviar JSON quando solicitado, e usar a visão padrão caso contrário:

use \Temma\Attributes\View as TµView;

#[TµView(negotiation: 'json')]
class MyController extends \Temma\Web\Controller {
    // ...
}

Para especificar objetos de visão com base no que o cliente solicita:

use \Temma\Attributes\View as TµView;

#[TµView(negotiation: [
    'json'             => '~Json',                  // para JSON, usa a visão JSON fornecida pelo Temma
    'application/toml' => '\Toml\TemmaView',        // visão específica para o formato TOML
    'application/pdf'  => '\App\View\PdfGenerator', // visão específica para arquivos PDF
])]
class MyController extends \Temma\Web\Controller {
    // ...
}

Para especificar que a visão INI deve ser usada por padrão, permitindo ainda respostas em JSON ou CSV caso o cliente as solicite explicitamente:

use \Temma\Attributes\View as TµView;

#[TµView('~Ini', negotiation: 'json, csv')]
class MyController extends \Temma\Web\Controller {
    // ...
}

É possível recuperar a visão atualmente em uso a partir do objeto Response:

use \Temma\Attributes\View as TµView;

#[TµView(negotiation: 'html, xhtml, json, csv')]
class MyController extends \Temma\Web\Controller {
    public function myAction() {
        $data = /* processing */;
        // verifica a visão ativa
        $view = $this->_response->getView();
        if ($view == '\Temma\Views\Json') {
            $this['json'] = $data;
        } else if ($view == '\Temma\Views\Csv') {
            $this['csv'] = $data;
            $this['filename'] = 'export.csv';
        } else {
            $this['data'] = $data;
        }
    }
}

4Visão condicional

Quando a visão a ser usada não pode ser determinada com antecedência, o método _view() do controlador deve ser usado para definir a visão:

class MyController extends \Temma\Web\Controller {
    public function myAction() {
        if ($this['responseType'] == 'api') {
            // uso explícito da visão JSON
            $this->_view('~Json');
        }
        // ...
    }
}

É claro que também é possível combinar o atributo com o método _view():

use \Temma\Attributes\View as TµView;

// usa a visão JSON por padrão para este controlador
#[TµView('~Json')]
class MyController extends \Temma\Web\Controller {
    public function myAction() {
        if ($this['must_use_smarty'] == true) {
            // uso explícito da visão Smarty
            $this->_view('~Smarty');
        }
        // ...
    }
}