I'm working on a plugin where the user can build a form and then display that form on the front end using a shortcode name of their choice.
In the database I have a list of form names, and the necessary data to render them, but I can't figure out how to dynamically register the shortcode function.
Below is some psudeo code that shows what I want to do. In it I query my database and pull out an object which contains the name of the form and a some json strings which I can parse and use to call a premade function with parameters:
foreach ($dbQuery as $row){
function $row->formName(){ // I know I can't do this
$internalFunction = json_decode($row->json)->internalFunctionName; // dynamically refrence predefined function
$internalFunction(json_decode($row->json)->params); // call the function defined above
// do other things with the string from the database
}
add_shortcode( $row->formName, $row->formName );
}
I looked up if php supports dynamic function names, and I found this SO post which says it only supports dynamic closures. I tried using them but wordpress throws an error saying the shortcode doesn't have a proper callback function. So I think it wants a real function.
I also found a similar question on this site, but didn't see how this would let me define my own code in the function.
Any help would be much appreciated!
I'm working on a plugin where the user can build a form and then display that form on the front end using a shortcode name of their choice.
In the database I have a list of form names, and the necessary data to render them, but I can't figure out how to dynamically register the shortcode function.
Below is some psudeo code that shows what I want to do. In it I query my database and pull out an object which contains the name of the form and a some json strings which I can parse and use to call a premade function with parameters:
foreach ($dbQuery as $row){
function $row->formName(){ // I know I can't do this
$internalFunction = json_decode($row->json)->internalFunctionName; // dynamically refrence predefined function
$internalFunction(json_decode($row->json)->params); // call the function defined above
// do other things with the string from the database
}
add_shortcode( $row->formName, $row->formName );
}
I looked up if php supports dynamic function names, and I found this SO post which says it only supports dynamic closures. I tried using them but wordpress throws an error saying the shortcode doesn't have a proper callback function. So I think it wants a real function.
I also found a similar question on this site, but didn't see how this would let me define my own code in the function.
Any help would be much appreciated!
Assuming the $row->internalFunction
is a function, or the name of a function which already exists, then you can do something like so:
foreach ( $dbQuery as $row ) {
add_shortcode( $row->formName, $row->internalFunction );
}
So if the formName
(shortcode tag) is foo
and internalFunction
is foo_func
, then [foo]
will be handled by the foo_func()
function:
// The standard/non-dynamic way.
function foo_func( $atts = array() ) {
return 'something good..';
}
add_shortcode( 'foo', 'foo_func' );
See the Codex for further details/guide.
Or here's an example of using closure:
foreach ( $dbQuery as $row ) {
$func = $row->internalFunction;
add_shortcode( $row->formName, function ( $atts = array() ) use ( $func ){
return $func( $atts );
} );
}
Or did I misunderstand your concept?
is there a way I can pass parameters into the internal function
Yes, you can pass custom parameters to the internal function (internalFunction
); but you'll do it via the closure:
foreach ( $dbQuery as $row ) {
$func = $row->internalFunction;
$params = json_decode( $row->json )->params;
add_shortcode( $row->formName, function ( $atts = array() ) use ( $func, $params ){
return $func( $params );
} );
}
Basically, use the use
keyword to make variables in the foreach
scope be available in the closure.
And you could even pass the entire $row
object..
foreach ( $dbQuery as $row ) {
add_shortcode( $row->formName, function ( $atts = array() ) use ( $row ){
$func = $row->internalFunction;
// Here you can pass $row->formName to the function.
return $func( json_decode( $row->json )->params );
} );
}