can I do something like that? to pass arguments to my function? I already studied add_action doc but did not figure out how to do it. What the exact syntax to pass two arguments would look like. In particular how to pass text & integer arguments.
function recent_post_by_author($author,$number_of_posts) { some commands; } add_action('thesis_hook_before_post','recent_post_by_author',10,'author,2')
UPDATE
it seems to me that it is done somehow through do_action but how? :-)
Passing arguments to function is a very important aspect of C++ programming. Arguments refer to values that can be passed to a function. Furthermore, this passing of arguments takes place for the purpose of being used as input information.
The call by value method of passing arguments to a function copies the actual value of an argument into the formal parameter of the function. In this case, changes made to the parameter inside the function have no effect on the argument. By default, C programming uses call by value to pass arguments.
Arguments are passed by value; that is, when a function is called, the parameter receives a copy of the argument's value, not its address. This rule applies to all scalar values, structures, and unions passed as arguments. Modifying a parameter does not modify the corresponding argument passed by the function call.
In other words, if an apply_filters() call passes four total arguments, callbacks bound to it can accept none (the same as 1) of the arguments or up to four.
can I do something like that? to pass arguments to my function?
Yes you can! The trick really is in what type of function you pass to add_action and what you expect from do_action.
We can do it with a closure.
// custom args for hook $args = array ( 'author' => 6, // id 'posts_per_page'=> 1, // max posts ); // subscribe to the hook w/custom args add_action('thesis_hook_before_post', function() use ( $args ) { recent_post_by_author( $args ); }); // trigger the hook somewhere do_action( 'thesis_hook_before_post' ); // renders a list of post tiles by author function recent_post_by_author( $args ) { // merge w/default args $args = wp_parse_args( $args, array ( 'author' => -1, 'orderby' => 'post_date', 'order' => 'ASC', 'posts_per_page'=> 25 )); // pull the user's posts $user_posts = get_posts( $args ); // some commands echo '<ul>'; foreach ( $user_posts as $post ) { echo "<li>$post->post_title</li>"; } echo '</ul>'; }
Here is a simplified example of a closure working
$total = array(); add_action('count_em_dude', function() use (&$total) { $total[] = count($total); } ); do_action ('count_em_dude' ); do_action ('count_em_dude' ); do_action ('count_em_dude' ); do_action ('count_em_dude' ); do_action ('count_em_dude' ); do_action ('count_em_dude' ); do_action ('count_em_dude' ); echo implode ( ', ', $total ); // 0, 1, 2, 3, 4, 5, 6
Anonymous vs. Closure
add_action ('custom_action', function(){ echo 'anonymous functions work without args!'; } ); // add_action ('custom_action', function($a, $b, $c, $d){ echo 'anonymous functions work but default args num is 1, the rest are null - '; var_dump(array($a,$b,$c,$d)); } ); // a add_action ('custom_action', function($a, $b, $c, $d){ echo 'anonymous functions work if you specify number of args after priority - '; var_dump(array($a,$b,$c,$d)); }, 10, 4 ); // a,b,c,d // CLOSURE $value = 12345; add_action ('custom_action', function($a, $b, $c, $d) use ($value) { echo 'closures allow you to include values - '; var_dump(array($a,$b,$c,$d, $value)); }, 10, 4 ); // a,b,c,d, 12345 // DO IT! do_action( 'custom_action', 'aa', 'bb', 'cc', 'dd' );
Proxy Function Class
class ProxyFunc { public $args = null; public $func = null; public $location = null; public $func_args = null; function __construct($func, $args, $location='after', $action='', $priority = 10, $accepted_args = 1) { $this->func = $func; $this->args = is_array($args) ? $args : array($args); $this->location = $location; if( ! empty($action) ){ // (optional) pass action in constructor to automatically subscribe add_action($action, $this, $priority, $accepted_args ); } } function __invoke() { // current arguments passed to invoke $this->func_args = func_get_args(); // position of stored arguments switch($this->location){ case 'after': $args = array_merge($this->func_args, $this->args ); break; case 'before': $args = array_merge($this->args, $this->func_args ); break; case 'replace': $args = $this->args; break; case 'reference': // only pass reference to this object $args = array($this); break; default: // ignore stored args $args = $this->func_args; } // trigger the callback call_user_func_array( $this->func, $args ); // clear current args $this->func_args = null; } }
Example Usage #1
$proxyFunc = new ProxyFunc( function() { echo "<pre>"; print_r( func_get_args() ); wp_die(); }, array(1,2,3), 'after' ); add_action('TestProxyFunc', $proxyFunc ); do_action('TestProxyFunc', 'Hello World', 'Goodbye'); // Hello World, 1, 2, 3
Example Usage #2
$proxyFunc = new ProxyFunc( function() { echo "<pre>"; print_r( func_get_args() ); wp_die(); }, // callback function array(1,2,3), // stored args 'after', // position of stored args 'TestProxyFunc', // (optional) action 10, // (optional) priority 2 // (optional) increase the action args length. ); do_action('TestProxyFunc', 'Hello World', 'Goodbye'); // Hello World, Goodbye, 1, 2, 3
Instead of:
add_action('thesis_hook_before_post','recent_post_by_author',10,'author,2')
it should be:
add_action('thesis_hook_before_post','recent_post_by_author',10,2)
...where 2 is the number of arguments and 10 is the priority in which the function will be executed. You don't list your arguments in add_action. This initially tripped me up. Your function then looks like this:
function function_name ( $arg1, $arg2 ) { /* do stuff here */ }
Both the add_action and function go in functions.php and you specify your arguments in the template file (page.php for example) with do_action like so:
do_action( 'name-of-action', $arg1, $arg2 );
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With