在Smarty3中,从插件函数中调用由{function}标记定义的模板函数

Smarty {call} built-in function is able to call a template function defined by the {function} tag. Now, I need to call a template function but inside a plugin function because I only know the function name inside the plugin.

Plugin function:

<?php

$smarty->registerPlugin('function', 'form_label', 'renderFormLabel');

function renderFormLabel($form, \Smarty_Internal_Template $template) {

    // find out which function to call based on the available ones
    $function = lookupTemplateFunction($template);

    $args = $form->getVariables();

    // How to call the Smarty template function with the given $args?
    // $html = $template->smarty->???($args); 

    //return $html;
}

Template:

<form action="submit.php" method="post">
    {form_label}
    ....
</form>

This is an effort to support Symfony2 Forms in SmartyBundle. Each form fragment is represented by a Smarty function. To customize any part of how a form renders, the user just needs to override the appropriate function.

I should have been more specific in my first answer. The code for the renderFormLabel should look like this:

function renderFormLabel($form, \Smarty_Internal_Template $template) {

    // find out which function to call based on the available ones
    $function = lookupTemplateFunction($template);

    if ($template->caching) {
        Smarty_Internal_Function_Call_Handler::call ('test',$template,$form,$template->properties['nocache_hash'],false);
    } else {
        smarty_template_function_test($template,$form);
    }
}

In this case the attributes(paramter) passed to the renderFormLabel plugin by the $form array will be seen as local template variables inside the template function.

It's possible to call template functions from inside plugins. But we originally did plan for this option so currently the API is different if caching is enabled or not. This may change also in future releases.

Assume you want to do something similar to {call name=test world='hallo'} from within a plugin:

if ($template->caching) {
   Smarty_Internal_Function_Call_Handler::call ('test',$template,array('world'=>'hallo'),$template->properties['nocache_hash'],false);
} else {
   smarty_template_function_test($template,array('world'=>'hallo'));
}

Note that the template function is called in the context of the template which did call the plugin. All template variables known in the calling template are automatically know inside the template function.

The template functions do not return the HTML output, but put it directly into the output buffer.

As far as I can understand your need, you wish to call a named method with given known args.

Why not use a call_user_func_array call like :

call_user_func_array(array($template->smarty, $function), $args);