diff --git a/docs/guide-pt-BR/README.md b/docs/guide-pt-BR/README.md index c3b578b..05989a9 100644 --- a/docs/guide-pt-BR/README.md +++ b/docs/guide-pt-BR/README.md @@ -112,7 +112,7 @@ Segurança * [Autorização](security-authorization.md) * [Trabalhando com Senhas](security-passwords.md) * **TBD** [Auth Clients](security-auth-clients.md) -* **TBD** [Melhores Práticas](security-best-practices.md) +* [Melhores Práticas](security-best-practices.md) Cache diff --git a/docs/guide-pt-BR/start-looking-ahead.md b/docs/guide-pt-BR/start-looking-ahead.md index 9de82f2..19740e8 100644 --- a/docs/guide-pt-BR/start-looking-ahead.md +++ b/docs/guide-pt-BR/start-looking-ahead.md @@ -43,3 +43,4 @@ usando o framework. - Facebook: <https://www.facebook.com/groups/yiitalk/> - Twitter: <https://twitter.com/yiiframework> - LinkedIn: <https://www.linkedin.com/groups/yii-framework-1483367> + - Stackoverflow: <http://stackoverflow.com/questions/tagged/yii2> \ No newline at end of file diff --git a/docs/guide-pt-BR/structure-views.md b/docs/guide-pt-BR/structure-views.md new file mode 100644 index 0000000..d2dd099 --- /dev/null +++ b/docs/guide-pt-BR/structure-views.md @@ -0,0 +1,867 @@ +Views (Visões) +=========== + +As views (visões) fazem parte da arquitetura [MVC](http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller). +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](structure-application-components.md) +[[yii\web\View|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). + + +## Criando Views (Visões) <a name="creating-views"></a> + +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 +<?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 +[[yii\web\View|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)](structure-controllers.md) ou de outros objetos que +desencadeiam a [renderização da view (visão)](#rendering-views). + +> 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). + + +### Segurança <a name="security"></a> + +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](http://en.wikipedia.org/wiki/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 +<?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 +<?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](caching-overview.md) + do resultado filtrado caso sua aplicação necessite de o máximo de performance. + + +### Organizando as Views (Visões) <a name="organizing-views"></a> + +Assim como os [controllers (controladores)](structure-controllers.md) e os +[models (modelos)](structure-models.md), existem convenções para organizar as +views (visões). + +* Para que as views (visões) sejam renderizadas por um controller (controlador), + elas devem ser colocadas sob o diretório `@app/views/IDdoController` por padrão, + onde o `IDdoController` refere-se ao [ID do controller](structure-controllers.md#routes). + 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 [[yii\base\Module::basePath|diretório do módulo]]. +* Para as views (visões) que serão renderizadas por um [widget](structure-widgets.md), + devem ser colocadas sob o diretório `WidgetPath/views` por padrão, onde `WidgetPath` + é o diretório onde encontra-se o arquivo da classe widget. +* Para as views (visões) que serão renderizadas por outros objetos, é recomendado + que siga a convenção semelhante à dos widgets. + +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. + + +## Renderizando Views (Visões) <a name="rendering-views"></a> + +A renderização das views (visões) podem ser feitas nos +[controllers (controladores)](structure-controllers.md), nos +[widgets](structure-widgets.md) 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 = []) +``` + + +### Renderização pelos Controllers (Controladores) <a name="rendering-in-controllers"></a> + +Nos [controllers (controladores)](structure-controllers.md), você pode chamar os +seguintes métodos para renderizar as views (visões): + +* [[yii\base\Controller::render()|render()]]: resulta na renderização de uma + [view nomeada](#named-views) aplicada em um [layout](#layouts). +* [[yii\base\Controller::renderPartial()|renderPartial()]]: resulta na renderização + de uma [view nomeada](#named-views) sem que seja aplicada em qualquer layout. +* [[yii\web\Controller::renderAjax()|renderAjax()]]: resulta na renderização de + uma [view nomeada](#named-views) sem que seja aplicada em qualquer layout mas + inclui todos os JS/CSS e arquivos registrados. Este método é utilizado + frequentemente nas respostas de requisições Web Ajax. +* [[yii\base\Controller::renderFile()|renderFile()]]: renderiza uma view a partir + de um caminho de um arquivo ou por uma [alias](concept-aliases.md). +* [[yii\base\Controller::renderContent()|renderContent()]]: renderiza um conteúdo + estático que será incorporado no [layout](#layouts) selecionado. Este método + está disponível desde a versão 2.0.1. + +Por exemplo, + +```php +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, + ]); + } +} +``` + + +### Renderização pelos Widgets <a name="rendering-in-widgets"></a> + +Nos [widgets](structure-widgets.md), você pode chamar os seguintes métodos do +widget para renderizar views (visões). + +* [[yii\base\Widget::render()|render()]]: resulta na renderização de uma + [view nomeada](#named-views). +* [[yii\base\Widget::renderFile()|renderFile()]]: renderiza uma view a partir de + um caminho de um arquivo ou por uma [alias](concept-aliases.md). + +Por exemplo, + +```php +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, + ]); + } +} +``` + + +### Renderização pelas Views (Visões) <a name="rendering-in-views"></a> + +Você pode renderizar uma view dentro de outra view chamando um dos seguintes +métodos fornecidos pelo [[yii\base\View|componente da view]]: + +* [[yii\base\View::render()|render()]]: resulta na renderização de uma + [view nomeada](#named-views). +* [[yii\web\View::renderAjax()|renderAjax()]]: resulta na renderização de uma + [view nomeada](#named-views) e inclui todos os JS/CSS e arquivos registrados. + Este método é utilizado frequentemente nas respostas de requisições Web Ajax. +* [[yii\base\View::renderFile()|renderFile()]]: renderiza uma view a partir de + um caminho de um arquivo ou por uma [alias](concept-aliases.md). + +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 [[yii\base\View|view]]: + +```php +<?= $this->render('_overview') ?> +``` + + +### Renderização por Outros Lugares <a name="rendering-in-other-places"></a> + +Em qualquer lugar, você pode acessar o componente de aplicação [[yii\base\View|view]] +pela expressão `Yii::$app->view` e chamar qualquer método mencionado anteriormente +para renderizar uma view (visão). Por exemplo, + +```php +// exibe o arquivo de view (visão) "@app/views/site/license.php" +echo \Yii::$app->view->renderFile('@app/views/site/license.php'); +``` + + +### Views (Visões) Nomeadas <a name="named-views"></a> + +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: + +* Um nome da view (visão) pode omitir a extensão do arquivo. Neste caso, o `.php` + será usado como extensão. Por exemplo, a view chamada `about` corresponderá ao + arquivo `about.php`. +* Se o nome da view (visão) iniciar com barras duplas `//`, o caminho correspondente + será `@app/views/ViewName`. Ou seja, a view (visão) será localizada sob o + [[yii\base\Application::viewPath|diretório das views da aplicação]]. Por exemplo, + `//site/about` corresponderá ao `@app/views/site/about.php`. +* Se o nome da view (visão) iniciar com barra `/`, o caminho do arquivo da view + será formado pelo nome da view (visão) com o [[yii\base\Module::viewPath|diretório da view]] + do [módulo](structure-modules.md) 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`. +* Se a view (visão) for renderizada com um [[yii\base\View::context|contexto]] e + que o mesmo implemente [[yii\base\ViewContextInterface]], o caminho do arquivo + da view será formado pelo nome da view (visão) com o + [[yii\base\ViewContextInterface::getViewPath()|diretório da view]] do contexto. + Isto se aplica principalmente para as views (visões) renderizadas pelos controllers + (controladores) e widgets. Por exemplo, `site/about` corresponderá ao + `@app/views/site/about.php` caso o contexto seja o controller (controlador) + `SiteController`. +* Se uma view (visão) for renderizada por outra view (visão), o diretório desta + outra view (visão) será usado para formar o caminho do arquivo da view atual. + Por exemplo, `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`. + + +### Acessando Dados em Views (Visões) <a name="accessing-data-in-views"></a> + +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`. + +```php +echo $this->render('report', [ + 'foo' => 1, + 'bar' => 2, +]); +``` + +Na abordagem *pull*, os dados serão recuperados ativamente pelo +[[yii\base\View|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: + +```php +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. + + +### Compartilhando Dados entre as Views (Visões) <a name="sharing-data-among-views"></a> + +O [[yii\base\View|componente da view]] fornece a propriedade +[[yii\base\View::params|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). + +```php +$this->params['breadcrumbs'][] = 'About Us'; +``` + +Em seguida, no arquivo do [layout](#layouts), que também é uma view, você pode +exibir o rastro da aplicação (breadcrumbs) usando os dados passados pela +propriedade [[yii\base\View::params|params]]: + +```php +<?= yii\widgets\Breadcrumbs::widget([ + 'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [], +]) ?> +``` + + +## Layouts <a name="layouts"></a> + +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. + + +### Criando Layouts <a name="creating-layouts"></a> + +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](structure-modules.md), devem ser guardados no diretório `views/layouts` +sob o [[yii\base\Module::basePath|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 +<?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. + +- [[yii\base\View::beginPage()|beginPage()]]: Este método deve ser chamado no início + do layout. Ele dispara o evento [[yii\base\View::EVENT_BEGIN_PAGE|EVENT_BEGIN_PAGE]] + que indica o início de uma página. +- [[yii\base\View::endPage()|endPage()]]: Este método deve ser chamado no final + do layout. Ele dispara o evento [[yii\base\View::EVENT_END_PAGE|EVENT_END_PAGE]] + que indica o fim de uma página. +- [[yii\web\View::head()|head()]]: Este método deve ser chamada na seção `<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. +- [[yii\web\View::beginBody()|beginBody()]]: Este método deve ser chamado no início + da seção `<body>` . Ele dispara o evento [[yii\web\View::EVENT_BEGIN_BODY|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. +- [[yii\web\View::endBody()|endBody()]]: Este método deve ser chamado no final da + seção `<body>`. Ele dispara o evento [[yii\web\View::EVENT_END_BODY|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. + + +### Acessando Dados nos Layouts <a name="accessing-data-in-layouts"></a> + +Dentro de um layout, você tem acesso a duas variáveis predefinidas: `$this` e +`$content`. A primeira refere-se ao componente da [[yii\base\View|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 [[yii\base\Controller::render()|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)](#accessing-data-in-views). 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)](#sharing-data-among-views). + + +### Usando Layouts <a name="using-layouts"></a> + +Como descrito na subseção [Renderização nos Controllers (Controladores)](#rendering-in-controllers), +quando você renderizar uma view (visão) chamando o método [[yii\base\Controller::render()|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`. + +```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 [[yii\base\Module::layout|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: + +- Se a propriedade [[yii\base\Controller::layout]] do controller (controlador) + não for nula, será usado como o nome do layout e o [[yii\base\Controller::module|módulo]] + do controller (controlador) como módulo de contexto. +- Se a propriedade [[yii\base\Controller::layout|layout]] for nula, será buscado + através de todos os módulos ancestrais (incluindo a própria aplicação) do + controller (controlador) até encontrar o primeiro módulo que a propriedade + [[yii\base\Module::layout|layout]] não esteja nula. Este módulo encontrado será + usado como o módulo de contexto e o valor de sua propriedade [[yii\base\Module::layout|layout]] + como o nome do layout. Se um módulo não for encontrado, significará que nenhum + layout será aplicado. + +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: + +- uma alias de caminho (por exemplo, `@app/views/layouts/main`). +- um caminho absoluto (por exemplo, `/main`): o nome do layout que começa com uma + barra. O arquivo do layout será procurado sob o + [[yii\base\Application::layoutPath|diretório do layout]] da aplicação, na qual + o valor padrão é `@app/views/layouts`. +- um caminho relativo (por exemplo, `main`): o arquivo do layout será procurado + sob o [[yii\base\Module::layoutPath|diretório do layout]] do módulo de contexto, + na qual o valor padrão é `views/layouts` sob o [[yii\base\Module::basePath|diretório do módulo]]. +- um valor booleano `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. + + +### Layouts Aninhados <a name="nested-layouts"></a> + +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 [[yii\base\View::beginContent()|beginContent()]] e +[[yii\base\View::endContent()|endContent()]] nos layouts filhos, como mostro no +exemplo a seguir: + +```php +<?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 [[yii\base\View::beginContent()|beginContent()]] e +[[yii\base\View::endContent()|endContent()]]. O parâmetro passado no +[[yii\base\View::beginContent()|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. + + +### Usando Blocos <a name="using-blocks"></a> + +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 [[yii\base\View::beginBlock()|beginBlock()]] +e [[yii\base\View::endBlock()|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 +... + +<?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 +... +<?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; ?> +... +``` + + +## Usando Componentes de View (Visão) <a name="using-view-components"></a> + +Os [[yii\base\View|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](structure-applications.md#application-configurations) +conforme o exemplo a seguir: + +```php +[ + // ... + '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: + +* [temas](output-theming.md): permite que você desenvolva e altere um tema para + o seu site. +* [cache de fragmento](caching-fragment.md): permite que guarde o cache de um + fragmento de uma página. +* [manipulando client scripts](output-client-scripts.md): suporta o registro e a + renderização de CSS e JavaScript. +* [manipulando asset bundle](structure-assets.md): suporta o registro e renderização + de [asset bundles](structure-assets.md). +* [motores de templates alternativos](tutorial-template-engines.md): permite que + você use outro motor de template, tais como o [Twig](http://twig.sensiolabs.org/) + e o [Smarty](http://www.smarty.net/). + +Você também pode usar com frequência os seguintes recursos menos úteis quando +estiver desenvolvendo suas páginas. + + +### Configuração do Título da Página <a name="setting-page-titles"></a> + +Cada página deve ter um título. Normalmente, a tag do título é colocada no início +de um [layout](#layouts). 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 [[yii\web\View::title|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 +<?php +$this->title = 'My page title'; +?> +``` + +E no layout, verifique se você tem o seguinte código sob o elemento `<head>`: + +```php +<title><?= Html::encode($this->title) ?></title> +``` + + +### Registrando os Meta Tags <a name="registering-meta-tags"></a> + +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 +<?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: + +```php +<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. + +```html +$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'); +``` + + +### Registrando as Tags Link <a name="registering-link-tags"></a> + +Assim como os [meta tags](#registering-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, + +```php +$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 + +```html +<link title="Live News for Yii" rel="alternate" type="application/rss+xml" href="http://www.yiiframework.com/rss.xml/"> +``` + +Semelhante ao método [[yii\web\View::registerMetaTag()|registerMetaTags()]], +você pode especificar uma chave quando chamar o método +[[yii\web\View::registerLinkTag()|registerLinkTag()]] para evitar a criação de +tags link repetidas. + + +## Eventos da View (Visão) <a name="view-events"></a> + +[[yii\base\View|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. + +- [[yii\base\View::EVENT_BEFORE_RENDER|EVENT_BEFORE_RENDER]]: é disparado no + início da renderização de um arquivo no controlador. Na função deste evento + pode definir a propriedade [[yii\base\ViewEvent::isValid]] como false para + cancelar o processo de renderização. +- [[yii\base\View::EVENT_AFTER_RENDER|EVENT_AFTER_RENDER]]: é disparado depois + da renderização de um arquivo pela chamada do método [[yii\base\View::afterRender()]]. + Na função deste evento pode obter o resultado da renderização por meio da propriedade + [[yii\base\ViewEvent::output]] podendo modifica-lo para alterar o resultado da + renderização. +- [[yii\base\View::EVENT_BEGIN_PAGE|EVENT_BEGIN_PAGE]]: é disparado pela chamada + do método [[yii\base\View::beginPage()]] nos layouts. +- [[yii\base\View::EVENT_END_PAGE|EVENT_END_PAGE]]: é disparado pela chamada do + método [[yii\base\View::endPage()]] nos layouts. +- [[yii\web\View::EVENT_BEGIN_BODY|EVENT_BEGIN_BODY]]: é disparado pela chamada + do método [[yii\web\View::beginBody()]] nos layouts. +- [[yii\web\View::EVENT_END_BODY|EVENT_END_BODY]]: é disparado pela chamada do + método [[yii\web\View::endBody()]] nos layouts. + +Por exemplo, o código a seguir insere a data atual no final do corpo da página: + +```php +\Yii::$app->view->on(View::EVENT_END_BODY, function () { + echo date('Y-m-d'); +}); +``` + + +## Renderizando Páginas Estáticas <a name="rendering-static-pages"></a> + +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: + +```php +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](structure-controllers.md#standalone-actions) chamando a classe +[[yii\web\ViewAction]] em um controller (controlador). Por exemplo, + +```php +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. + + +## Boas Práticas <a name="best-practices"></a> + +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): + +* devem conter principalmente códigos de apresentação, tais como o HTML e códigos + simples de PHP para formatação, renderização e transferência de dados. +* não devem conter códigos que realiza consultas no banco de dados. Esta + responsabilidade pertence aos models (modelos). +* devem evitar ter acesso direto aos dados de requisição, tais como o `$_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). +* poderão ler as propriedades dos models (modelos), mas não podem alterá-las. + +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: + +* use os [layouts](#layouts) para representar as seções de apresentação comuns + (por exemplo, cabeçalho e o rodapé). +* divida uma view (visão) complicada em varias outras menores. As views (visões) + menores podem ser renderizadas e montadas em um maior usando os métodos que + descrevemos anteriormente. +* crie e use [widgets](structure-widgets.md) como blocos de construção das views + (visões). +* crie e use as classes helpers para transformar e formatar os dados nas views + (visões). diff --git a/docs/internals/design-decisions.md b/docs/internals/design-decisions.md index f3910d1..c767e58 100644 --- a/docs/internals/design-decisions.md +++ b/docs/internals/design-decisions.md @@ -12,3 +12,6 @@ the core developers. messages should be translated when these are displayed to non-tech end user and make sense to him. HTTP status messages, exceptions about the code etc. should not be translated. Console messages are always in English because of encoding and codepage handling difficulties. +3. **[Adding new auth client support](https://github.com/yiisoft/yii2/issues/1652)** + For better maintenability, we will not add any additional auth clients to the core extension. They should be done + in terms of user extensions.