quinta-feira, 21 de abril de 2011

Integrando Zend Framework -1.11.4 com Smarty -3.0.6

Olá, galera, hoje irei apresentar como usar o Smarty com o Zend Framework.


Smarty é uma biblioteca em Php que possibilita separar a interface gráfica da lógica de programação, desta forma o web design não irá interferir na lógica de programação e o programador não irá interferir no layout do site, isso gera uma grande facilidade em trabalhos em equipe  com isso facilita e melhora o desenvolvimento de qualquer aplicação em Php.


Zend Framework é um framework de código aberto totalmente orientado a objeto e seguindo rigorosamente o padrão MVC mantendo assim o código sempre limpo e de fácil manutenção por qualquer um que for dar suporte ao site.


O Zend já possui um ótimo sistema de views que trabalha com a extensão .phtm, então porque usar um outro sistema de templates. 


As views .phtml utilizam script php para apresentar as informações com isso o web design terá que ter conhecimentos em php ou o programador php terá que trabalhar com os layouts. Outra grande vantagem que encontro no uso do Smarty é que imagina que haverá uma mudança de framework agora irá utilizar o CakePhp, CodeIgniter  ou algum outro, se você utilizar Smarty não haverá a necessidade de mudar nenhum tipo de tratamento no layout. 


Não vou abordar sobre as vantagens e desvantagens de se utilizar o Smarty com Zend Framework, na internet existem muitos artigos abordando esse tema. Aqui vou apenas apresentar como é simples a integração entre os dois, então vamos ao que interessa.


Neste post utilizei o Zend Tool para criar o projeto, num post posterior ensino como instalar o Zend Tool e usar as suas funcionalidades.
Link para download do Zend http://www.framework.zend.com/download/current/
Link para download do Smarty http://www.smarty.net/download

Neste post eu considero que você já tenha criado o projeto seguindo os padrões da ZF, como o Zend Tool não adiciona a biblioteca automaticamente abra a pasta do ZF que você baixou e copie a pasta Zend ela se encontra dentro da pasta library, agora cole ela dentro da pasta library do seu projeto.
Agora vá para a pasta do Smarty que você baixou e copie a pasta libs e cole ela dentro da pasta library do seu projeto, agora mude o nome da pasta libs para Smarty.

Com isso você tem as duas bibliotecas já gravadas em seu projeto agora vamos realizar a integração entre as duas.

Abra o application.ini o caminho padrão dele é application\configs\application.ini e adicione a linha autoloadernamespaces[] = "SmartyMain";

Exemplo do application.ini







Dentro do arquivo Bootstrap.php adicione o método abaixo, ele que indica ao ZF qual tipo template usar e onde ele se encontra:


protected function _initView()  
    {  
  
        // aqui podemos passar quaisquer parâmetros que sejam atributos do objeto smarty  
        // se quisermos habilitar o cache, por exemplo:  
        $params = array(  
                      'caching'        => true,  
                      'cache_lifetime' => 30  
                  );  
                  
        
        /*
         * Aqui você define onde encontrar as pastas do templates, templates_c, cache e config
         */
        $view = new SmartyMain('application/views/', $params);  
        
        
        $viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer();  
       
        
        /*
         * Aqui define como o Zend irá encontrar o template necessário para cada ação do usuário não é indicado alterar
         * 
         */
        $viewRenderer->setView($view)  
                     ->setViewBasePathSpec($view->getEngine()->template_dir)  
                     ->setViewScriptPathSpec(':controller/:action.:suffix')  
                     ->setViewScriptPathNoControllerSpec(':action.:suffix')  
                     ->setViewSuffix('tpl');  
        Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);  
  
    } 


Agora você terá que criar a Classe SmartyMain.php dentro da pasta library, esta classe é responsável por instânciar a classe Smarty é e nesta classe que você define as pastas onde ficarão os templates.


<?php

require_once('Smarty/Smarty.class.php');

class SmartyMain implements Zend_View_Interface
{

    /**
     * Smarty object
     * @var Smarty
     */
    protected $_smarty;

    /**
     * Constructor
     *
     * @param string $tmplPath
     * @param array $extraParams
     * @return void
     */
    public function __construct($tmplPath = null, $extraParams = array())
    {
        $this->_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)) {
            
            /*
             * Aqui você irá definir quais são os diretorios onde os templates, templates_c , cache e config serão armazenados
             * estes nomes são o padrão do Smarty
             */
            
            $this->_smarty->template_dir = $path."templates";
            $this->_smarty->compile_dir  = $path."templates_c";
            $this->_smarty->cache_dir    = $path."cache";
            $this->_smarty->config_dir   = $path."config";
            
            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);
    }

}

Agora crie os diretórios onde ficarão os templates,  o padrão que esta sendo utilizado é esse:









Usando o padrão do ZF Controller/Action de acesso as views,  para cada controller você deverá criar uma pasta e dentro desta pasta o nome do template e ele é de acordo com a ação a ser realizada, exemplo:

Para o  IndexController ficara desta forma templates/index/index.tpl

Para o AlunoController ficara desta forma templates/aluno/index.tpl

Para o AlunoController ficara desta forma templates/aluno/novo.tpl

Dependendo da ação a ser executada irá chamar o template necessário.



Estrutura completa do projeto:






Que tal agora fazer um teste, adicione o método abaixo dentro da classe IndexController 




    public function indexAction()
    {
        // cria algumas variáveis  
        $projeto = "Integrando Smarty e Zend Framework";  
        $dados_completo = array(  
            array('nome' => 'Wesley', 'sobrenome' => 'David Santos'),
            array('nome' => 'Fulano', 'sobrenome' => 'de tal')  
        );  
        // inclui as variáveis na view  
        $this->view->assign('projeto', $projeto);  
        $this->view->assign('dados_completo', $dados_completo);  
    }



Agora dentro do index.tpl localizado dentro de templates/index/index.tpl adicione:

<p>{$projeto}</p>  
<table>  
    
    {foreach from=$dados_completo item=registro}  
    <tr>  
        <td>{$registro.nome}</td>  
        <td>{$registro.sobrenome}</td>  
    </tr>  
    {/foreach}  
</table>  


Agora é só abrir o navegador e testar.

Espero que tenham gostado, qualquer dúvida estou a disposição.

5 comentários:

  1. o meu dá erro tanto do windows quanto no linux

    Fatal error: Uncaught exception 'Exception' with message 'Invalid path provided' in /var/www/zend.dev/library/SmartyMain.php:69
    Stack trace:
    #0 /var/www/zend.dev/library/SmartyMain.php(26): SmartyMain->setScriptPath('application/vie...')
    #1 /var/www/zend.dev/application/Bootstrap.php(20): SmartyMain->__construct('application/vie...', Array)
    #2 /var/www/zend.dev/library/Zend/Application/Bootstrap/BootstrapAbstract.php(667): Bootstrap->_initView()
    #3 /var/www/zend.dev/library/Zend/Application/Bootstrap/BootstrapAbstract.php(620): Zend_Application_Bootstrap_BootstrapAbstract->_executeResource('view')
    #4 /var/www/zend.dev/library/Zend/Application/Bootstrap/BootstrapAbstract.php(584): Zend_Application_Bootstrap_BootstrapAbstract->_bootstrap(NULL)
    #5 /var/www/zend.dev/library/Zend/Application.php(355): Zend_Application_Bootstrap_BootstrapAbstract->bootstrap(NULL)
    #6 /var/www/zend.dev/public/index.php(25): Zend_Application->bootstrap()
    #7 {main}
    thrown in /var/www/zend.dev/library/SmartyMain.php on line 69

    ResponderExcluir
  2. ele consegue ler as pastas, mesmo eu tendo dado a permissão total 777

    ResponderExcluir
  3. Bruno, Blz

    Em relação ao erro verifique se no application.ini do zend você informou a classe do smarty a ser chamada autoloadernamespaces[] = "SmartyMain";

    O nome SmartyMain também deve ser o nome da classe e não somente do arquivo
    ex.: Class SmartyMain{ metódos e atributos da classe} e dentro desta classe SmartyMain verifique também se você informa ao Zend onde estão os diretório que possuem as views.

    Dá uma lida devagar no Post entenda bem o funcionamento de cada parte para integração de libs no Zend, pois com certeza isso irá facilitar e muito quando você desejar adicionar novas libs.

    Abraço.

    ResponderExcluir
  4. isso nao adiantou pra mim
    fiz o q vc falou mas continua dando o erro que o bruno disse

    ResponderExcluir
  5. pra mim so aparece a pagina em branco sem nenhum erro

    ResponderExcluir