Scripts de Visualização
Uma vez que seu controlador tenha atribuido as variáveis e chamado o método
render(), Zend_View incluirá o script de
visualização requerido e o executará "dentro" do escopo da instância de
Zend_View. Portanto, em seus scripts de visualização, as referências
a $this apontarão para a própria instância de Zend_View.
Variáveis atribuídas à visualização pelo controlador são referidas como propriedades de
instância. Por exemplo, se o controlador atribuir a variável 'algumacoisa', você deve
referir-se a ela como $this->algumacoisa em seu script de visualização. (Isto permite um
rastreamento dos valores que foram atribuidos ao script, e que são internos ao mesmo).
A fim de lembrar, aqui está um exemplo de script de visualização originado da introdução do
Zend_View.
books): ?>
Autor
Título
books as $key => $val): ?>
escape($val['author']) ?>
escape($val['title']) ?>
Não existem livros a serem exibidos.
]]>Escapando a Saída
Uma das tarefas mais importantes a ser executada por scripts de visualização é assegurar
que a saída seja corretamente escapada; entre outras coisas, isto ajuda a evitar ataques
do tipo site-cruzado. A menos que você esteja usando uma função, método, ou assistente
que realize o escape, você sempre deverá escapar o conteúdo das variáveis antes de
exibí-lo.
Zend_View implementa um método chamado escape() que realiza
corretamente o escape para você.
variable;
// maneira recomendada:
echo $this->escape($this->variable);
]]>
Por padrão, o método escape() usa a função htmlspecialchars() do PHP
para fazer o escape. Mas, dependendo do seu ambiente, você pode desejar um comportamento
diferente para o escape. Use o método setEscape() no nível do controlador para instruir
o Zend_View sobre qual função de callback utilizar para fazer o
escape.
setEscape('htmlentities');
// ou instrui o uso de um método estático de classe
$view->setEscape(array('SomeClass', 'methodName'));
// ou mesmo um método de instância
$obj = new SomeClass();
$view->setEscape(array($obj, 'methodName'));
// e renderiza a visualização
echo $view->render(...);
]]>
A função ou método de callback deverá tomar o valor a ser escapado como seu primeiro
parâmetro, e os demais parâmetros deverão ser opcionais.
Usando Sistemas de Template Alternativos
Embora o PHP em si seja um poderoso sistema de template, muitos
desenvolvedores sentiram que ele é muito potente ou complexo para seus designers de
templates e acabam usando um motor de template alternativo.
Zend_View fornece para isso dois mecanismos, o primeiro através
de scripts de visualização, e o segundo implementando
Zend_View_Interface.
Sistemas de Template Usando Scripts de Visualização
Um script de visualização pode ser usado para instanciar e manipular um objeto de
template separado, como um template do PHPLIB. O script de visualização para esse
tipo de atividade pode ser algo como isto:
books) {
$tpl->setFile(array(
"booklist" => "booklist.tpl",
"eachbook" => "eachbook.tpl",
));
foreach ($this->books as $key => $val) {
$tpl->set_var('author', $this->escape($val['author']);
$tpl->set_var('title', $this->escape($val['title']);
$tpl->parse("books", "eachbook", true);
}
$tpl->pparse("output", "booklist");
} else {
$tpl->setFile("nobooks", "nobooks.tpl")
$tpl->pparse("output", "nobooks");
}
]]>
Estes seriam os arquivos de template relacionados:
Autor
Título
{books}
{author}
{title}
Não existem livros a serem exibidos.
]]>Sistemas de Template Usando Zend_View_Interface
Alguns podem achar mais fácil simplesmente fornecer um sistema de template
compatível com Zend_View.
Zend_View_Interface define a interface mínima necessária para
a compatibilidade:
Usando essa interface, torna-se relativamente fácil envolver um sistema de template
de terceiro como uma classe compatível com Zend_View. Como
exemplo, o seguinte é um potencial envoltório para Smarty:
_smarty = new Smarty;
if (null !== $tmplPath) {
$this->setScriptPath($tmplPath);
}
foreach ($extraParams as $key => $value) {
$this->_smarty->$key = $value;
}
}
/**
* Return the template engine object
*
* @return Smarty
*/
public function getEngine()
{
return $this->_smarty;
}
/**
* Set the path to the templates
*
* @param string $path The directory to set as the path.
* @return void
*/
public function setScriptPath($path)
{
if (is_readable($path)) {
$this->_smarty->template_dir = $path;
return;
}
throw new Exception('Invalid path provided');
}
/**
* Retrieve the current template directory
*
* @return string
*/
public function getScriptPaths()
{
return array($this->_smarty->template_dir);
}
/**
* Alias for setScriptPath
*
* @param string $path
* @param string $prefix Unused
* @return void
*/
public function setBasePath($path, $prefix = 'Zend_View')
{
return $this->setScriptPath($path);
}
/**
* Alias for setScriptPath
*
* @param string $path
* @param string $prefix Unused
* @return void
*/
public function addBasePath($path, $prefix = 'Zend_View')
{
return $this->setScriptPath($path);
}
/**
* Assign a variable to the template
*
* @param string $key The variable name.
* @param mixed $val The variable value.
* @return void
*/
public function __set($key, $val)
{
$this->_smarty->assign($key, $val);
}
/**
* Allows testing with empty() and isset() to work
*
* @param string $key
* @return boolean
*/
public function __isset($key)
{
return (null !== $this->_smarty->get_template_vars($key));
}
/**
* Allows unset() on object properties to work
*
* @param string $key
* @return void
*/
public function __unset($key)
{
$this->_smarty->clear_assign($key);
}
/**
* Assign variables to the template
*
* Allows setting a specific key to the specified value, OR passing
* an array of key => value pairs to set en masse.
*
* @see __set()
* @param string|array $spec The assignment strategy to use (key or
* array of key => value pairs)
* @param mixed $value (Optional) If assigning a named variable,
* use this as the value.
* @return void
*/
public function assign($spec, $value = null)
{
if (is_array($spec)) {
$this->_smarty->assign($spec);
return;
}
$this->_smarty->assign($spec, $value);
}
/**
* Clear all assigned variables
*
* Clears all variables assigned to Zend_View either via
* {@link assign()} or property overloading
* ({@link __get()}/{@link __set()}).
*
* @return void
*/
public function clearVars()
{
$this->_smarty->clear_all_assign();
}
/**
* Processes a template and returns the output.
*
* @param string $name The template to process.
* @return string The output.
*/
public function render($name)
{
return $this->_smarty->fetch($name);
}
}
]]>
Neste exemplo, você poderia instanciar a classe
Zend_View_Smarty em vez de Zend_View,
e então usá-la aproximadamente da mesma maneira que
Zend_View:
setView($view)
->setViewBasePathSpec($view->_smarty->template_dir)
->setViewScriptPathSpec(':controller/:action.:suffix')
->setViewScriptPathNoControllerSpec(':action.:suffix')
->setViewSuffix('tpl');
//Example 2. Usage in action controller remains the same...
class FooController extends Zend_Controller_Action
{
public function barAction()
{
$this->view->book = 'Zend PHP 5 Certification Study Guide';
$this->view->author = 'Davey Shafik and Ben Ramsey'
}
}
//Example 3. Initializing view in action controller
class FooController extends Zend_Controller_Action
{
public function init()
{
$this->view = new Zend_View_Smarty('/path/to/templates');
$viewRenderer = $this->_helper->getHelper('viewRenderer');
$viewRenderer->setView($this->view)
->setViewBasePathSpec($view->_smarty->template_dir)
->setViewScriptPathSpec(':controller/:action.:suffix')
->setViewScriptPathNoControllerSpec(':action.:suffix')
->setViewSuffix('tpl');
}
]]>