As views (visões) fazem parte da arquitetura MVC. São os responsáveis por apresentar dados aos usuários finais. Em um aplicação Web, as views (visões) normalmente são criadas sobre o termo de view templates (modelos de visão) que são arquivos PHP contendo principalmente códigos HTML e códigos PHP de apresentação. A gerência deles são realizadas pelo componente da aplicação view na qual fornece métodos comumente utilizados para facilitar a montagem e a renderização da view (visão). Para simplificar, chamaremos sempre os arquivos view templates (modelos de visão) ou view template (modelo de visão) apenas como views (visões).
Como mencionado anteriormente, uma view (visão) é simplesmente um arquivo PHP composto por HTML ou códigos PHP. A view (visão) a seguir, apresenta um formulário de login. Como você pode observar, o código PHP geralmente é utilizado para gerar conteúdo dinâmico, tais como o título da página e o formulário, enquanto o código HTML é utilizado para deixar a página mais apresentável.
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
/* @var $this yii\web\View */
/* @var $form yii\widgets\ActiveForm */
/* @var $model app\models\LoginForm */
$this->title = 'Login';
?>
<h1><?= Html::encode($this->title) ?></h1>
<p>Please fill out the following fields to login:</p>
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'username') ?>
<?= $form->field($model, 'password')->passwordInput() ?>
<?= Html::submitButton('Login') ?>
<?php ActiveForm::end(); ?>
Em uma view (visão), você pode acessar a variável $this
que referencia o
componente da view (visão) para gerenciar e renderizar a view
(visão) atual.
Além da variável $this
, podem existir outras variáveis predefinidas na view
(visão) como a variável $model
do exemplo anterior. Estas variáveis representam
os dados que foram informados a view (visão) por meio dos
controllers (controladores) ou de outros objetos que
desencadeiam a renderização da view (visão).
Dica: As variáveis predefinidas são listadas em um bloco de comentário no inicio de uma view (visão), de modo que possam ser reconhecidas pelas IDEs. Além de ser uma ótima maneira de documentar suas views (visões).
Ao criar views (visões) que geram páginas HTML, é importante que você codifique ou filtre dados obtidos pelos usuários antes que os apresente. Caso contrário, sua aplicação poderá estar sujeita a sofrer um ataque cross-site scripting.
Para exibir um texto simples, codifique-o antes chamando o método yii\helpers\Html::encode(). Por exemplo, o código a seguir codifica o nome do usuário antes que seja exibido:
<?php
use yii\helpers\Html;
?>
<div class="username">
<?= Html::encode($user->name) ?>
</div>
Para exibir um conteúdo HTML, utilize o método yii\helpers\HtmlPurifier para filtrar o conteúdo primeiro. Por exemplo, o código a seguir filtra o conteúdo que foi postado antes que seja exibido:
<?php
use yii\helpers\HtmlPurifier;
?>
<div class="post">
<?= HtmlPurifier::process($post->text) ?>
</div>
Dica: Enquanto o HTMLPurifier faz um excelente trabalho ao montar uma saída segura, ele não é rápido. Você pode considerar guardar o cache do resultado filtrado caso sua aplicação necessite de o máximo de performance.
Assim como os controllers (controladores) e os models (modelos), existem convenções para organizar as views (visões).
@app/views/IDdoController
por padrão,
onde o IDdoController
refere-se ao ID do controller.
Por exemplo, se a classe controller (controlador) for PostController
, o diretório
será @app/views/post
; se for PostCommentController
, o diretório será
@app/views/post-comment
. No caso do controller (controlador) pertencer a um
módulo, o diretório será views/ControllerID
sob o diretório do módulo.WidgetPath/views
por padrão, onde WidgetPath
é o diretório onde encontra-se o arquivo da classe widget.Você pode personalizar estes diretórios padrão das views (visões) sobrescrevendo o método yii\base\ViewContextInterface::getViewPath() dos controllers (controladores) ou dos widgets.
A renderização das views (visões) podem ser feitas nos controllers (controladores), nos widgets ou em qualquer lugar que chame os métodos de renderização de views (visões),
/**
* @param string $view nome da view ou do caminho do arquivo, dependendo do método de renderização atual
* @param array $params os dados que serão passados para a view (visão)
* @return string resultado da renderização
*/
methodName($view, $params = [])
Nos controllers (controladores), você pode chamar os seguintes métodos para renderizar as views (visões):
Por exemplo,
namespace app\controllers;
use Yii;
use app\models\Post;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
class PostController extends Controller
{
public function actionView($id)
{
$model = Post::findOne($id);
if ($model === null) {
throw new NotFoundHttpException;
}
// renderiza uma view chamada de "view" e aplica um layout nele
return $this->render('view', [
'model' => $model,
]);
}
}
Nos widgets, você pode chamar os seguintes métodos do widget para renderizar views (visões).
Por exemplo,
namespace app\components;
use yii\base\Widget;
use yii\helpers\Html;
class ListWidget extends Widget
{
public $items = [];
public function run()
{
// renderiza uma view chamada "list"
return $this->render('list', [
'items' => $this->items,
]);
}
}
Você pode renderizar uma view dentro de outra view chamando um dos seguintes métodos fornecidos pelo componente da view:
Por exemplo, no código a seguir, uma view (visão) qualquer renderiza outro arquivo
de view (visão) chamado _overview.php
onde ambas encontram-se no mesmo diretório.
Lembre-se que a $this
da view (visão) refere-se ao componente da view:
<?= $this->render('_overview') ?>
Em qualquer lugar, você pode acessar o componente de aplicação view
pela expressão Yii::$app->view
e chamar qualquer método mencionado anteriormente
para renderizar uma view (visão). Por exemplo,
// exibe o arquivo de view (visão) "@app/views/site/license.php"
echo \Yii::$app->view->renderFile('@app/views/site/license.php');
Ao renderizar uma view (visão), você pode especificar a view usando um nome ou o caminho do arquivo/alias. Na maioria dos casos, você usará a primeira maneira, pois são mais concisos e flexíveis. Especificamente, chamaremos as views usando nomes como views (visões) nomeadas.
Um nome da view (visão) resolve o caminho da view (visão) correspondente de acordo com as seguintes regras:
.php
será usado como extensão. Por exemplo, a view chamada about
corresponderá ao
arquivo about.php
.//
, o caminho correspondente
será @app/views/ViewName
. Ou seja, a view (visão) será localizada sob o
diretório das views da aplicação. Por exemplo,
//site/about
corresponderá ao @app/views/site/about.php
./
, o caminho do arquivo da view
será formado pelo nome da view (visão) com o diretório da view
do módulo ativo. Se não existir um módulo ativo, o
@app/views/ViewName
será usado. Por exemplo, o /user/create
corresponderá
ao @app/modules/user/views/user/create.php
, caso o módulo ativo seja user
.
Se não existir um módulo ativo, o caminho do arquivo da view (visão) será
@app/views/user/create.php
.about
corresponderá ao
@app/views/site/about.php
caso o contexto seja o controller (controlador)
SiteController
.item
corresponderá ao @app/views/post/item.php
se ela for
renderizada pela view @app/views/post/index.php
.De acordo com as regras acima, ao chamar $this->render('view')
em um controller
(controlador) app\controllers\PostController
será renderizado o arquivo de view
(visão) @app/views/post/view.php
e, ao chamar $this->render('_overview')
nesta
view, será renderizado o arquivo de visão @app/views/post/_overview.php
.
Existem duas abordagens para acessar dados em um view (visão): push e pull.
Ao passar os dados como o segundo parâmetro nos métodos de renderização de view
(visão), você estará usando a abordagem push.
Os dados devem ser representados por um array com pares de nome-valor. Quando a
view (visão) estiver sendo renderizada, a função extract()
do PHP será chamado
passando este array a fim de extraí-los em variáveis na view (visão).
Por exemplo, o código do controller (controlador) a seguir fornecerá (pela
abordagem push) duas variáveis para a view (visão) report
: $foo = 1
e $bar = 2
.
echo $this->render('report', [
'foo' => 1,
'bar' => 2,
]);
Na abordagem pull, os dados serão recuperados ativamente pelo
componente da view ou por outros objetos que acessam as views
(por exemplo, Yii::$app
). Usando o código do exemplo a seguir, você poderá
acessar o objeto do controller (controlador) pela expressão $this->context
dentro da view. E como resultado, será possível acessar qualquer propriedade ou
métodos do controller (controlador) na view (visão) report
, como o ID do
controller conforme o exemplo a seguir:
The controller ID is: <?= $this->context->id ?>
?>
A abordagem push normalmente é a forma preferida de acessar dados nas views (visões), pelo fato de criar menos dependências nos objetos de contexto. A desvantagem é que você precisará montar manualmente os dados em um array o tempo todo, o que poderia tornar-se tedioso e propenso a erros se uma view for compartilhada e renderizada em lugares diferentes.
O componente da view fornece a propriedade params que você pode usar para compartilhar dados entre as views (visões).
Por exemplo, em uma view about
, você pode ter o seguinte código para especificar
o seguimento atual do rastro da aplicação (breadcrumbs).
$this->params['breadcrumbs'][] = 'About Us';
Em seguida, no arquivo do layout, que também é uma view, você pode exibir o rastro da aplicação (breadcrumbs) usando os dados passados pela propriedade params:
<?= yii\widgets\Breadcrumbs::widget([
'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [],
]) ?>
Os layouts são um tipo especial de views (visões) que representam as partes comuns das views (visões). Por exemplo, a maioria das páginas de aplicações Web compartilham o mesmo cabeçalho e rodapé. Embora você possa repetir o mesmo cabeçalho e rodapé em todas as view, a melhor maneira é fazer isso apenas uma vez no layout e incorporar o resultado da renderização de uma view em um lugar apropriado no layout.
Pelo fato dos layouts também serem views (visões), eles podem ser criados de
forma semelhante as views (visões) normais. Por padrão, os layouts são guardados
no diretório @app/views/layouts
. Para os layouts usados nos
módulos, devem ser guardados no diretório views/layouts
sob o diretório do módulo.
Você pode personalizar o diretório do layout padrão configurando a propriedade
yii\base\Module::$layoutPath da aplicação ou do módulo.
O exemplo a seguir mostra como é o layout. Observe que, para fins ilustrativos, simplificamos o código do layout. Em prática, você pode adicionar mais conteúdo, como tags de cabeçalho, menu principal, etc.
<?php
use yii\helpers\Html;
/* @var $this yii\web\View */
/* @var $content string */
?>
<?php $this->beginPage() ?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<?= Html::csrfMetaTags() ?>
<title><?= Html::encode($this->title) ?></title>
<?php $this->head() ?>
</head>
<body>
<?php $this->beginBody() ?>
<header>My Company</header>
<?= $content ?>
<footer>© 2014 by My Company</footer>
<?php $this->endBody() ?>
</body>
</html>
<?php $this->endPage() ?>
Como pode ver, o layout gera as tags HTML que são comuns em todas as páginas. Na
seçao <body>
, o layout dará echo da variável $content
que representa o
resultado da renderização do conteúdo das views (visões) e é incorporado ao layout
quando método yii\base\Controller::render() for chamado.
Como mostrado no código acima, a maioria dos layouts devem chamar os métodos listados a seguir. Estes métodos podem desencadeiam eventos referentes ao processo de renderização para que scripts e tags registrados em outros lugares possam ser inseridos nos locais onde estes métodos forem chamados.
<head>
de uma página HTML. Ele reserva este local para gerar os códigos HTML do
cabeçalho que foram registrados (por exemplo, link e meta tags) quando uma
página finaliza a renderização.<body>
. Ele dispara o evento EVENT_BEGIN_BODY
e reserva este local para gerar os códigos HTML (por exemplo, JavaScript)
voltados para a posição inicial do corpo do layout que foram registrados.<body>
. Ele dispara o evento EVENT_END_BODY
e reserva este local para gerar códigos HTML (por exemplo, JavaScript) voltados
para a posição final do corpo do layout que foram registrados.Dentro de um layout, você tem acesso a duas variáveis predefinidas: $this
e
$content
. A primeira refere-se ao componente da view como as
views normais, enquanto o segundo contém o resultado da renderização do conteúdo
de uma view que é gerada pela execução do método render()
no controller (controlador).
Se você quiser acessar outros dados nos layouts, você terá que usar a abordagem pull conforme descrito na subseção Acessando Dados em Views (Visões). Se você quiser passar os dados de um conteúdo da view em um layout, poderá usar o método descrito na subseção Compartilhando Dados entre as Views (Visões).
Como descrito na subseção Renderização nos Controllers (Controladores),
quando você renderizar uma view (visão) chamando o método render()
em um controller (controlador), o resultado da renderização será aplicado em um layout.
Por padrão, o layout @app/views/layouts/main.php
será usado.
Você pode usar um layout diferente configurando a propriedade
yii\base\Application::$layout ou yii\base\Controller::$layout.
A primeira aplica o layout em todos os controllers (controladores) usados,
enquanto o segundo sobrescreve a primeira forma pelos controllers (controladores)
de forma individual.
Por exemplo, o código a seguir faz com que o controller post
use o
@app/views/layouts/post.php
como layout quando renderizar as suas views (visões).
Os outros controllers (controladores), assumindo que a propriedade layout
da
aplicação não foi alterada, usará como padrão o layout @app/views/layouts/main.php
.
namespace app\controllers;
use yii\web\Controller;
class PostController extends Controller
{
public $layout = 'post';
// ...
}
Para os controllers (controladores) que pertencem a um módulo, você pode configurar a propriedade layout do módulo para usar um layout em particular para estes controllers.
Devido a propriedade layout
possa ser configurado em diferentes níveis
(controllers, módulos, aplicação), por baixo dos panos o Yii determina em duas
etapas qual é o arquivo de layout que será usado por um controller (controlador)
em particular.
Na primeira etapa, o Yii determina o nome do layout e o módulo de contexto:
Na segunda etapa, ele determina o arquivo do layout de acordo com o valor do layout e o modulo de contexto obtidos na primeira etapa. O nome do layout pode ter:
@app/views/layouts/main
)./main
): o nome do layout que começa com uma
barra. O arquivo do layout será procurado sob o
diretório do layout da aplicação, na qual
o valor padrão é @app/views/layouts
.main
): o arquivo do layout será procurado
sob o diretório do layout do módulo de contexto,
na qual o valor padrão é views/layouts
sob o diretório do módulo.false
: nenhum layout será aplicado.Caso o nome do layout não tiver uma extensão de arquivo, será usado um .php
por padrão.
Algumas vezes, você pode querer que um layout seja usado dentro de outro. Por exemplo, você pode querer usar diferentes layouts para cada seção de um página Web, onde todos estes layouts compartilharão o mesmo layout básico a fim de gerar toda a estrutura de uma página HTML5. Este objetivo pode ser alcançado chamando os métodos beginContent() e endContent() nos layouts filhos, como mostro no exemplo a seguir:
<?php $this->beginContent('@app/views/layouts/base.php'); ?>
...conteúdo do layout filho...
<?php $this->endContent(); ?>
Como mostrado no exemplo acima, o conteúdo do layout filho deve ser envolvido pelos métodos beginContent() e endContent(). O parâmetro passado no beginContent() indica qual é o layout pai. Ele pode ser tanto um arquivo do layout quanto uma alias.
Usando a abordagem mencionada, poderá aninhar os layouts em mais de um nível.
Os blocos lhe permitem especificar o conteúdo da view (visão) de um local e exibi-lo em outro. Geralmente são usados em conjunto com os layouts. Por exemplo, você pode definir um bloco no conteúdo de uma view (visão) e exibi-lo no layout.
Para definir um bloco, deverá chamar os métodos beginBlock()
e endBlock().
O bloco pode ser acessado via $view->blocks[$blockID]
, onde o $blockID
é o
identificador único que você associou ao bloco quando o definiu.
O exemplo a seguir mostra como você pode usar blocos para personalizar as partes especificas de um layout pelo conteúdo da view (visão).
Primeiramente, no conteúdo da view (visão), defina um ou vários blocos:
...
<?php $this->beginBlock('block1'); ?>
...conteúdo do block1...
<?php $this->endBlock(); ?>
...
<?php $this->beginBlock('block3'); ?>
... conteúdo do block3...
<?php $this->endBlock(); ?>
Em seguida, na view (visão) do layout, aplique os blocos se estiverem disponíveis ou caso não esteja disponível exiba um conteúdo padrão.
...
<?php if (isset($this->blocks['block1'])): ?>
<?= $this->blocks['block1'] ?>
<?php else: ?>
... conteúdo padrão para o block1 ...
<?php endif; ?>
...
<?php if (isset($this->blocks['block2'])): ?>
<?= $this->blocks['block2'] ?>
<?php else: ?>
... conteúdo padrão para o block2 ...
<?php endif; ?>
...
<?php if (isset($this->blocks['block3'])): ?>
<?= $this->blocks['block3'] ?>
<?php else: ?>
... conteúdo padrão para o block3 ...
<?php endif; ?>
...
Os componentes de view (visão) fornecem muitos recursos
relacionados às views (visões). Enquanto você pode obter os componentes de view
(visão) através da criação de instancias individuais da classe yii\base\View
ou de suas classes filhas, na maioria dos casos você simplesmente usará o
componente da aplicação view
. Você pode configurar estes componentes nas
configurações da aplicação
conforme o exemplo a seguir:
[
// ...
'components' => [
'view' => [
'class' => 'app\components\View',
],
// ...
],
]
A seguir, os recursos úteis relacionados às views (visões) que os componentes de view (visão) fornecem. Cada um dos recursos são descritos com mais detalhes em seções separadas:
Você também pode usar com frequência os seguintes recursos menos úteis quando estiver desenvolvendo suas páginas.
Cada página deve ter um título. Normalmente, a tag do título é colocada no início de um layout. Mas na prática, o título é muitas vezes determinado pelo conteúdo das views (visões) do que pelos os layouts. Para resolver este problema, a classe yii\web\View fornece a propriedade title para você informar o título pelas view (visões) para os layouts.
Para fazer uso deste recurso, em cada view (visão), você pode definir o título da página conforme o exemplo a seguir:
<?php
$this->title = 'My page title';
?>
E no layout, verifique se você tem o seguinte código sob o elemento <head>
:
<title><?= Html::encode($this->title) ?></title>
As páginas Web geralmente precisam gerar vários meta tags necessários para
diferentes fins. Assim como os títulos, os meta tags precisam estar na seção
<head>
e normalmente são criados nos layouts.
Se você quiser especificar quais meta tags precisam ser criados no conteúdo de uma view (visão), poderá chamar o método yii\web\View::registerMetaTag() no conteúdo da view, conforme o exemplo a seguir:
<?php
$this->registerMetaTag(['name' => 'keywords', 'content' => 'yii, framework, php']);
?>
O código acima registrará um meta tag "keywords" com o componente da view (visão). O meta tag registrado será processado antes que o layout finalize sua renderização. O código do HTML a seguir será criado no lugar da chamada yii\web\View::head() no layout:
<meta name="keywords" content="yii, framework, php">
Observe que ao chamar o método yii\web\View::registerMetaTag() muitas vezes, registrará diversas meta tags, independente se forem as mesmas meta tags ou não.
Para garantir que existirá apenas uma única instância de um tipo de meta tag, você pode especificar uma chave no segundo parâmetro ao chamar o método. Por exemplo, o código a seguir registra dois meta tags "description". No entanto, apenas o segundo será processado.
$this->registerMetaTag(['name' => 'description', 'content' => 'This is my cool website made with Yii!'], 'description');
$this->registerMetaTag(['name' => 'description', 'content' => 'This website is about funny raccoons.'], 'description');
Assim como os meta tags, as tags link são úteis em muitos casos, tais como a personalização do favicon, apontamento de feed RSS ou delegar o OpenID para outros servidores. Você pode trabalhar com as tags link de forma similar aos meta tags, usando o método yii\web\View::registerLinkTag(). Por exemplo, no conteúdo da view (visão), você pode registrar uma tag link conforme o seguinte exemplo,
$this->registerLinkTag([
'title' => 'Live News for Yii',
'rel' => 'alternate',
'type' => 'application/rss+xml',
'href' => 'http://www.yiiframework.com/rss.xml/',
]);
O código acima resultará em
<link title="Live News for Yii" rel="alternate" type="application/rss+xml" href="http://www.yiiframework.com/rss.xml/">
Semelhante ao método registerMetaTags(), você pode especificar uma chave quando chamar o método registerLinkTag() para evitar a criação de tags link repetidas.
Os componentes de view (visão) disparam vários eventos durante o processo de renderização da view (visão). Você pode usar estes eventos para inserir conteúdos nas views (visões) ou processar os resultados da renderização antes de serem enviados para os usuários finais.
false
para
cancelar o processo de renderização.Por exemplo, o código a seguir insere a data atual no final do corpo da página:
\Yii::$app->view->on(View::EVENT_END_BODY, function () {
echo date('Y-m-d');
});
Páginas estáticas referem-se a páginas cujo principal conteúdo é na maior parte estática, sem a necessidade de acessar conteúdos dinâmicos pelos controllers (controladores).
Você pode produzir páginas estáticas referenciando uma view (visão) no controller (controlador) conforme o código a seguir:
public function actionAbout()
{
return $this->render('about');
}
Se o site contiver muitas páginas estáticas, seria um desperdício de tempo repetir os códigos semelhantes muitas vezes. Para resolver este problema, poderá introduzir uma ação standalone chamando a classe yii\web\ViewAction em um controller (controlador). Por exemplo,
namespace app\controllers;
use yii\web\Controller;
class SiteController extends Controller
{
public function actions()
{
return [
'page' => [
'class' => 'yii\web\ViewAction',
],
];
}
}
Agora, se você criar uma view (visão) chamada about
sob o diretório
@app/views/site/pages
, será capaz de exibir esta view (visão) conforme a
seguinte URL:
http://localhost/index.php?r=site/page&view=about
O parâmetro view
passado via GET
informa a classe yii\web\ViewAction
qual view (visão) será solicitada. A ação, então, irá procurar a view (visão)
sob o diretório @app/views/site/pages
. Você pode configurar a propriedade
yii\web\ViewAction::$viewPrefix para alterar o diretório onde as views (visões)
serão procuradas.
As views (visões) são os responsáveis por apresentar modelos no formato que os usuários finais desejarem. Em geral, as view (visões):
$_GET
e
o $_POST
. Esta responsabilidade deve pertencer aos controllers (controladores).
Se os dados da requisição forem necessários, deverão ser fornecidas as views (visões)
pelos controllers (controladores).Para views (visões) mais gerenciáveis, evite criar views (visões) muito complexas ou que contenham muitos códigos redundantes. Você pode usar as seguintes técnicas para atingir estes objetivos:
Found a typo or you think this page needs improvement?
Edit it on github !
Signup or Login in order to comment.