¿Qué hacen add_filters() y apply_filter() en WordPress?

23 ago 2011, 15:18:25
Vistas: 18.7K
Votos: 5

Estoy un poco confundido sobre por qué esto no funciona - aunque debo admitir que no estoy muy seguro de lo que hacen apply_filters() y add_filter, ¡así que cualquier consejo general también sería genial!

Quiero una consulta que muestre los cinco posts anteriores en una página de post individual. Estoy enviando la fecha del post actual y quiero aplicar un filtro que excluya posts posteriores a esta.

function sw_filter_posts_before( $where = '', $date) {
    // Filtra posts anteriores a la fecha especificada
    $where .= " AND post_date < '" . $date . "'";
    return $where;
}

¿Cómo aplico esto correctamente? Simplemente usar add_filter o apply_filter antes de crear un nuevo objeto WP_Query no parece funcionar correctamente.

¡Gracias de antemano!

Edición: Para profundizar, me gustaría entender cómo pasar una variable al filtro, ya que no puedo hacer que $date se pase desde otra función.

Aquí está dicha función (es una llamada AJAX dentro de WordPress, por eso comienzo obteniendo el ID del post de la página actual a través de una variable $_POST):

function create_more_videos_sidebar() {
    // Obtiene el ID del post desde AJAX
    $id = $_POST['theID'];

    $args = array(  'post_type'         =>  'videos',
                    'posts_per_page'    =>  1,
                    'p'                 =>  $id
                ); 

    $wp_query = new WP_Query($args);

    while ($wp_query->have_posts()) : $wp_query->the_post(); $do_not_duplicate = $post->ID;
        // Obtiene la fecha del post actual
        $date = get_the_date('Y-m-d');
    endwhile;

    $args = array(  'post_type'         =>  'videos',
                    'posts_per_page'    => 5
                ); 

    // Añade filtro pero no sabe cómo pasar $date
    add_filter( 'posts_where', 'sw_filter_videos_before' );


    $wp_query = new WP_Query($args);
    // Elimina el filtro después de usarlo
    remove_filter( 'posts_where', 'sw_filter_videos_before' );

    // Aquí iría el código del loop

    $response = json_encode( array( 'result' => $result ) );

    header( "Content-Type: application/json" );
    echo $response;

    exit;
}
3
Comentarios

Bien, primero lo primero: ¿a qué hook exactamente estás intentando agregar tu filtro? Eso importa, porque tu variable $date usa datos de $post, así que necesitamos saber si estamos filtrando dentro o fuera del Loop.

Chip Bennett Chip Bennett
23 ago 2011 17:31:31

Creo que aquí es donde mi falta de conocimiento sobre filtros de WP me está afectando. Pensé que el hook era 'posts_where', y que agregaría la cadena dada a la consulta SQL. Hasta donde sé, eso está fuera del loop, ya que es en la parte de preprocesamiento de la creación de un loop. ¿Tienes alguna sugerencia sobre cómo lograría mi objetivo siguiendo las mejores prácticas?

Michael Watson Michael Watson
23 ago 2011 19:27:38

Claro, podemos llegar ahí. :) ¿Qué fecha quieres usar? Preguntado de manera más precisa: ¿cómo quieres determinar qué fecha usar?

Chip Bennett Chip Bennett
23 ago 2011 20:53:28
Todas las respuestas a la pregunta 1
7

¿Qué estás intentando filtrar? Supongo que estás intentando agregar un filtro a un gancho de filtro llamado posts_before. En ese caso, necesitas agregar tu filtro a este gancho mediante add_filter():

function mytheme_filter_posts_before( $where = '', $date) {

    $where .= " AND post_date < '" . $date . "'";
    return $where;
}
// Agregar la función al gancho de filtro
add_filter( 'posts_before', 'mytheme_filter_posts_before' );

Nota que cambié el nombre de tu función. filter_posts_before() es un nombre de función demasiado genérico y muy probable que cause una colisión de nombres de funciones.

EDITAR

Y sólo para aclarar:

  • apply_filters() es la ubicación del gancho de filtro, es llamado por el código principal y se usa para aplicar cualquier filtro que es agregado a la cola por Temas/Plugins (y el núcleo).
  • add_filter() es llamado por Temas/Plugins (y el núcleo), y se usa para agregar filtros a la cola para ser aplicados al gancho por el núcleo.

EDITAR 2

Basado en tu comentario anterior, el gancho es posts_where. Así que, intentemos reconstruir tu función de callback:

function mytheme_filter_posts_where( $where ) {

    // Aquí, necesitamos determinar cómo
    // establecer qué fecha usar. En tu 
    // ejemplo de código, llamas a get_the_date(),
    // pero esta función debe usarse dentro
    // del Loop. Intentemos con get_the_time()
    // en su lugar. Solo necesitarás encontrar
    // una manera de determinar qué ID de post usar.
    $post = 'some_post_id';
    $date = get_the_time( 'Y-m-d', $post );

    $where .= " AND post_date < '" . $date . "'";
    return $where;
}
// Agregar la función al gancho de filtro
add_filter( 'posts_where', 'mytheme_filter_posts_where' );
23 ago 2011 15:26:20
Comentarios

¡Gracias por la aclaración! Me aseguraré de renombrar el filtro. Todavía no entiendo cómo pasar la variable $date a esto, ¿podrías aclarar eso también? ¡Gracias!

Michael Watson Michael Watson
23 ago 2011 15:34:12

¿Qué es la variable $date y de dónde proviene?

Chip Bennett Chip Bennett
23 ago 2011 15:38:27

$date proviene de otra función mía, es la fecha del post actual, en el formato 'Y-m-d'.

Michael Watson Michael Watson
23 ago 2011 15:49:57

¿Estás globalizando $date, o devolviéndolo desde la función, qué? ¿Puedes publicar también el código de esa función?

Chip Bennett Chip Bennett
23 ago 2011 16:31:33

Vale, he actualizado la publicación original con más detalles. Podría globalizar la fecha, pero ¿es realmente necesario? ¿No sería mejor, si es posible, simplemente pasarla de alguna manera?

Michael Watson Michael Watson
23 ago 2011 16:42:11

He actualizado mi respuesta. Solo necesitamos encontrar una forma de determinar el ID de la publicación para referenciarlo y así obtener la fecha correcta que usar en la consulta.

Chip Bennett Chip Bennett
23 ago 2011 20:58:51

Absolutamente. Seguí tu consejo inicial y tengo el ID de la publicación llegando desde la página a través de json, y luego simplemente lo globalizo. Lo cual funciona bien, pero supongo que no es la mejor práctica. Todo funciona perfectamente ahora, pero me sentiría mucho mejor si pudiera pasar estos datos de forma privada. Muchas gracias por tu ayuda hasta ahora.

Michael Watson Michael Watson
24 ago 2011 13:16:09
Mostrar los 2 comentarios restantes