smarty-php / smarty

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

Smarty registerPlugin #911

Closed KarelWintersky closed 10 months ago

KarelWintersky commented 11 months ago

If you do it like this:

$smarty->registerPlugin('function', 'sum', function($params) {
    return ($params['a'] ?? 0) + ($params['b'] ?? 0);
});

and

{sum a=11 b=14}

works correct.

If you try to define a function directly, with a list of arguments:

$smarty->registerPlugin('function', 'sum', function($a = 0, $b = 0) {
    return $a + $b;
});

and

{sum a=11 b=14}

throws FATAL Error like this:

PHP Notice:  Object of class Smarty_Internal_Template could not be converted to number in index.php on line 179
PHP Fatal error:  Uncaught Error: Unsupported operand types in index.php:179
Stack trace:
#0 /var/www/AJUR.Template/tests/cache/5bbb9d0fded84af2ca4c00d28db53a60895fefa4_0.file.test_sum.tpl.php(26): AJUR\TemplatePlugins::add1()
#1 /var/www/AJUR.Template/vendor/smarty/smarty/libs/sysplugins/smarty_template_resource_base.php(123): content_651d48a1e2fdd3_52213244()
#2 /var/www/AJUR.Template/vendor/smarty/smarty/libs/sysplugins/smarty_template_compiled.php(114): Smarty_Template_Resource_Base->getRenderedTemplateCode()
#3 /var/www/AJUR.Template/vendor/smarty/smarty/libs/sysplugins/smarty_internal_template.php(217): Smarty_Template_Compiled->render()
#4 /var/www/AJUR.Template/vendor/smarty/smarty/libs/sysplugins/smarty_internal_templatebase.php(238): Smarty_Internal_Template->render()
#5 /var/www/AJUR.Template/vendor/smarty/smarty/libs/sysplugins/smarty_internal_templatebase.php(116): Smarty_Internal_TemplateBase->_execute()
#6 /var/www/AJUR.Template/src/Template.php(232): Smarty_Internal_Template in index.php on line 179

The fact is that in the definition of a “modifier” type plugin, both definitions are possible:

registerPlugin('modifier', 'size_format', function size_format(int $size, int $decimals = 0, string $decimal_separator = '.', string $thousands_separator = ','):string
    {
        $units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
        $index = min(floor((strlen(strval($size)) - 1) / 3), count($units) - 1);
        $number = number_format($size / pow(1000, $index), $decimals, $decimal_separator, $thousands_separator);
        return sprintf('%s %s', $number, $units[$index]);
    }

// use later in template:
{$size|size_format:3:','}

and

registerPlugin('modifier', 'size_format', function sf(int $size, array $params):string
    {
        $units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
        $decimals = $params['decimals'] ?? 3;
        $decimal_separator = $params['decimal_separator'] ?? '.';
        $thousands_separator = $params['thousands_separator'] ?? ',';

        $index = min(floor((strlen(strval($size)) - 1) / 3), count($units) - 1);
        $number = number_format($size / pow(1000, $index), $decimals, $decimal_separator, $thousands_separator);
        return sprintf('%s %s', $number, $units[$index]);
    }
// use later:
{$size|size_format:[3,',','-']}

Is this a systemic limitation of the template engine and is impossible in principle, or am I doing something wrong?

KarelWintersky commented 11 months ago

Smarty 4.3

wisskid commented 10 months ago

Please see the documentation on writing plugins. Your plugin handler should accept an array of $params and a Smarty_Internal_Template $template. modifiers do not get passed the Smarty_Internal_Template object.

KarelWintersky commented 10 months ago

Why

registerPlugin('modifier', 'size_format', function size_format(int $size, int $decimals = 0, string $decimal_separator = '.', string $thousands_separator = ','):string

is possible too ?

wisskid commented 10 months ago

Modifier plugins are a little different: modifiers do not get passed the Smarty_Internal_Template object.