Pasando un parámetro para filtrar y funciones de acción

49

Es una forma de pasar mis propios parámetros a la función en add_filter o add_action . Por ejemplo, eche un vistazo en el siguiente código:

function my_content($content, $my_param)
{
do something...
using $my_param here ...
return $content;
}
add_filter('the_content', 'my_content', 10, 1);

¿Puedo pasar mi propio parámetro? algo como:

add_filter('the_content', 'my_content($my_param)', 10, 1)

o

add_filter('the_content', 'my_content', 10, 1, $my_param)
    
pregunta Aakash Chakravarthy 17.03.2012 - 12:24

8 respuestas

74

Por defecto esto no es posible. Hay soluciones si lo haces de la manera OOP.
Podría crear una clase para almacenar los valores que desea usar más adelante.

Ejemplo:

/**
 * Stores a value and calls any existing function with this value.
 */
class WPSE_Filter_Storage
{
    /**
     * Filled by __construct(). Used by __call().
     *
     * @type mixed Any type you need.
     */
    private $values;

    /**
     * Stores the values for later use.
     *
     * @param  mixed $values
     */
    public function __construct( $values )
    {
        $this->values = $values;
    }

    /**
     * Catches all function calls except __construct().
     *
     * Be aware: Even if the function is called with just one string as an
     * argument it will be sent as an array.
     *
     * @param  string $callback Function name
     * @param  array  $arguments
     * @return mixed
     * @throws InvalidArgumentException
     */
    public function __call( $callback, $arguments )
    {
        if ( is_callable( $callback ) )
            return call_user_func( $callback, $arguments, $this->values );

        // Wrong function called.
        throw new InvalidArgumentException(
            sprintf( 'File: %1$s<br>Line %2$d<br>Not callable: %3$s',
                __FILE__, __LINE__, print_r( $callback, TRUE )
            )
        );
    }
}

Ahora puede llamar a la clase con cualquier función que desee, si la función existe en algún lugar, se llamará con sus parámetros almacenados.

Vamos a crear una función de demostración ...

/**
 * Filter function.
 * @param  array $content
 * @param  array $numbers
 * @return string
 */
function wpse_45901_add_numbers( $args, $numbers )
{
    $content = $args[0];
    return $content . '<p>' . implode( ', ', $numbers ) . '</p>';
}

... y úsalo una vez ...

add_filter(
    'the_content',
    array (
        new WPSE_Filter_Storage( array ( 1, 3, 5 ) ),
        'wpse_45901_add_numbers'
    )
);

... y otra vez ...

add_filter(
    'the_content',
    array (
        new WPSE_Filter_Storage( array ( 2, 4, 6 ) ),
        'wpse_45901_add_numbers'
    )
);

Salida:

  

Laclaveesreutilización:puedereutilizarlaclase(yennuestrosejemplostambiénlafunción).

PHP5.3+

SipuedesusarunaversióndePHP5.3ounamásreciente cierres será mucho más fácil:

$param1 = '<p>This works!</p>';
$param2 = 'This works too!';

add_action( 'wp_footer', function() use ( $param1 ) {
        echo $param1;
    }, 11 
);
add_filter( 'the_content', function( $content ) use ( $param2 ) {
        return t5_param_test( $content, $param2 );
    }, 12
);

/**
 * Add a string to post content
 *
 * @param  string $content
 * @param  string $string This is $param2 in our example.
 * @return string
 */
function t5_param_test( $content, $string )
{
    return "$content <p><b>$string</b></p>";
}

El inconveniente es que no se pueden escribir pruebas unitarias para los cierres.

    
respondido por el fuxia 17.03.2012 - 19:32
1

Crea una función con los argumentos necesarios que devuelve una función. Pase esta función (función anónima, también conocida como cierre) al gancho wp.

Se muestra aquí para un aviso de administrador en el servidor de WordPress.

public function admin_notice_func( $message = '')
{
$class = 'error';
    $output = sprintf('<div class="%s"><p>%s</p></div>',$class, $message);
    $func = function() use($output) { print $output; };
    return $func;
}
$func = admin_notice_func('Message');
add_action('admin_notices', $func);
    
respondido por el hornament 20.01.2016 - 19:53
1

Sé que ya pasó el tiempo, pero tuve algunos problemas para pasar mi propio parámetro hasta que encontré que el 4º parámetro en add_filter es el número de parámetros pasados que incluyen el contenido que debe cambiar. Por lo tanto, si pasa 1 parámetro adicional, el número debería ser 2 y no 1 en su caso

add_filter('the_content', 'my_content', 10, 2, $my_param)

y usando

function my_content($content, $my_param) {...}
    
respondido por el giacoder 16.02.2017 - 13:48
0

Si creas tu propio gancho, aquí tienes un ejemplo.

// lets say we have three parameters  [ https://codex.wordpress.org/Function_Reference/add_filter ]
add_filter( 'filter_name', 'my_func', 10, 3 );
my_func( $first, $second, $third ) {
  // code
}

luego implementa el gancho:

// [ https://codex.wordpress.org/Function_Reference/apply_filters ]
echo apply_filters( 'filter_name', $first, $second, $third );
    
respondido por el T.Todua 14.05.2015 - 11:20
0

Use php Funciones anónimas :

$my_param = 'my theme name';
add_filter('the_content', function ($content) use ($my_param) {
    //$my_param is available for you now
    if (is_page()) {
        $content = $my_param . ':<br>' . $content;
    }
    return $content;
}, 10, 1);
    
respondido por el Wesam Alalem 23.01.2016 - 11:26
0

Siempre puedes usar global, ¿no?

  global $my_param;
    
respondido por el samjco 25.08.2017 - 01:47
0

La forma correcta, realmente breve y más eficiente de pasar cualquier número de argumentos a los filtros y acciones de WP es desde @Wesam Alalem Aquí , que utiliza el cierre.

Solo agregaría que podría hacerlo aún más claro y mucho más flexible al separar el método real del cierre anónimo. Para esto, simplemente llame al método desde el cierre de la siguiente manera (ejemplo modificado de @Wesam Alalem answer).

De esta manera, puede escribir la lógica tan larga o complicada como desee de manera léxica fuera del cierre que usa para llamar al hacedor real.

// ... inside some class

private function myMethod() {
    $my_param = 'my theme name';
    add_filter('the_content', function ($content) use ($my_param) {
        // This is the anonymous closure that allows to pass 
        // whatever number of parameters you want via 'use' keyword.
        // This is just oneliner.
        // $my_param is available for you now via 'use' keyword above
        return $this->doThings($content, $my_param);
    }, 10, 2);
}

private function doThings($content, $my_param) {
    // Call here some other method to do some more things
    // however complicated you want.
    $morethings = '';
    if ($content = 'some more things') {
        $morethings = (new MoreClass())->get();
    }
    return $my_param . ':<br>' . $content . $morethings;
}
    
respondido por el bob-12345 14.10.2018 - 18:10
-1

Esperaba hacer lo mismo, pero como no es posible, supongo que una solución simple es llamar a una función diferente como      add_filter('the_content', 'my_content_filter', 10, 1);

entonces my_content_filter () puede simplemente llamar a my_content () pasando cualquier argumento que desee.

    
respondido por el Pierre-Verthume Larivière 12.12.2017 - 22:24

Lea otras preguntas en las etiquetas