Search code examples
phpsmarty

The Smarty template shows two time the function result


I have a smarty project:

see the test.php:

<?php

require($_SERVER['DOCUMENT_ROOT'] . '/smartyHeader.php');

function test1($args){
    $str="test1";

    return $str;
}

$smarty->registerPlugin('block' ,'hsp', 'test1');

$smarty->display('php/test.tpl');

its test.tpl:

<html>
    <head>
        <title> Ho </title>
    </head>
    <body>

        {hsp times="1"}{/hsp}

    </body>
</html>

you see I only invoke the hsp function one time.

but the browser shows two times result:

enter image description here


edit-01

the smartyHeader.php is just create the smarty instance:

<?php

require_once($_SERVER['DOCUMENT_ROOT'] . '/libs/Smarty.class.php');

$smarty = new Smarty();
$smarty->caching = true;
$smarty->cache_lifetime = 120;
$smarty->template_dir = $_SERVER['DOCUMENT_ROOT'].'/templates';
$smarty->compile_dir = $_SERVER['DOCUMENT_ROOT'].'/templates_c';

Solution

  • Try this variation on your function

    function test1($params, $content)
    {
      if( $content !== null )
      {
        $str="test1";
        return $str;
      }
    }
    

    or

    function test1($params, $content, &$smarty, &$repeat)
    {
      if( $repeat === false )
      {
        $str="test1";
        return $str;
      }
    }
    

    Your custom function is called twice by smarty, once at the start of the block and again at the closing tag of the block, you can test if $content === null (must be explicitly null) or $repeat === false.

    https://www.smarty.net/docsv2/en/plugins.block.functions.tpl

    By default your function implementation is called twice by Smarty: once for the opening tag, and once for the closing tag. (See $repeat below on how to change this.)

    The value of the $content variable depends on whether your function is called for the opening or closing tag. In case of the opening tag, it will be NULL, and in case of the closing tag it will be the contents of the template block. Note that the template block will have already been processed by Smarty, so all you will receive is the template output, not the template source.

    and

    The parameter $repeat is passed by reference to the function implementation and provides a possibility for it to control how many times the block is displayed. By default $repeat is TRUE at the first call of the block-function (the opening tag) and FALSE on all subsequent calls to the block function (the block's closing tag). Each time the function implementation returns with $repeat being TRUE, the contents between {func}...{/func} are evaluated and the function implementation is called again with the new block contents in the parameter $content.