smarty-php / smarty

Smarty is a template engine for PHP, facilitating the separation of presentation (HTML/CSS) from application logic.
Other
2.25k stars 709 forks source link

Output filter on smarty v.5 doesn't running . #899

Closed Factify closed 1 year ago

wisskid commented 1 year ago

@Factify we could use a little bit more information. Maybe some sample code and the actual output vs expected output?

Factify commented 1 year ago

// load extension smarty class require_once('mySmarty.extension.php');

use \Smarty{Smarty, Template}; use Factify\Classes{Hook, RunStatic};

class mySmarty extends Smarty {

/** __construct **/
public function __construct() {
    parent::__construct();

    $this->compile_check = false; 
    $this->force_compile = false; 

    /* The Smarty delimiter tags { and } will be ignored so long as they are surrounded
    by white space. This behavior can be disabled by setting auto_literal to false. */
    $this->auto_literal = true;

    // set compile root
    $this->setCompileDir('compile_tpl');

    // set root tpl||components
    $tempDirs['FTL'] = 'template_dir_1'; 
    $tempDirs['STL'] = 'template_dir_2'; 
    $tempDirs['MTL'] = 'template_dir_3'; 

    // set cache root
    $this->cache_dir = 'cache_tpl'; 

    // set configs root array
    $this->setConfigDir('config_tpl');

    // set Template Dir array
    $this->setTemplateDir($tempDirs);

    // Prefilter Before Compiled
    $this->registerFilter('pre', [$this, 'runFilterPre']);

    // outputfilter asfter Compiled 
    $this->registerFilter('output', [$this, 'runFilterOutput']);

    //#TDOD Handling missing templates || OLD => $this->_smarty_include
    $this->registerDefaultTemplateHandler([$this, 'handleMissingTemplate']);

    // add Extension
    $this->addExtension(new mySmartyExtension($this));

    // testInstall 
    //if(true === SD_DEBUG) $this->testInstall();
}

/*** Get Smarty object ***
* --> @return Smarty **/
//public function getSmarty() { return $this; }

public function ifExistRegistered($type = null, $name = null) {
    return (($type && $name) && isset($this->registered_plugins[$type][$name]));
}

public function handleMissingTemplate($type, $name, &$content, &$modified, Smarty $smarty) {        
    // return blank tpl
    return SD_TPL_ROOT_G . 'blank.tpl';
}

public function repFileName($name_file = '') {
    if(str_contains($name_file, ':')){
        if (($pos = strpos($name_file, ']')) !== false) $name_file = substr($name_file, $pos+1);
        if (($pos = strpos($name_file, ':')) !== false) $name_file = substr($name_file, $pos+1);
    }
    return $name_file;
}

/** ## Prefilter Before Compiled smarty output
 * @param string compiled content
 * --> @return string - transformed content **/
public function runFilterPre($tpl_output, Template $_template) {
    $file_dir = $_template->template_resource;
    if(!str_ends_with($file_dir, '.tpl')) return $tpl_output;

    //Remove HTML Comments
    $tpl_output = preg_replace('/<!--(.|\s)*?-->/', '', $tpl_output);

    $name_file = $this->repFileName($file_dir);
    Hook::load('smartyPreFetchHook', $tpl_output, $name_file);

    //@todo 
    $tpl_output = str_replace('xajax_', _PERFIX_REACT, $tpl_output);

    return $tpl_output;
}

/** ## transforms compiled smarty output
 * @param string compiled content
 * --> @return string - transformed content **/
public function runFilterOutput($tpl_output, Template $_template) {
    $file_dir = $_template->template_resource;
    if(!str_ends_with($file_dir, '.tpl')) return $tpl_output;

    $name_file = $this->repFileName($file_dir);
    echo ' <br>runFilterOutput name: ' . $name_file; // only for test
    Hook::load('smartyFetchHook', $tpl_output, $name_file);

    // static data class parser
    $tpl_output = RunStatic::collectJSDynamicCode($tpl_output, $name_file);         

    return $tpl_output;
}

}

// my mySmartyExtension file // use Smarty\Extension\Base;

class mySmartyExtension extends Base {

/** __construct **/
public function __construct() {}

public function getModifierCallback(string $modifierName) {
    if(is_callable($modifierName)) return $modifierName;
    //#|TODO if(isset($this->functionCallback[$modifierName])) return $this->functionCallback[$modifierName];

    switch ($modifierName) {
        // #TODO
    }
    //if(is_callable($modifierName)) return $modifierName;
    return null;
}

}

wisskid commented 1 year ago

@Factify found it, thanks for your bug report!

Factify commented 1 year ago

@wisskid I have tested, working only in fetch not on index.

wisskid commented 1 year ago

Do you mean $smarty->display()?

Factify commented 1 year ago

@wisskid yes display.

wisskid commented 1 year ago

There should be no difference between the two. Except maybe for already cached output. Can you try to empty your caches?

Factify commented 1 year ago

@wisskid I don't used the cache.

wisskid commented 1 year ago

Strange. I've tested (and just retested) it using both $smarty->display('issue899.tpl'); and echo $smarty->fetch('issue899.tpl');. Result is the same, output filter is running perfectly. Please check if the error isn't in your own code, e.g. in the if(!str_ends_with($file_dir, '.tpl')) return $tpl_output; part.

If you're sure it's in Smarty, please provide a clear reproduction scenario. This issue is a great example on how to provide a reproduction scenario that will help us find the problem.

Factify commented 1 year ago

'public function runFilterOutput($tpl_output, Template $_template) { $file_dir = $_template->template_resource; if(!str_ends_with($file_dir, '.tpl')) return $tpl_output;

echo ' <br>runFilterOutput name: ' . $file_dir; // only for test    

return $tpl_output;

}'

Factify commented 1 year ago

@wisskid Now in my project I have smarty version 4.3.2 .output filter is OK.