Layouts

Os layouts fazem parte da camada de view da sua aplicação. Geralmente compõem toda a parte apresentacional que envolve uma view. É nos layouts onde você inclui as partes fixas da apresentação de sua aplicação, geralmente sua marca, os menus de navegação, rodapé, entre outros.

Os layouts possuem um comportamento bastante semelhante ao das outras views: são arquivos HTML com pouca ou nenhuma lógica PHP embutida, geralmente apenas estruturas simples de PHP, como laços de repetição, assim como nas views. Contudo, eles não estão vinculados a um controller assim como as views, pois são compartilhados entre boa parte de sua apliação.

O arquivo de layout padrão da sua aplicação Spaghetti* é o arquivo /app/layouts/default.htm.php, mas você pode criar quantos layouts diferentes você achar necessário, e dar o nome que você quiser a eles.

Recebendo o conteúdo de uma view

Você pode sobrescrever o layout padrão, montado uma estrutura de HTML simples, como a mostrada abaixo.

<html>
<head>
     <title>My Page</title>
</head>
<body>
     <h1>Welcome to My Page</h1>
</body>
</html>

No exemplo acima, você terá uma página apenas com um cabeçalho “Welcome to My Page”. Não importa se você está acessando uma view que possui conteúdo, o layout acima apenas mostrará o código que você digitou. É necessário injetar o conteúdo de uma view no layout para que esse possa ser mostrado. Para isso, você precisa imprimir a variável de instância View::$contentForLayout, que contém tudo o que foi gerado por suas views na página em questão.

<html>
<head>
     <title>My Page</title>
</head>
<body>
     <h1>Welcome to My Page</h1>
     <?php echo $this->contentForLayout ?>
</body>
</html>

No exemplo acima, portanto, além do cabeçalho “Welcome to My Page”, o conteúdo da view solicitada será impresso logo em seguida.

Criando layouts e escolhendo qual utilizar

Se você possuir uma página de login em seu sistema, provavelmente optará por escrever um layout próprio para esta página, livre dos elementos de navegação presentes em todo o restante do sistema. Para tal, você precisa criar um novo layout na pasta /app/layouts/ com o nome do arquivo que você desejar.

Então, você precisa alterar o controller onde deseja trocar o layout a ser mostrado, e definir a variável Controller::$layout, como já explicado.

public $layout = "login";

Com o exemplo acima, quando alguma action do controller onde a variável Controller::$layout foi definida for chamada, o Spaghetti* procurará pelo arquivo /app/layouts/login.htm.php, e o mostrará envolvendo a view correspondente à action.

Você pode também definir um layout específico para uma action, sem precisar afetar todas as outras actions de um mesmo controller. Para tal, basta definir Controller::$layout dentro da action desejada.

public function login() {
     $this->layout = "login";
}

Neste caso, apenas a action login onde a atribuição acima foi feita é que será afetada pelo layout escolhido.

Alterando o layout padrão da aplicação

Conforme dito anteriormente, o layout padrão definido pelo Spaghetti* é /app/layouts/default.htm.php. Porém, caso prefira utilizar outro arquivo, você pode alterar o layout padrão definindo-o no AppController de sua aplicação, conforme explicado em AppController:

<?php
class AppController extends Controller {
     public $layout = "my_layout";
}
?>

A partir disso, toda sua aplicação passará a usar o layout my_layout, a menos que esse seja sobrescrito por um controller ou action onde se faça necessário.

Definindo um título para a página

A maneira como as views do Spaghetti* são estruturadas permite que algumas técnicas interessantes sejam utilizadas. Definir o conteúdo de uma tag <title>, dentro do layout, a partir de um título qualquer dentro de uma view é uma delas.

Como internamente o Spaghetti* gera primeiro o conteúdo da view para só depois injetá-la dentro de um layout (embora em uma primeira observação possa parecer o contrário), qualquer variável definida na view também estará disponível para o layout, já que ambos compartilham a mesma instância de View. Com isso, podemos definir uma variável View::$pageTitle dentro da view, e ela estará disponível para todo o layout, elements e helpers.

Suponha que, em uma view qualquer, você defina o título da página, e ele também deve aparecer em <title>. Usando a idéia de View::$pageTitle, podemos imprimir esse título ao mesmo tempo em que o atribuímos à variável:

<h1><?php echo $this->pageTitle = "Título da Página" ?></h1>

Após isso, basta modificar seu layout para que adote View::$pageTitle como título da página:

<title><?php echo $this->pageTitle ?></title>

Além de definir o título da página, essa técnica pode ser usada para várias outras propósitos. Um deles, usado internamente pelo HtmlHelper, é imprimir tags de estilo e script de maneira não-inline, ou seja, embora a chamada a esses elementos seja feita pela view, eles são impressos dentro de <header>, no layout, através de View::$stylesForLayout e View::$scriptsForLayout, como você pode descobrir na documentação sobre o HtmlHelper.