ExpressionEngine CMS
Open, Free, Amazing

Thread

This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.

The active forums are here.

Yet Another Smarty Thread

September 03, 2007 6:32pm

Subscribe [23]
  • #1 / Sep 03, 2007 6:32pm

    xtramix

    7 posts

    Integration of CI and Smarty has been discussed many times on this forum, yet I’ve decided to post here my own solution, in the hopes that someone might find it useful.

    The only advantage this particular approach offers over other suggested solutions, is its ability to incorporate CI and Smarty code in the same template, rather than forcing you to choose between the two. If your templates contain pure Smarty code, you can load/parse them in a usual fashion, e.g.:

    $this->smarty_parser->parse("template.tpl", $data);

    However, if your template started out as a regular CI view, you can switch to Smarty at any time and still keep all the php code in your template intact, knowing that all CI function calls and variables will be processed correctly. Simply prefix the template name with “ci:” to tell Smarty it’s a “resource”, and it will ask CI to load and pre-parse the view before handing it off to Smarty engine:

    $this->smarty_parser->parse("ci:template.tpl", $data);

    The steps necessary to set up Smarty under CI in this case are very similar to those suggested by other authors:

    1. Rename Smarty “libs” folder to “smarty”, and move it to CI’s application/libraries directory.

    2. Create Smarty_parser.php file in the same directory and paste the following code:

    <?php if (!defined('BASEPATH')) exit('No direct script access allowed');
    
    require "smarty/Smarty.class.php";
    
    class Smarty_parser extends Smarty {
    
        function Smarty_parser($config = array())
        {
            parent::Smarty();
            
            if (count($config) > 0)
            {
                $this->initialize($config);
            }
    
            // register Smarty resource named "ci"
            $this->register_resource("ci", array($this, 
                            "ci_get_template", "ci_get_timestamp", "ci_get_secure", "ci_get_trusted")
            );
                                           
            log_message('debug', "Smarty_parser Class Initialized");
        }
    
        /**
         * Initialize preferences
         */    
        function initialize($config = array())
        {
            foreach ($config as $key => $val)
            {
                if (isset($this->$key))
                {
                    $method = 'set_'.$key;
                    
                    if (method_exists($this, $method))
                    {
                        $this->$method($val);
                    }
                    else
                    {
                        $this->$key = $val;
                    }            
                }
            }
        }
    
        /**
         *  Set the left/right variable delimiters
         */
        function set_delimiters($l = '{', $r = '}')
        {
            $this->left_delimiter = $l;
            $this->right_delimiter = $r;
        }
    
        /**
         *  Parse a template using Smarty engine
         *
         * Parses pseudo-variables contained in the specified template,
         * replacing them with the data in the second param.
         * Allows CI and Smarty code to be combined in the same template 
         * by prefixing template name with "ci:".
         */
        function parse($template, $data, $return = FALSE)
        {
            if ($template == '')
            {
                return FALSE;
            }
    
            $CI =& get_instance();
            
            $CI->benchmark->mark('smarty_parse_start');
            
            if (is_array($data))
            {
                $this->assign(&$data);
            }
            
            // make CI object directly accessible from a template (optional)
            $this->assign_by_ref('CI', $CI);
            
            $template = $this->fetch($template);
    
            if ($return == FALSE)
            {
                $CI->output->final_output = $template;
            }
            
            $CI->benchmark->mark('smarty_parse_end');
            
            return $template;
        }
    
        /**
         * Smarty resource accessor functions
         */     
        function ci_get_template ($tpl_name, &$tpl_source, &$smarty_obj)
        {
            $CI =& get_instance();
            
            // ask CI to fetch our template
            $tpl_source = $CI->load->view($tpl_name, $smarty_obj->get_template_vars(), true);
            return true;
        }
        
        function ci_get_timestamp($view, &$timestamp, &$smarty_obj)
        {
            $CI =& get_instance();
            
            // Taken verbatim from _ci_load (Loader.php, 580):
            $ext = pathinfo($view, PATHINFO_EXTENSION);
            $file = ($ext == '') ? $view.EXT : $view;
            $path = $CI->load->_ci_view_path.$file;
            
            // get file modification date
            $timestamp = filectime($path);
            return ($timestamp !== FALSE);
        }
        
        function ci_get_secure($tpl_name, &$smarty_obj)
        {
            // assume all templates are secure
            return true;
        }
        
        function ci_get_trusted($tpl_name, &$smarty_obj)
        {
            // not used for templates
        }
    }
    ?>

    3. Create Smarty_parser.php file in the application/config directory:

    <?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
    
    // Please see Smarty user guide for more info:
    // <a href="http://smarty.php.net/manual/en/api.variables.php">http://smarty.php.net/manual/en/api.variables.php</a>
    
    // The name of the directory where templates are located.
    $config['template_dir'] = dirname(FCPATH);
    
    // The directory where compiled templates are located
    $config['compile_dir'] = BASEPATH.'cache/';
    
    //This tells Smarty whether or not to cache the output of the templates to the $cache_dir. 
    $config['caching']        = 0;
    
    // This forces Smarty to (re)compile templates on every invocation. 
    // When deploying, change this value to 0
    $config['force_compile'] = 1;
    $config['compile_check'] = TRUE;
    ?>

    4. In your controller, load Smarty library and parse the template, as such:

    // uncomment the line below to load the library under the name "smarty", if desired
    // $this->load->_ci_varmap['smarty_parser'] = 'smarty';
    $this->load->library('smarty_parser');
    $this->smarty_parser->parse("ci:template", $data);

    Hope this helps.

  • #2 / Sep 03, 2007 8:16pm

    esra

    485 posts

    Nice solution. You might consider placing your entire post on the wiki with a url link back to here.

  • #3 / Sep 13, 2007 2:02am

    ahmad furqon's avatar

    ahmad furqon

    3 posts

    yeah, this is cool…
    thanks a lot for this solution

  • #4 / Sep 13, 2007 6:41am

    bijon

    46 posts

    Hi ,

    This is really nice. I am also think that you should write it to wiki .

  • #5 / Feb 01, 2008 6:41pm

    jargo

    2 posts

    hi!
    could there be a problem with this smarty wrapper and the new CI version 1.6.0?
    I tried to upgrade my application from v1.5.4 to v1.6.0, but all i get is:

    A PHP Error was encountered

    Severity: User Warning

    Message: Smarty error: unable to read resource: “welcome.html”

    Filename: smarty/Smarty.class.php

    Line Number: 1095

    the welcome.html exists, the specified path seems to be right:

    /var/www/localhost/htdocs/homepage/system/application/views

    I also tried to create a simple new application only with out-of-the-box CI-1.6.0 and the smarty wrapper above.
    Same problem.  :down:

    any idea about a solution?

    jargo

  • #6 / Feb 03, 2008 7:08pm

    xtramix

    7 posts

    jargo,

    try changing line 7 in your config/Smarty_parser.php file to:

      $config[‘template_dir’] = BASEPATH . ‘application/views’ ;

    Please note that you will need to revert the changes if you decide to move your smarty templates to the web app root.


    - x

  • #7 / Feb 06, 2008 5:16pm

    jargo

    2 posts

    hi!
    thanks for your reply. I found the problem/solution.
    my smarty_parser.php in application/config was written with capital “s”.
    CI 1.6.0 doesn’t like it 😊

    Perhaps change this line in your tutorial:

    3. Create Smarty_parser.php file in the application/config directory

    to

    3. Create smarty_parser.php file in the application/config directory

    jargo

  • #8 / Feb 25, 2008 11:11am

    MABUS

    6 posts

    hey guys.I’m kinda new to smarty. I’ve used it with some project, but that one didn’t have CI in it. Now, I’d like to ask where shall I put my .tpl files? inside the “views” folder? is it supposed to be named as “xxx.tpl” ???

    Another thing, this tutorial shows how to make a call to your smarty library, but doesn’t show what $data variable is? . I am used to just passing an array to a view file, and use the values of that as variables on the view file. But this time , since smarty is playing along, how do you suppose doing it using these methods discussed here? does that $data array contain an array ? if so, where do we put the values , or the output from that smarty function call?

    and last question, is “call_by_pass_reference” really needed to get CI and smarty going together? atleast for this method

  • #9 / Mar 02, 2008 11:17pm

    Avatar's avatar

    Avatar

    198 posts

    Nice. I like your class. While using it thus far I’ve found that changing the parse function calls second param to have a default value makes it even nicer.

    function parse($template, $data=’‘, $return = FALSE)

    notice I added =”” after data param.

    Thanks alot. It’s just what I was looking for.

  • #10 / Mar 04, 2008 2:14am

    Avatar's avatar

    Avatar

    198 posts

    I very much like this class. I use it with modular extensions. see reference below:

    http://ellislab.com/forums/viewthread/72580

    This way you can load module views in smarty templates to get a themed templated site which is also modulated. I would very much like to hear more on this solution. CI is the greatest framework I’ve ever found. My cousin works with prado, I’ve looked at it. but I don’t see it comparing with ci. maybe if combining the two would be even more effecting. You see this would be even nicer. because prado is php and asp.net combined. Just have a sys and a prado directory for your frameworks and mix and match the templates and multiple systems. also this maybe overdoing it a little much. 😊

  • #11 / Mar 05, 2008 2:24pm

    Avatar's avatar

    Avatar

    198 posts

    I’ve created a thread which utilizes this lib and the modular extensions lib along with it, located here:

    http://ellislab.com/forums/viewthread/73367/

  • #12 / Mar 06, 2008 4:04pm

    Avatar's avatar

    Avatar

    198 posts

    Just incase anyone has this problem with javascript in the templates you can add the below to your smarty_parser.php config file:

    $config['left_delimiter'] = '<!--{';
    $config['right_delimiter'] = '}-->';

    or use:

    {literal}javascript{/literal}
  • #13 / Mar 07, 2008 5:05pm

    Avatar's avatar

    Avatar

    198 posts

    added function to smarty_parser.php

    function template_exists($template)
        {
            if ($template == '')
            {
                return FALSE;
            }
            return parent::template_exists($template);
        }
  • #14 / Mar 10, 2008 11:18pm

    kenjis's avatar

    kenjis

    118 posts

    Hi!

    I’ve just made zip file of the code in this thread,
    and put it in WIKI for convenience.

    http://codeigniter.com/wiki/Smarty/

    Thank you for good Smarty integration code.

  • #15 / Jun 12, 2008 9:29am

    donpepito's avatar

    donpepito

    3 posts

    Hi!

    How can I disable caching?

    I set the

    $config['caching']

    variable to 0 in application/config/Smarty_parser.php.

    I also tried to set it in the controller:

    $this->smarty_parser->caching = 0;

    If I modify the

    $data["smarty_test"] = "smarty var test";

    variable, I don’t see the changes.

    —update—
    Smarty is ok now, but CI caches the data.

    $data["ci_var"] = "test msg";
    $this->smarty_parser->parse("ci:testpage.tpl", $data);

    I can’t see the changes.

    Thank you for your help!

.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases