SitePoint Sponsor

User Tag List

Results 1 to 16 of 16
  1. #1
    SitePoint Zealot
    Join Date
    Nov 2007
    Posts
    102
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Smarty and ZF integration

    Hello people,
    I'm still new to ZF, but i was trying to implement ZF with smarty with help of this site:
    http://framework.zend.com/manual/en/...w.scripts.html

    But i have a problem.
    Here's the folder structure:
    Code:
    /application
        /controllers
        /models
        /Smarty
             /cache
             /config
             /templates
             /templates_c
    /library
        /Smarty  --  holds smarty files
        /Zend  --  holds zf files
    .htaccess
    index.php  --  bootstrapper file
    Here are some files for reference:

    smarty.php
    PHP Code:
    <?php

    require_once '../library/Smarty/libs/Smarty.class.php'

    class 
    Zend_View_Smarty implements Zend_View_Interface
        
    {
            
    /**
             * Smarty object
             * @var Smarty         
             * @return void
             */
            
    protected $_smarty;
            
            
    /**
             * Constructor
             * 
             * @param $tmplPath
             * @param $extraParams
             * @return void
             */
            
    public function __construct($tmplPath null$extraParams = array())
            {
                require_once 
    '../library/Smarty/libs/Smarty.class.php'
                
    $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
             * @see library/Zend/View/Zend_View_Interface#getEngine()
             */
            
    public function getEngine()
            {
                return 
    $this->_smarty;
            }
            
            
    /**
             * Set path to templates
             * 
             * @param string $path 
             * return void
             * @see library/Zend/View/Zend_View_Interface#setScriptPath()
             */
        
    public function setScriptPath($path)
        {
            
            if (
    is_readable($path)) 
            {
                
    //Sets all smarty directories
                //$this->_smarty->template_dir = $path;
                
    $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';
                
    get_class_methods('Smarty');
                return;
         
            }

            throw new 
    Exception('Invalid path provided');
        }
            
            
    /**
             * retrieve all current template directories 
             * 
             * @return string
             * @see library/Zend/View/Zend_View_Interface#getScriptPaths()
             */
            
    public function getScriptPaths()
            {
                return 
    $this->_smarty->template_dir;
            }
            
            
    /**
             * alias for setScriptPath
             * 
             * @param string $path
             * @param string prefix unused
             * @return void
             * @see library/Zend/View/Zend_View_Interface#setBasePath()
             */
            
    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 variable to the template
         * 
         * @param string $key The variable name.
         * @param mixed $val The variable value.
         * @return void
         * @see library/Zend/View/Zend_View_Interface#__set()
         */
        
    public function __set($key$val)
        {
            
    $this->_smarty->assign($key$val);
        }
        
        
    /**
         * 
         * @param $key
         * @return unknown_type
         */
        
    public function __get($key)
        {
            return 
    $this->_smarty->get_template_vars($key);
        }
        
         
    /**
         * 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);
        }
    }

    ?>
    indexController.php
    PHP Code:
    <?php 
    class indexController extends Zend_Controller_Action
    {
        public function 
    init()
        {
            
    // Set Smarty defaults so it is availale throught the class 
            
    $this->view = new Zend_View_Smarty(); 
            
    $this->view->setScriptPath(realpath('../application/Smarty')); 
            
            
    $viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer($this->view); 
            
    $viewRenderer->setViewBasePathSpec('../application/Smarty/templates'); 
            
    $viewRenderer->setViewScriptPathSpec(':controller/:action.:suffix'); 
            
    $viewRenderer->setViewScriptPathNoControllerSpec(':action.:suffix'); 
            
    $viewRenderer->setViewSuffix('tpl'); 

            
    Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
    }
        
        function 
    indexAction()
        {
            
    $this->view->author 'Zoran';
        }
    }
    index.tpl
    PHP Code:
    <html>
        <
    head>
            <
    title>BRAVO</title>
        </
    head>
        <
    body>
            <
    h1>{$author}</h1BLA
        
    </body>
    </
    html
    Now it seems to be ok, but i have a problem, as it seems that it cannot find .tpl files, but it does not display any error, it's just blank site (but it did load smarty class and all that).
    SO any ideas where i went wrong? Tnx.

  2. #2
    SitePoint Enthusiast
    Join Date
    Dec 2007
    Posts
    40
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Do you have a bootstrap file? (index.php) If so could you please post your bootstrap file.

    I suspect that you need to move the code you currently have in the init() method to the index.php bootstrap file. I think your problem may lie with the controller already having dispatched the request BEFORE you are assigning the view renderer as a helper with:

    PHP Code:
     Zend_Controller_Action_HelperBroker::addHelper($viewRenderer); 
    I think the helper needs to be assigned before you call:

    PHP Code:
    Zend_Controller_Front::getInstance()->dispatch(); 
    in your bootstrap.

  3. #3
    <?php while(!sleep()){code();} G.Schuster's Avatar
    Join Date
    Mar 2007
    Location
    Germany
    Posts
    428
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Look at exTSend: http://www.extsend.com/
    It has a Smarty integration, perhaps that suits your needs.

  4. #4
    SitePoint Zealot
    Join Date
    Nov 2007
    Posts
    102
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    ok i finally managed to make it display tpl files (yes, i put the code in bootstrap file).

    the only problem that i have now is, that i get this warning:

    Warning: Invalid argument supplied for foreach() in E:\wamp\www\uf1r\library\Zend\Controller\Action\Helper\ViewRenderer.php on line 492

    I get this on all pages, but everything seems to be displayed correctly, so i dunno what is the problem about it?

    This is the part of index.php (bootstrap file) that deals with smarty:
    PHP Code:
    // Set Smarty defaults so it is availale throught the class 
       
    $view = new Zend_View_Smarty(); 
        
    $view->setScriptPath(realpath('../application/Smarty')); 
            
        
    $viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer(); 
        
    $viewRenderer->setView($view)
                     ->
    setViewBasePathSpec('../application/Smarty')
                     ->
    setViewScriptPathSpec(':controller/:action.:suffix')
                       ->
    setViewScriptPathNoControllerSpec(':action.:suffix')
                        ->
    setViewSuffix('tpl'); 

        
    Zend_Controller_Action_HelperBroker::addHelper($viewRenderer); 
    Any ideas why i get this warning?

    and tnx for help btw!

  5. #5
    <?php while(!sleep()){code();} G.Schuster's Avatar
    Join Date
    Mar 2007
    Location
    Germany
    Posts
    428
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Seems as if there is no "scriptPath" set - at least getScriptPaths() doesn't return an array.
    Lines 489 to 492:
    PHP Code:
            $currentPaths $this->view->getScriptPaths();
            
    $path         str_replace(array('/''\\'), '/'$path);
            
    $pathExists   false;
            foreach (
    $currentPaths as $tmpPath) { 

  6. #6
    SitePoint Enthusiast
    Join Date
    Dec 2007
    Posts
    40
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yes, it seems like you have no paths defined or the getScriptPaths() method doesn't return an array as G.Schuster said.

    Add this for now to the bootstrap (after you set up the view) and tell us what echoes out:

    PHP Code:
    print_r($view->getScriptPaths()); 
    You should (hopefully) see an array of script paths. Check them against your actual paths.

    Also, what is your folder structure inside the templates directory? Are you following the structure laid out in the 'setViewScriptPathSpec'? ('index/index.tpl' for IndexController->indexAction).

    I would recommend changing these lines for now and try just putting your templates directly into the templates folder for now. For example: templates/index.tpl

    I've also found (from doing my own custom routing for the project I'm working on) that Zend automatically assumes you will have a folder labeled 'scripts' in your view path and you CAN'T CHANGE IT. It is automatically concatenated to the path string in one of the Zend classes (can't remember where I found it in their code but it is there). Trust me, I've tried to change it. So you might want to try something like 'templates/scripts/index.tpl' if the above is not working.

    PHP Code:
    ->setViewBasePathSpec(realpath('../application/Smarty/templates')) //Try the realpath function here and see if it helps.
    ->setViewScriptPathSpec(':action.:suffix'//Try changing this for now and see if it can find a template at 'templates/index.tpl' or 'templates/scripts/index.tpl' for example.
    ->setViewScriptPathNoControllerSpec(':action.:suffix'//You really shouldn't need this one. This is the default setting. 

  7. #7
    SitePoint Zealot
    Join Date
    Nov 2007
    Posts
    102
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    well, maybe the is that there is no array, but actually a value. For example, in lines where the warning appears:
    // Determine if this path has already been registered
    $currentPaths = $this->view->getScriptPaths();
    $path = str_replace(array('/', '\\'), '/', $path);
    $pathExists = false;

    echo $currentPaths;
    foreach ($currentPaths as $tmpPath) {
    the echo actually displays the path, rether then word 'array'. Maybe that the problem; it's not getting array but rether string in the loop?

  8. #8
    SitePoint Enthusiast
    Join Date
    Dec 2007
    Posts
    40
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Woops. I just spotted something. setViewBasePathSpec() is supposed to be given a spec (like :controller/:action ) and NOT a path. Try commenting that out. It should not be needed.

    Here is a link to the API doc for setViewBasePathSpec().

    This may be a Zend bug. It maybe needs to have more than one path set or it doesn't return an array when it calls getScriptPaths(). You could test that by adding another script path to the view with the following and see if it then returns an array.

    PHP Code:
    $view->addScriptPath(realpath('../application/some_other_path')); 

  9. #9
    SitePoint Zealot
    Join Date
    Nov 2007
    Posts
    102
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    well i just checked default zend framework view that extends Zend_View_Interface, just the way i do with Smarty. The difrence is, that their implemenetation actually have special (private) methods that creates array from start and later just fill this array, so even if this is just one path, it's still array.

    While my problem was that i check how ZF manual suggest to deal with smarty, and it wasn't really mentioned there that it really has to be array (and it seems it has to).

    So if default View class has special methods that convert all path into array, then i think i have to do something similar.

    I'll try to do that (that means Smarty.php) and will let you know of the result.

    ---edited---
    Ok, to avoid doubleposting, just in case if anyone else will need to know.
    Ok so, i used the same methods that default zend View (Zend_View_Abstract, iirc) uses to put all paths into array and now it finally works.

    So, in short, the problem was that foreach loop was getting string instead of array, so you have to modify your (smarty) class that extends Zend_View_Interface so that setScriptPath will also store paths into array, and getScriptPath so that it will actually return this array instead of single string.

    Tnx all for help!

  10. #10
    SitePoint Zealot
    Join Date
    Nov 2007
    Posts
    102
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    also, i'm now trying to use zend_layout with smarty....buti have some problems.

    When i use the Zend_layout::startMvc('..setup path here...');

    I get Smarty error, that it cannot find index.phtml. I'm a little lost here right now, is there maybe something in Smarty.php that i forgot to implement?

  11. #11
    <?php while(!sleep()){code();} G.Schuster's Avatar
    Join Date
    Mar 2007
    Location
    Germany
    Posts
    428
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Uhm...Zend_Layout IS something like Smarty.
    You normally don't use both.

  12. #12
    SitePoint Enthusiast
    Join Date
    Dec 2007
    Posts
    40
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You can use Zend Layout with Smarty. I use both. It is very helpful to use a two step view.

    I was wondering if you were going to try this approach. Here is what my Zend Layout setup looks like in my bootstrap file:

    PHP Code:
    // Setup inflector for Zend_Layout
        
    $inflector = new Zend_Filter_Inflector(':script.:suffix');
        
    $inflector->addRules(array(':script' => array('Word_CamelCaseToDash','StringToLower'),'suffix' => 'tpl'));
         
        
    //Initialize Zend_Layout's MVC helpers
        
    Zend_Layout::startMvc(array('layout' => 'public',
                                    
    'layoutPath' => BASE_PATH PUBLIC_FOLDER,
                                    
    'view' => $view,
                                    
    'inflector' => $inflector)); 
    Set the 'layout' option to the name of your layout script WITHOUT the suffix and set the 'layoutPath' to your layout path. I have set up constants for all my paths (BASE_PATH,PUBLIC_FOLDER etc..) using define() at the beginning of my bootstrap.

  13. #13
    <?php while(!sleep()){code();} G.Schuster's Avatar
    Join Date
    Mar 2007
    Location
    Germany
    Posts
    428
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by awright418 View Post
    You can use Zend Layout with Smarty.
    Why would you do that?
    Zend_Layout offers all features you need - it's extra processing time that get's lost to start up Smarty for the sake of nothing gained.

  14. #14
    SitePoint Zealot
    Join Date
    Nov 2007
    Posts
    102
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    will try that awright, tnx.

    Though, i thought zend_view (default zend view) was something like smarty(dealing with templates), while zend_layout was rether the way to organize layout structure?

  15. #15
    SitePoint Enthusiast
    Join Date
    Dec 2007
    Posts
    40
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Why would you do that?
    Zend_Layout offers all features you need - it's extra processing time that get's lost to start up Smarty for the sake of nothing gained.
    I think the advantage I see is in the way Zend Layout handles the two step view process.

    With Smarty, you must use include inside EACH "content" template to include the header and footer thus wrapping the content in the layout. Big problems can occur if you wanted to for example change the name of the header or footer template you are including. You would have to make that change in every end "content" template file.

    With Zend Layout, you create a layout template and within that layout template you include the page content.

    It breaks down to Zend Layout doing:

    1. Render the layout template.
    2. Include the page content template.

    and Smarty doing:

    1. Render the page content template.
    2. Include the header and footer templates from within the page content template.

    I guess it really is just a choice. In the end, both methods work fine. I just find the way in which Zend Layout handles the process to be less risky from a large project standpoint. I would much rather not have lots and lots of includes for the layout in my many content templates.

    I hope this makes sense.

  16. #16
    <?php while(!sleep()){code();} G.Schuster's Avatar
    Join Date
    Mar 2007
    Location
    Germany
    Posts
    428
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by awright418 View Post
    With Smarty, you must use include inside EACH "content" template to include the header and footer thus wrapping the content in the layout. Big problems can occur if you wanted to for example change the name of the header or footer template you are including. You would have to make that change in every end "content" template file.
    Nope, you don't have to.
    Just plan your app right and you're able to render the page content into a given layout.
    With exTSend I managed to set a layout which is for all pages and each page is able to set a specific layout if needed - completely without Zend_Layout.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •