Development

Changeset 14409 for plugins/sfSmartyPlugin/trunk

You must first sign up to be able to contribute.

Show
Ignore:
Timestamp:
01/01/09 02:12:27 (4 years ago)
Author:
insaini
Message:

Updated compiler process and optimized parsing methods. Updated documentation.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • plugins/sfSmartyPlugin/trunk/LICENSE

    r11464 r14409  
    11Copyright (c) 2006 Georg Gell 
     2Copyright (c) 2008 Jesse Badwal 
    23 
    3 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 
     4Permission is hereby granted, free of charge, to any person obtaining a copy 
     5of this software and associated documentation files (the "Software"), to deal 
     6in the Software without restriction, including without limitation the rights 
     7to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
     8copies of the Software, and to permit persons to whom the Software is furnished 
     9to do so, subject to the following conditions: 
    410 
    5 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 
     11The above copyright notice and this permission notice shall be included in all 
     12copies or substantial portions of the Software. 
    613 
    7 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
     14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
     15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
     16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
     17AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
     18LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
     19OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
     20THE SOFTWARE. 
  • plugins/sfSmartyPlugin/trunk/README

    r14326 r14409  
    126126Refer to the Smarty documentation.  
    127127 
     128### Symfony Helpers ### 
    128129The Javascript helper tag is also available and must be used as such: 
    129130 
     
    142143The {use} tag does not accept an array of values currently. 
    143144 
     145All other helpers are used as compiler methods in Smarty. That is you would use the function name after the opening brace. 
     146  {include_component moduleName='default' componentName'test'} 
     147 
     148As well all symfony helper methods are also modifiers meaning they can be used within compiler function calls like so 
     149  {url_for internal_uri="foo/bar"|cat:"?command=new"} 
     150This will concatenate 'command=new' to 'foo/bar' and of course the modifier can be a variable. 
     151 
     152Another example would be link_to with an image: 
     153  {link_to name="foo_icon.gif"|image_tag routeName='@foobar'} 
     154And if you need image_tag to take additional parameters 
     155  {link_to name="foo_icon.gif"|image_tag:par2:par3 routeName='@foobar'} 
     156where par1 to image_tag is of course "foo_icon.gif" 
     157 
     158### Symfony Actions ### 
    144159Smarty can also be utilized within actions via static calls. In an action: 
    145160 
     
    149164$foobar will then be available as an object reference in your template. 
    150165 
     166 
    151167## Final Notes ## 
    152168 
    153 I have tried to optimize certain methods and have cleaned up some from the last 0.12 release. 
     169The sfSmartyPlugin has been improved considerably over the last couple weeks and there is still further improvements that can be made. 
     170Specifically the compiler method should also compile modifier scripts if they are not smarty internal modifiers. Currently the modifiers will run through Smarty which adds extra overhead and is not necessary. 
    154171 
    155172Helpers that are used are cached and will also be loaded from the cache after that. Smarty also compiles the templates and once compiled are always loaded until modified. 
  • plugins/sfSmartyPlugin/trunk/lib/helper/AppUrlHelper.php

    r14325 r14409  
    22use_helper('Url'); 
    33/** 
    4 * link_to with additionnal param : $app 
    5 
    6 * @param string name of the link, i.e. string to appear between the <a> tags 
    7 * @param string 'module/action' or '@rule' of the action 
    8 * @param array additional HTML compliant <a> tag parameters 
    9 * @param string name of the application 
    10 * @return string XHTML compliant <a href> tag 
    11 */ 
     4 * Link between applications 
     5 * 
     6 * @param string $app name of application 
     7 * @param strubg $name name of hte link, i.e. string to appear between <a> tags 
     8 * @param string $internal_uri 'module/action' or '@route' of the action 
     9 * @param array $options additional HTML compliant <a> tag parameters 
     10 * @param boolean $subdomain if linking to another subdomain or to a folder under the current domain 
     11 * @param string $path path of the folder, if linking to a folder under the current domain 
     12 * @return string 
     13 */ 
    1214function link_to_app($app, $name = '', $internal_uri = '', $options = array(), $subdomain = true, $path = '/') { 
    1315  $current_app = sfConfig::get('sf_app'); 
  • plugins/sfSmartyPlugin/trunk/lib/sfSmarty.class.php

    r14325 r14409  
    11<?php 
     2/* 
     3 * This file is part of the sfSmarty Plugin 
     4 * (c) 2008 Jesse Badwal <jesse@insaini.com> 
     5 * 
     6 * For the full copyright and license information, please view the LICENSE 
     7 * file that was distributed with this source code. 
     8 */ 
     9 
    210/** 
    311 * sfSmarty 
    412 * 
    5  * @package 
    6  * @author jbadwal 
    7  * @copyright Copyright (c) 2008 
    8  * @version $Id$ 
    9  * @access public 
     13 * @package sfSmartyPlugin 
     14 * @subpackage lib 
     15 * @author Jesse Badwal <jesse@insaini.com> 
     16 * @version SVN: $Id: sfSmarty.class.php 11783 2008-09-25 16:21:27Z insaini $ 
    1017 **/ 
    1118class sfSmarty { 
     
    103110     
    104111    /** 
    105      * Escapes smarty stored vars and stores in sf_data 
    106      * // TODO: Optimize.. Data is often escaped multiple times 
     112     * Escapes smarty stored vars for sfData 
    107113     * 
    108114     * @param sfSmartyView $view 
     
    113119    { 
    114120      $current_sf_data = self::$smarty->get_template_vars('sf_data'); 
    115     if (!empty($current_sf_data) && $view->getAttributeHolder()->get('sf_type') == 'partial') { 
     121    if (!empty($current_sf_data) && $view->getAttribute('sf_type') == 'partial') { 
    116122      if (isset($current_sf_data['sf_content'])) { 
    117123        $view->getAttributeHolder()->set('sf_content',$current_sf_data['sf_content']); 
     
    137143    $sf_user = $sf_context->getUser(); 
    138144     
    139     self::$smarty->compile_id = $view->getModuleName(); 
     145    if ($view->getAttribute('sf_type') == 'layout') { 
     146      self::$smarty->compile_id = $view->getDecoratorTemplate();         
     147    } else { 
     148      self::$smarty->compile_id = $view->getModuleName(); 
     149    } 
    140150     
    141151    $this->loadCoreAndStandardHelpers(); 
     
    150160        self::$smarty->assign_by_ref($key, $value); 
    151161      } 
    152       //self::$smarty->assign($view->getAttributeHolder()->getAll()); 
    153162    }  
    154163     
     
    183192    $helpers = array_unique(array_merge($core_helpers, $standard_helpers)); 
    184193    foreach ($helpers as $helperName) { 
    185       if (!isset(self::$loadedHelpers[$helperName])) { 
    186         $this->loadHelper($helperName); 
    187       } 
     194      $this->loadHelper($helperName); 
    188195    } 
    189196    $smarty_helpers = sfConfig::get('sf_smarty_helpers'); 
     
    200207  protected function loadHelper($helperName) 
    201208  { 
    202     if (!self::$cache->has($helperName)) { 
    203       static $dirs; 
    204       if (!is_array($dirs)) {  
    205         $dirs = sfProjectConfiguration::getActive()->getHelperDirs(/*$moduleName*/); 
     209    if (!isset(self::$loadedHelpers[$helperName])) { 
     210      if (!self::$cache->has($helperName)) { 
     211        static $dirs; 
     212        if (!is_array($dirs)) {  
     213          $dirs = sfProjectConfiguration::getActive()->getHelperDirs(/*$moduleName*/); 
     214        } 
     215         
     216        $fileName = $helperName . 'Helper.php'; 
     217        $path = ''; 
     218        foreach($dirs as $dir) { 
     219          if (is_readable($dir . DIRECTORY_SEPARATOR . $fileName)) { 
     220            $path = $dir . DIRECTORY_SEPARATOR . $fileName; 
     221              self::$cache->set($helperName, self::parseHelper($helperName, $path)); 
     222            break; 
     223          } 
     224        } 
    206225      } 
    207226       
    208       $fileName = $helperName . 'Helper.php'; 
    209       $path = ''; 
    210       foreach($dirs as $dir) { 
    211         if (is_readable($dir . DIRECTORY_SEPARATOR . $fileName)) { 
    212           $path = $dir . DIRECTORY_SEPARATOR . $fileName; 
    213             self::$cache->set($helperName, self::parseFile($path)); 
    214           break; 
    215         } 
    216       } 
    217     } 
    218     eval(self::$cache->get($helperName)); 
    219     self::$loadedHelpers[$helperName] = true; 
     227      eval(self::$cache->get($helperName)); 
     228      self::$loadedHelpers[$helperName] = true; 
     229    } 
    220230  } 
    221231   
    222  
    223   /** 
    224    * sfSmarty::parseFile() 
    225    * 
    226    * @param mixed $path 
    227    * @return 
    228    **/ 
    229   protected static function parseFile($path) 
    230   { 
    231     if (self::$log) self::$log->info('{sfSmarty} parsing file: ' . $path . ' into the Smarty helper cache');           
    232     //$code = '<?php '; 
     232  protected static function parseHelper($helperName, $path) 
     233  { 
     234    if (self::$log) self::$log->info('{sfSmarty} parsing helper: ' . $path . ' into the Smarty helper cache');           
    233235    $code = ''; 
    234236    $lines = file($path); 
     
    249251        } 
    250252        $code .= ";\nself::registerCompilerFunction('$name', array(\$this, '{$name}_CompilerFunction'));"; 
     253        $code .= ";\nself::registerModifier('$name', array(\$this, '{$name}_Modifier'));";         
    251254      } 
    252255    } 
     
    258261   * 
    259262   * @param mixed $argumentString 
    260    * @param boolean $smarty 
    261    * @return 
    262    **/ 
    263   protected static function parseArguments($argumentString, $smarty = false) 
    264   { 
    265     $argumentString .= $smarty ? ' ' : ','; 
    266     $inDoubleQuotes = false; 
    267     $inSingleQuotes = false; 
     263   * @return array 
     264   **/ 
     265  protected static function parseArguments($argumentString) 
     266  { 
     267    $ex_arg_str = explode(',',$argumentString); 
     268     
    268269    $args = array(); 
    269     $argumentName = ''; 
    270     $defaultValue = ''; 
    271     $parsingDefaultValue = false; 
    272     $inArray = 0; 
    273     for ($i = 0; $i < strlen($argumentString); $i++) { 
    274       $letter = $argumentString{$i}; 
    275       if (!$smarty && !$inDoubleQuotes && !$inSingleQuotes && ($letter == ' ' || $letter == ' ')) { 
     270    foreach ($ex_arg_str as &$ex_arg) { 
     271      $par = explode('=',$ex_arg); 
     272      $key = trim($par[0]); 
     273      if (count($par) === 1) { 
     274        $args[$key] = array();   
    276275        continue; 
    277276      } 
    278       if (!$parsingDefaultValue) { 
    279         if (preg_match('/\\w/', $letter) || $letter == '$' || $letter == '>') { 
    280           $argumentName .= $letter; 
    281         } elseif ($letter == '=') { 
    282           $parsingDefaultValue = true; 
    283         } elseif ((!$smarty && $letter == ',') || ($letter == ' ' || $letter == ' ')) { 
    284           $args[$argumentName] = array(); 
    285           $argumentName = ''; 
    286         } elseif ($letter == '&') { 
    287         } else { 
    288           print_r($args); 
    289           die("$inDoubleQuotes/$inSingleQuotes/$argumentName/$defaultValue/$parsingDefaultValue/'$letter'\n$argumentString\nI wonder..."); 
    290         } 
    291       } else { 
    292         switch ($letter) { 
    293           case '(': 
    294             if (!$inSingleQuotes && !$inDoubleQuotes) { 
    295               $inArray++; 
    296               if (self::$templateSecurity && strcasecmp(substr($defaultValue, -5), 'array')) { 
    297                 throw new Exception('sfSmartyView: You may not use PHP functions in a template! "' . $defaultValue . '"'); 
    298               } 
    299             } 
    300             $defaultValue .= $letter; 
    301             break; 
    302           case ')': 
    303             if (!$inSingleQuotes && !$inDoubleQuotes) { 
    304               $inArray--; 
    305             } 
    306             $defaultValue .= $letter; 
    307             break; 
    308           case ',': 
    309             if ($inSingleQuotes || $inDoubleQuotes || $inArray) { 
    310               $defaultValue .= $letter; 
    311             } elseif (!$smarty) { 
    312               $parsingDefaultValue = false; 
    313               $args[$argumentName] = array('default' => $defaultValue); 
    314               $argumentName = ''; 
    315               $defaultValue = ''; 
    316             } 
    317             break; 
    318           case '"': 
    319             if (!$inSingleQuotes) { 
    320               $inDoubleQuotes ^= true; 
    321             } 
    322             $defaultValue .= $letter; 
    323             break; 
    324           case "'": 
    325             if (!$inDoubleQuotes) { 
    326               $inSingleQuotes ^= true; 
    327             } 
    328             $defaultValue .= $letter; 
    329             break; 
    330           case ' ': 
    331           case '  ': 
    332             if (!($inSingleQuotes || $inDoubleQuotes || $inArray)) { 
    333               $parsingDefaultValue = false; 
    334               $args[$argumentName] = preg_replace('/\\$(\\w+)/', '$this->_tpl_vars[\'$1\']', $defaultValue); 
    335               $argumentName = ''; 
    336               $defaultValue = ''; 
    337             } else { 
    338               $defaultValue .= $letter; 
    339             } 
    340             break; 
    341           default: 
    342             $defaultValue .= $letter; 
    343         } // switch 
    344       } 
    345     } 
    346     if (isset($args[''])) { 
    347       unset($args['']); 
     277       
     278      $val = trim($par[1]); 
     279      $args[$key] = array('default' => $val); 
    348280    } 
    349281    return $args; 
     
    377309  { 
    378310    $helpers = ''; 
    379     foreach(self::$loadedHelpers as $helper => $dummy) { 
    380       $helpers .= "use_helper('$helper');"; 
    381     } 
    382     if ($helpers) { 
     311    if (count(self::$loadedHelpers)) { 
     312      $helpers .= "use_helper('".implode("','",array_keys(self::$loadedHelpers))."');"; 
    383313      $helpers = "<?php $helpers ?>"; 
    384314    } 
    385315    return $helpers . $content; 
    386   } 
    387    
    388   /** 
    389    * sfSmarty::__call() 
    390    * generic compiler function for all new tags 
    391    * 
    392    * @param mixed $functionName 
    393    * @param mixed $argsArray 
    394    * @return 
    395    **/ 
    396   public function __call($functionName, $argsArray) 
    397   { 
    398     if (!trim($argsArray[0])) { 
    399       $args = array(); 
    400     } else { 
    401       $args = $this->parseArguments($argsArray[0], true); 
    402     } 
    403     $functionName = str_replace('_CompilerFunction', '', $functionName); 
    404     $argsOrder = $allArgs = (array)self::$knownFunctions[$functionName]; 
    405     $helperWithVarArgs = count($allArgs) == 0; 
    406     $cacheArgs = array(); 
    407     foreach($args as $name => $value) { 
    408       $name = '$' . trim($name); 
    409       $value = trim($value); 
    410       if (!isset($allArgs[$name]) && !$helperWithVarArgs) { 
    411         throw new Exception('sfSmartyView: Cannot compile template. Unknown field found: "' . substr($name, 1) . '" near tag ' . $functionName); 
    412       } 
    413       $cacheArgs[$name] = $value; 
    414       unset($allArgs[$name]); 
    415     } 
    416     foreach($allArgs as $name => $default) { 
    417       if (!isset($default['default'])) { 
    418         throw new Exception('sfSmartyView: Cannot compile template. Required field "' . substr($name, 1) . '" not found near tag ' . $functionName); 
    419       } 
    420       $cacheArgs[$name] = $default['default']; 
    421     } 
    422     $code = ''; 
    423     if (!$helperWithVarArgs) { 
    424       foreach($argsOrder as $name => $value) { 
    425         $code .= $code?',':''; 
    426         if (is_bool($value)) { 
    427           $code .= $cacheArgs[$name]?'true':'false'; 
    428         } else { 
    429           $code .= $cacheArgs[$name]; 
    430         } 
    431       } 
    432     } else { 
    433       foreach($cacheArgs as $name => $value) { 
    434         $code .= $code?',':''; 
    435         if (is_bool($value)) { 
    436           $code .= $value?'true':'false'; 
    437         } else { 
    438           $code .= $value; 
    439         } 
    440       } 
    441     } 
    442     $code = "echo $functionName($code);\n"; 
    443     return $code; 
    444316  } 
    445317 
     
    498370  { 
    499371    self::$smarty->register_modifier($tag, $function); 
    500   }     
     372  }    
     373 
     374  /** 
     375   * sfSmarty::__call() 
     376   * generic compiler function for all new tags 
     377   * 
     378   * @param mixed $functionName 
     379   * @param mixed $argsArray 
     380   * @return 
     381   **/ 
     382  public function __call($functionName, $argsArray) 
     383  {    
     384    $return = ''; 
     385    if (strpos($functionName, '_Modifier') !== FALSE) { 
     386      $return = call_user_func_array(str_replace('_Modifier', '', $functionName), $argsArray); 
     387    } else if (strpos($functionName, '_CompilerFunction') !== FALSE) { 
     388      if (!trim($argsArray[0]) || !is_object($argsArray[1])) { 
     389        $args = array(); 
     390      } else { 
     391        $args = $argsArray[1]->_parse_attrs($argsArray[0]);  
     392      } 
     393      $return = $this->_processCompilerFunction(str_replace('_CompilerFunction', '', $functionName), $args); 
     394    } 
     395    return $return;    
     396  } 
     397     
     398  /** 
     399   * sfSmarty::_processCompilerFunction() 
     400   * 
     401   * @param string $functionName 
     402   * @param array $args 
     403   * @return string 
     404   */ 
     405  private function _processCompilerFunction($functionName, $args)  
     406  { 
     407    $argsOrder = $allArgs = (array)self::$knownFunctions[$functionName]; 
     408    $helperWithVarArgs = count($allArgs) == 0; 
     409    $cacheArgs = array(); 
     410    foreach($args as $name => $value) { 
     411      $name = '$' . trim($name); 
     412      $value = trim($value); 
     413      if (!isset($allArgs[$name]) && !$helperWithVarArgs) { 
     414        throw new Exception('sfSmartyView: Cannot compile template. Unknown field found: "' . substr($name, 1) . '" near tag ' . $functionName); 
     415      } 
     416      $cacheArgs[$name] = $value; 
     417      unset($allArgs[$name]); 
     418    } 
     419    foreach($allArgs as $name => $default) { 
     420      if (!isset($default['default'])) { 
     421        throw new Exception('sfSmartyView: Cannot compile template. Required field "' . substr($name, 1) . '" not found near tag ' . $functionName); 
     422      } 
     423      $cacheArgs[$name] = $default['default']; 
     424    } 
     425    $code = ''; 
     426    if (!$helperWithVarArgs) { 
     427      foreach($argsOrder as $name => $value) { 
     428        $code .= $code ? ',' : ''; 
     429        if (is_bool($value)) { 
     430          $code .= $cacheArgs[$name]?'true':'false'; 
     431        } else { 
     432          $code .= $cacheArgs[$name]; 
     433        } 
     434      } 
     435    } else { 
     436      $code .= implode(',',array_values($cacheArgs)); 
     437    } 
     438    return "echo $functionName($code);";     
     439  } 
    501440} 
  • plugins/sfSmartyPlugin/trunk/lib/sfSmartyView.class.php

    r14325 r14409  
    11<?php 
     2/* 
     3 * This file is part of the sfSmarty Plugin 
     4 * (c) 2008 Jesse Badwal <jesse@insaini.com> 
     5 * 
     6 * For the full copyright and license information, please view the LICENSE 
     7 * file that was distributed with this source code. 
     8 */ 
     9 
    210/** 
    311 * sfSmartyView 
    412 * 
    5  * @package 
    6  * @author georg 
    7  * @copyright Copyright (c) 2008 
    8  * @version $Id$ 
    9  * @access public 
     13 * @package sfSmartyPlugin 
     14 * @subpackage lib 
     15 * @author Jesse Badwal <jesse@insaini.com> 
     16 * @version SVN: $Id: sfSmartyView.class.php 11783 2008-09-25 16:21:27Z insaini $ 
    1017 **/ 
    1118class sfSmartyView extends sfPHPView { 
    1219 
     20  /** 
     21   * SfSmarty Instance 
     22   * 
     23   * @var sfSmarty 
     24   */ 
    1325  protected static $smarty = null; 
    1426   
     
    3749  /** 
    3850   * sfSmartyView::getEngine() 
    39    * returns the smarty instance 
     51   * returns the sfSmarty instance 
    4052   * 
    41    * @return smarty instance 
     53   * @return sfSmarty instance 
    4254   */ 
    4355  public function getEngine() 
     
    5062   * 
    5163   * Does some logic to allow the use of both 
    52    * .php and @$this->template_extension files as action view
     64   * .php and smarty template file
    5365   * 
    5466   * @see sfView::preRenderCheck() 
     
    6274      $this->setTemplate(str_replace($this->getExtension(), '.php', $this->getTemplate())); 
    6375      $this->setExtension('.php'); 
    64       parent::configure();    
     76      //parent::configure(); 
    6577      parent::preRenderCheck(); 
    6678    } 
     
    7688   **/ 
    7789  protected function renderFile($file) 
    78   { 
    79     if (sfConfig::get('sf_logging_enabled')) { 
    80       $this->dispatcher->notify(new sfEvent($this, 'application.log', array('{sfSmartyView} renderFile '.$file))); 
    81     } 
    82      
     90  {  
    8391    if ($this->getExtension() == '.php' && $this->getAttribute('sf_type') != 'layout') { 
    8492      return parent::renderFile($file); 
    8593    } 
    8694     
     95    if (sfConfig::get('sf_logging_enabled')) { 
     96      $this->dispatcher->notify(new sfEvent($this, 'application.log', array('{sfSmartyView} renderFile '.$file))); 
     97    } 
    8798    return $this->getEngine()->renderFile($this, $file); 
    8899  } 
  • plugins/sfSmartyPlugin/trunk/package.xml

    r14326 r14409  
    1111  <active>yes</active> 
    1212 </lead> 
    13  <date>2008-12-25</date> 
    14  <time>06:34:35</time> 
     13 <date>2008-12-31</date> 
     14 <time>17:34:35</time> 
    1515 <version> 
    16   <release>0.2.3</release> 
     16  <release>0.3.0</release> 
    1717  <api>1.0.0</api> 
    1818 </version> 
     
    6868      <release> 
    6969        <version> 
    70           <release>0.2.3</release> 
     70          <release>0.3.0</release> 
    7171          <api>1.0.0</api> 
    7272        </version> 
     
    7878          MIT license 
    7979        </license> 
    80         <date>2008-12-25</date> 
     80        <date>2008-12-31</date> 
    8181        <license>MIT</license> 
    8282        <notes> 
    83            * insaini: - Updated link_to_app helper method for correct behaviour between environments 
    84 - Updated sfSmarty to assign_by_ref all values from the view 
    85 - Updated sfSmarty to correctly select the renderer for the layout. 
     83           * insaini: - Updated sfSmartyView compilation process and modifier support. 
    8684        </notes> 
    8785      </release>