Views (ou Visões) são o V do MVC. Views são responsáveis por gerar a saída de dados específica para uma determinada requisição. Geralmente esta saída é apresentada na forma de HTML, XML ou JSON. No entanto, disponibilizar arquivos através de streaming (fluxo de informação, geralmente multimídia, através de pacotes) ou criar PDFs, que podem ser baixados, também são de responsabilidade da Camada View.
O CakePHP traz incluso várias classes do tipo View para lidar com os cenários mais comuns de renderização:
Para criar webservices em XML ou JSON, você pode usar o JSON and XML views
Para prover arquivos protegidos ou arquivos criados dinamicamente, você pode usar Media Views
Para criar múltiplos temas para as visões, você pode usar Themes
Em CakePHP, você fala com seus usuários através da camada view (visão). Na maior parte do tempo, suas views exibirão documentos (X)HTML nos navegadores, mas você pode também precisar prover dados AMF para um objeto em Flash, responder a uma aplicação remota via SOAP ou gerar um arquivo CSV para um usuário.
Por padrão, no CakePHP os arquivos do tipo view são escritos em PHP comum e possuem a extensão .ctp (CakePHP Template). Estes arquivos contém toda a lógica de apresentação necessária para transformar os dados recebidos do controller em um formato pronto para o público. Caso você prefira usar uma linguagem de template como Twig ou Smarty, uma subclasse da View irá fazer uma ponte entre sua linguagem de template e o CakePHP.
Arquivos do tipo view são guardados em /app/View/
, dentro do
diretório com o nome do controller que usa os arquivos e nomeado
de acordo com a ação correspondente. Por exemplo, a ação “view()”
do controller Products será normalmente encontrada em
/app/View/Products/view.ctp
.
A camada view no CakePHP pode ser composta de diferentes partes. Cada parte tem diferentes usos e serão cobertas em seções específicas:
views: views é a única parte da página que está em execução. Compõem a parte crucial da resposta da aplicação.
elements: pedaços de código pequenos e reutilizáveis. Elements geralmente são renderizados dentro de views.
layouts: arquivos da view contendo código de apresentação que envolve várias interfaces da aplicação. A maior parte dos arquivos views é renderizada dentro de um layout.
helpers: essas classes encapsulam lógica da view que seja necessária em vários lugares na camada view. Helpers no CakePHP podem ajudá-lo a construir formulários, construir funcionalidade AJAX, paginar dados do model, prover feeds RSS, dentre outras coisas.
Novo na versão 2.1.
A extensão de uma View permite que você inclua uma view dentro de outra. Combinando isto com view blocks você tem uma maneira poderosa para deixar suas views DRY (enxutas). Por exemplo, sua aplicação tem uma barra lateral (sidebar) que precisa mudar a depender de quando uma view específica é renderizada. Estendendo um mesmo arquivo de view, você pode evitar repetições de marcações em comum e apenas definir as que mudam:
// app/View/Common/view.ctp
<h1><?php echo $this->fetch('title'); ?></h1>
<?php echo $this->fetch('content'); ?>
<div class="actions">
<h3>Related actions</h3>
<ul>
<?php echo $this->fetch('sidebar'); ?>
</ul>
</div>
O arquivo de view acima pode ser usado como uma view pai. Esta espera
que a view que a estende defina os blocos sidebar
e title
. O bloco
content
é um bloco especial que o CakePHP cria. Ele conterá todo o conteúdo
não-capturado da view que a estende. Considerando que nosso arquivo view
tem uma variável $post
com informação sobre nosso post, nossa view
poderá parecer como:
<?php
// app/View/Posts/view.ctp
$this->extend('/Common/view');
$this->assign('title', $post)
$this->start('sidebar');
?>
<li> echo $this->Html->link('edit', array(
'action' => 'edit',
$post['Post']['id']
)); ?>
</li>
<?php $this->end(); ?>
// O conteúdo restante estará disponível como o bloco `content`
// na view pai.
echo h($post['Post']['body']);
A view de post acima mostra como você pode estender uma view e
preenche-la com um conjunto de blocos. Qualquer conteúdo que não estiver
definido em um bloco será capturado e colocado em um bloco especial chamado
content
. Quando uma view contém uma chamada para extend()
, a execução
continua até o fim do arquivo view atual. Uma vez finalizada, a view
estendida será renderizada. Chamar extend()
mais de uma vez em um
arquivo view irá sobrescrever a view pai que será processada em seguida:
$this->extend('/Common/view');
$this->extend('/Common/index');
O trecho acima resultará em /Common/index.ctp
sendo renderizada como a
view pai para a view atual.
Você pode aninhar views estendidas quantas vezes forem necessárias. Cada
view pode estender outra view se quiser. Cada view pai pegará
o conteúdo da view anterior como o bloco content
.
Nota
Você deve evitar o uso de content
como o nome de um bloco em sua aplicação.
CakePHP usa este nome em views estendidas para conteúdos não-capturados.
Novo na versão 2.1.
Blocos de views substituem $scripts_for_layout
e provêm uma API flexível que
permite criar slots ou blocos em suas views/layouts que podem ser definidas
em qualquer lugar. Por exemplo, blocos são ideais para implementar recursos como
barras laterais ou regiões para carregar seções na parte de baixo ou no topo
do layout.
Blocos podem ser definidos de duas formas. Seja capturando um bloco ou por atribuição
direta. Os métodos start()
, append()
e end()
permitem trabalhar com
captura de blocos:
// cria um bloco lateral.
$this->start('sidebar');
echo $this->element('sidebar/recent_topics');
echo $this->element('sidebar/recent_comments');
$this->end();
// Concatena na barra lateral em seguida.
$this->append('sidebar');
echo $this->element('sidebar/popular_topics');
$this->end();
Também é possível concatenar blocos utilizando o método start()
múltiplas vezes.
O método assign()
pode ser usado para limpar ou sobrescrever o bloco:
// Limpa o conteúdo anterior da barra lateral.
$this->assign('sidebar', '');
Nota
Você deve evitar o uso de content
como o nome de um bloco em sua aplicação.
CakePHP usa este nome em views estendidas para conteúdos não-capturados .
Novo na versão 2.1.
Você pode exibir blocos usando o método fetch()
. fetch()
irá retornar
um bloco de maneira segura, retornando ‘’ se o bloco não existir”:
echo $this->fetch('sidebar');
Você também pode usar o fetch para exibir condicionalmente um conteúdo que deve envolver um bloco que deveria existir. Isto é útil em layouts ou views estendidas, nas quais você queira mostrar cabeçalhos e outras marcações condicionalmente:
// em app/View/Layouts/default.ctp
<?php if ($this->fetch('menu')): ?>
<div class="menu">
<h3>Menu options</h3>
<?php echo $this->fetch('menu'); ?>
</div>
<?php endif; ?>
Novo na versão 2.1.
Blocos substituem a variável obsoleta $scripts_for_layout
do layout. Em vez
de usá-la, você deve usar blocos. A HtmlHelper
vincula-se aos blocos da
view e a cada um dos seus métodos php:meth:~HtmlHelper::script(), css()
e meta()
quando o bloco com o mesmo nome utiliza a opção inline = false
:
<?php
// no seu arquivo de view
$this->Html->script('carousel', array('inline' => false));
$this->Html->css('carousel', array('inline' => false));
?>
// no seu arquivo de layout
<!DOCTYPE html>
<html lang="en">
<head>
<title><?php echo $this->fetch('title'); ?></title>
<?php echo $this->fetch('script'); ?>
<?php echo $this->fetch('css'); ?>
</head>
// o resto do layout continua
A HtmlHelper
também permite você controlar para que bloco os scripts e CSS vão:
// na sua view
$this->Html->script('carousel', array('block' => 'scriptBottom'));
// no seu layout
echo $this->fetch('scriptBottom');
Um layout contem o código de apresentação que envolve uma view. Qualquer coisa que você queira ver em todas as suas views deve ser colocada em um layout.
Arquivos de layouts devem ser colocados em /app/View/Layouts
. O
layout padrão do CakePHP pode ser sobrescrito criando um novo layout
padrão em /app/View/Layouts/default.ctp
. Uma vez que um novo layout
padrão tenha sido criado, o código da view renderizado pelo controller
é colocado dentro do layout padrão quando a página é renderizada.
Quando você cria um layout, você precisa dizer ao CakePHP onde colocar
o código de suas views. Para isso, garanta que o seu layout inclui
um lugar para $this->fetch('content')
. A seguir, um exemplo de como
um layout padrão deve parecer:
<!DOCTYPE html>
<html lang="en">
<head>
<title><?php echo $title_for_layout?></title>
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
<!-- Incluir arquivos extenos e scripts aqui (Ver o helper HTML para mais detalhes) -->
echo $this->fetch('meta');
echo $this->fetch('css');
echo $this->fetch('script');
?>
</head>
<body>
<!-- Se você quiser exibir algum menu
em todas as suas views, inclua-o aqui -->
<div id="header">
<div id="menu">...</div>
</div>
<!-- Aqui é onde eu quero que minhas views sejam exibidas -->
<?php echo $this->fetch('content'); ?>
<!-- Adicionar um rodapé para cada página exibida -->
<div id="footer">...</div>
</body>
</html>
Nota
Na versão anterior a 2.1, o método fetch() não estava disponível, fetch('content')
é uma substituição para $content_for_layout
e as linhas fetch('meta')
,
fetch('css')
and fetch('script')
estavam contidas na variável $scripts_for_layout
na versão 2.0.
Os blocos script
, css
e meta
contém qualquer conteúdo definido
nas views usando o helper HTML embutido. Útil na inclusão de arquivos javascript
e CSS de views.
Nota
Quando usar HtmlHelper::css()
ou HtmlHelper::script()
em views, especifique ‘false’ para a opção ‘inline’ para colocar o código html
em um bloco de mesmo nome. (Veja a API para mais detalhes de uso)
O bloco content
contem o conteúdo da view renderizada.
$title_for_layout
contém o título da página, Esta variável é gerada automaticamente,
mas você poderá sobrescrevê-la definindo-a em seu controller/view.
Para definir o título para o layout, o modo mais fácil é no controller, setando
a variável $title_for_layout
:
class UsersController extends AppController {
public function view_active() {
$this->set('title_for_layout', 'View Active Users');
}
}
Você também pode setar a variável title_for_layout no arquivo de view:
$this->set('title_for_layout', $titleContent);
Você pode criar quantos layouts você desejar: apenas coloque-os no
diretório app/View/Layouts
, e defina qual deles usar dentro das ações
do seu controller usando a propriedade $layout
do
controller ou view:
// de um controller
public function admin_view() {
// códigos
$this->layout = 'admin';
}
// de um arquivo view
$this->layout = 'loggedin';
Por exemplo, se a seção do meu site incluir um pequeno espaço para banner, eu posso criar um novo layout com um pequeno espaço para propaganda e especificá-lo como layout para as ações de todos os controllers usando algo como:
class UsersController extends AppController {
public function view_active() {
$this->set('title_for_layout', 'View Active Users');
$this->layout = 'default_small_ad';
}
public function view_image() {
$this->layout = 'image';
//output user image
}
}
O CakePHP tem em seu núcleo, dois layouts (além do layout padrão)
que você pode usar em suas próprias aplicações: ‘ajax’ e ‘flash’.
O layout Ajax é útil para elaborar respostas Ajax - é um layout vazio
(a maior parte das chamadas ajax requer pouca marcação de retorno,
preferencialmente a uma interface totalmente renderizada). O layout
flash é usado para mensagens mostradas pelo método Controller::flash()
.
Outros três layouts, XML, JS, e RSS, existem no núcleo como um modo rápido e fácil de servir conteúdo que não seja text/html.
Novo na versão 2.1.
Se você quiser usar um layout que existe em um plugin, você pode usar a sintaxe de plugin. Por exemplo, para usar o layout de contato do plugin de contatos:
class UsersController extends AppController {
public function view_active() {
$this->layout = 'Contacts.contact';
}
}
Muitas aplicações possuem pequenos blocos de código de apresentação que precisam ser repetidos a cada página, às vezes em diferentes lugares no layout. O CakePHP ajuda você a repetir partes do seu website que precisam ser reutilizados. Estas partes reutilizáveis são chamadas de Elements (ou Elementos). Propagandas, caixas de ajuda, controles de navegação, menus extras, formulários de login e chamadas geralmente são implementadas como elements. Um element é básicamente uma mini-view que pode ser incluída em outras views, layouts e até mesmo em outros elements. Elements podem ser usados para criar uma view mais legível, colocando o processamento de elementos repetidos em seu próprio arquivo. Eles também podem ajudá-lo a re-usar conteúdos fragmentados pela sua aplicação.
Elements são colocados na pasta /app/View/Elements/
e possuem a extensão .ctp
no nome do arquivo. Eles são exibidos através do uso do método element
da view:
echo $this->element('helpbox');
Você pode passar dados para um element através do segundo argumento do element:
echo $this->element('helpbox', array(
"helptext" => "Oh, este texto é muito útil."
));
Dentro do arquivo do element, todas as variáveis passadas estão disponíveis como
membros do array de parâmetros (da mesma forma que Controller::set()
no
controller trabalha com arquivos de views). No exemplo acima, o arquivo
/app/View/Elements/helpbox.ctp
pode usar a variável $helptext
:
// Dentro de app/View/Elements/helpbox.ctp
echo $helptext; //outputs "Oh, este texto é muito útil."
O método View::element()
também suporta opções para o element.
As opções suportadas são ‘cache’ e ‘callbacks’. Um exemplo:
echo $this->element('helpbox', array(
"helptext" => "Isto é passado para o *element * como $helptext",
"foobar" => "TIsto é passado para o *element * como $foobar",
),
array(
"cache" => "long_view", // usa a configuração de cache "long_view"
"callbacks" => true // atribue verdadeiro para ter before/afterRender chamado pelo *element*
)
);
O cache de element é facilitado através da classe Cache
. Você pode
configurar elements para serem guardados em qualquer configuração de cache que você
tenha definido. Isto permite uma maior flexibilidade para decidir onde e por quantos
elements são guardados. Para fazer o cache de diferentes versões de um mesmo element
em uma aplicação, defina uma única chave de cache usando o seguinte formato:
$this->element('helpbox', array(), array(
"cache" => array('config' => 'short', 'key' => 'unique value')
)
);
Você pode tirar vantagem de elements usando
requestAction()
. A função requestAction()
carrega variáveis da
views a partir de ações do controller e as retorna como um array.
Isto habilita seus elements para atuar verdadeiramente no estilo MVC. Crie
uma ação de controller que prepara as variáveis da view para seu element, depois
chame requestAction()
no segundo parâmetro do element()
para carregar as variáveis
da view a partir do seu controller.
Para isto, em seu controller, adicione algo como segue, como exemplo de Post:
class PostsController extends AppController {
// ...
public function index() {
$posts = $this->paginate();
if ($this->request->is('requested')) {
return $posts;
} else {
$this->set('posts', $posts);
}
}
}
Em seguida, no element, você poderá acessar os modelos de posts paginados. Para obter os últimos cinco posts em uma lista ordenada, você pode fazer algo como:
<h2>Latest Posts</h2>
<?php $posts = $this->requestAction('posts/index/sort:created/direction:asc/limit:5'); ?>
<?php foreach ($posts as $post): ?>
<ol>
<li><?php echo $post['Post']['title']; ?></li>
</ol>
<?php endforeach; ?>
Você pode tomar proveito do CakePHP view caching, se você fornecer
um parâmetro de cache. Se definido como true, o element será guardado
na configuração de cache ‘default’. Caso contrário, você poderá definir
qual configuração de cache deve ser usada. Veja Caching
para mais informações de configuração Cache
. Um exemplo simples
de caching um element seria:
echo $this->element('helpbox', array(), array('cache' => true));
Se você renderiza o mesmo element mais que uma vez em uma view e tem caching ativado, esteja certo de definir o parâmetro chave (key) para um nome diferente cada vez. Isto irá prevenir que cada chamada sucessiva substitua o resultado armazenado da chamada element() anterior. E.g.:
echo $this->element(
'helpbox',
array('var' => $var),
array('cache' => array('key' => 'first_use', 'config' => 'view_long')
);
echo $this->element(
'helpbox',
array('var' => $differenVar),
array('cache' => array('key' => 'second_use', 'config' => 'view_long')
);
O código acima garante que ambos os resultados do element serão armazenados separadamente.
Se você quiser que todos os elementos armazenados usem a mesma configuração de cache, você
pode salvar alguma repetição, setando View::$elementCache
para a configuração
de cache que você quer usar. O CakePHP usará esta configuração, quando nenhuma outra for dada.
Para carregar um element de um plugin, use a opção plugin (retirada da opção data na versão 1.x):
echo $this->element('helpbox', array(), array('plugin' => 'Contacts'));
Se você está usando um plugin e deseja usar elements de dentro deste plugin apenas use plugin syntax. Se a view está renderizando para um controller/action de plugin, o nome do plugin será automaticamente prefixado antes de todos os elements usados, ao menos que outro nome de plugin esteja presente. Se o element não existir no plugin, será procurado na pasta principal da APP.:
echo $this->element('Contacts.helpbox');
Se sua view é parte de um plugin você pode omitir o nome do plugin. Por exemplo,
se você está no ContactsController
do plugin Contatos:
echo $this->element('helpbox');
// and
echo $this->element('Contacts.helpbox');
São equivalentes e resultarão no mesmo elemento sendo renderizado.
Alterado na versão 2.1: A opção $options[plugin]
foi descontinuada e o suporte para
Plugin.element
foi adicionado.
Métodos de Views são acessíveis por todas as views, elements e arquivos de layout.
Para chamar qualquer método de uma view use $this->method()
.
Views têm métodos set()
que são análogos aos set()
encontrados nos objetos controllers. Usando set() em seu arquivo view
serão adicionados variáveis para layouts e elements que serão renderizados
posteriormente. Veja Métodos dos Controllers para maiores informações de como
usar o set().
No seu arquivo de view, você pode:
$this->set('activeMenuButton', 'posts');
Assim em seu layout a variável $activeMenuButton
estará disponível
e conterá o valor ‘posts’.
Obtem o valor de viewVar com o nome $var
Obtem uma lista de todas as variáveis disponíveis da view, no escopo renderizado corrente. Retorna um array com os nomes das variáveis.
Renderiza um elemento ou parte de uma view. Veja a seção Elements para maiores informações e exemplos.
Gera um DOM ID não randômico único para um objeto, baseado no tipo
do objeto e url. Este método é frequentemente usado por helpers que
precisam gerar DOM ID únicos para elementos como JsHelper
:
$uuid = $this->uuid('form', array('controller' => 'posts', 'action' => 'index'));
//$uuid contains 'form0425fe3bad'
Adiciona conteúdo para buffer de scripts internos. Este buffer
é disponibilizado no layout como $scripts_for_layout
. Este
método auxilia na criação de helpers que necessitam adicionar
javascript or css diretamente para o layout. Ciente que scripts
adicionados de layouts, or elements do layout não serão adicionados
para $scripts_for_layout
. Este método é frequentemente usado dentro
dos helpers, como nos Helpers /core-libraries/helpers/js e
HtmlHelper.
Obsoleto desde a versão 2.1: Use a feature Usando Blocos de Views (Visões), ao invés.
Obtem o nome de todos os blocos definidos como um array.
Inicia a caputura de bloco para um bloco de view. Veja a seção em Usando Blocos de Views (Visões) para exemplos.
Novo na versão 2.1.
Finaliza o mais recente bloco sendo capturado. Veja a seção em Usando Blocos de Views (Visões) para exemplos.
Novo na versão 2.1.
Anexa no bloco com $name
. Veja a seção em
Usando Blocos de Views (Visões) para examplos.
Novo na versão 2.1.
Atribui o valor de um bloco. Isso irá sobrescrever qualquer conteúdo existente. Veja a seção em Usando Blocos de Views (Visões) para exemplos.
Novo na versão 2.1.
Fetch o valor do bloco. ‘’ Serão retornados de blocos que não estão definidos Veja a seção em Usando Blocos de Views (Visões) para exemplos.
Novo na versão 2.1.
Estende o view/element/layout corrente com o nome fornecido. Veja a seção em Estendendo Views para examplos.
Novo na versão 2.1.
Seta o layout onde a view corrente será envolvida.
A configuração de cache usada para armazenar elements. Setando esta propriedade a configuração padrâo usada para armazenar elements será alterada Este padrão pode ser sobrescrito usando a opção ‘cache’ no método do element.
Uma instância de CakeRequest
. Use esta instância para acessar
informaçãoes sobre a requisição atual.
Contem o último conteúdo renderizado de uma view, seja um arquivo de view ou conteúdo do layout.
Obsoleto desde a versão 2.1: Use $view->Blocks->get('content');
ao invés.
Uma instância de ViewBlock
. Usada para prover um bloco
de funcionalidades de view na view renderizada.
Novo na versão 2.1.