WP_Query con “post_title LIKE 'something%'”?

39

Necesito hacer un WP_Query con un LIKE en el post_title .

Comencé con este WP_Query regular:

$wp_query = new WP_Query( 
    array (
        'post_type'        => 'wp_exposants',
        'posts_per_page'   => '1',
        'post_status'      => 'publish',
        'orderby'          => 'title', 
        'order'            => 'ASC',
        'paged'            => $paged
    )
); 

Pero lo que realmente quiero hacer se ve así en SQL:

$query = "
        SELECT      *
        FROM        $wpdb->posts
        WHERE       $wpdb->posts.post_title LIKE '$param2%'
        AND         $wpdb->posts.post_type = 'wp_exposants'
        ORDER BY    $wpdb->posts.post_title
";
$wpdb->get_results($query);

La salida imprime los resultados que estoy esperando, pero uso el <?php while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?> regular para mostrar los resultados.
Y eso no funciona con $wpdb->get_results() .

¿Cómo puedo lograr lo que describí aquí?

    
pregunta Ludo 30.05.2011 - 14:11

5 respuestas

43

Solucionaría esto con un filtro en WP_Query . Una que detecta una variable de consulta adicional y la utiliza como prefijo del título.

add_filter( 'posts_where', 'wpse18703_posts_where', 10, 2 );
function wpse18703_posts_where( $where, &$wp_query )
{
    global $wpdb;
    if ( $wpse18703_title = $wp_query->get( 'wpse18703_title' ) ) {
        $where .= ' AND ' . $wpdb->posts . '.post_title LIKE \'' . esc_sql( $wpdb->esc_like( $wpse18703_title ) ) . '%\'';
    }
    return $where;
}

De esta manera aún puedes llamar a WP_Query , solo pasas el título como el argumento wpse18703_title (o cambias el nombre a algo más corto).

    
respondido por el Jan Fabry 30.05.2011 - 16:06
15

Quería actualizar este código en el que trabajaron para wordpress 4.0 y superior, ya que esc_sql () está en desuso en 4.0 más arriba.

function title_filter($where, &$wp_query){
    global $wpdb;

    if($search_term = $wp_query->get( 'search_prod_title' )){
        /*using the esc_like() in here instead of other esc_sql()*/
        $search_term = $wpdb->esc_like($search_term);
        $search_term = ' \'%' . $search_term . '%\'';
        $where .= ' AND ' . $wpdb->posts . '.post_title LIKE '.$search_term;
    }

    return $where;
}

El resto de las cosas es igual.

También quiero señalar que puede usar la variable s dentro de los argumentos de WP_Query para pasar los términos de búsqueda, que también buscarán el título de la publicación, creo.

Me gusta esto:

$args = array(
    'post_type' => 'post',
    's' => $search_term,
    'post_status' => 'publish',
    'orderby'     => 'title', 
    'order'       => 'ASC'        
);
$wp_query = new WP_Query($args);
    
respondido por el Ashan Jay 02.01.2015 - 06:36
15

Simplificado:

function title_filter( $where, &$wp_query )
{
    global $wpdb;
    if ( $search_term = $wp_query->get( 'search_prod_title' ) ) {
        $where .= ' AND ' . $wpdb->posts . '.post_title LIKE \'%' . esc_sql( like_escape( $search_term ) ) . '%\'';
    }
    return $where;
}

$args = array(
    'post_type' => 'product',
    'posts_per_page' => $page_size,
    'paged' => $page,
    'search_prod_title' => $search_term,
    'post_status' => 'publish',
    'orderby'     => 'title', 
    'order'       => 'ASC'
);

add_filter( 'posts_where', 'title_filter', 10, 2 );
$wp_query = new WP_Query($args);
remove_filter( 'posts_where', 'title_filter', 10, 2 );
return $wp_query;
    
respondido por el Rao 19.04.2013 - 15:24
7

Aprovechando otras respuestas antes que yo, para proporcionar flexibilidad en la situación en la que desea buscar una publicación que contenga una palabra en un campo meta O en el título de la publicación, le doy esa opción a través del argumento "title_filter_relation". En esta implementación, solo permito entradas "OR" o "AND" con un valor predeterminado de "AND".

function title_filter($where, &$wp_query){
    global $wpdb;
    if($search_term = $wp_query->get( 'title_filter' )){
        $search_term = $wpdb->esc_like($search_term); //instead of esc_sql()
        $search_term = ' \'%' . $search_term . '%\'';
        $title_filter_relation = (strtoupper($wp_query->get( 'title_filter_relation'))=='OR' ? 'OR' : 'AND');
        $where .= ' '.$title_filter_relation.' ' . $wpdb->posts . '.post_title LIKE '.$search_term;
    }
    return $where;
}

Aquí hay un ejemplo del código en acción para un tipo de pregunta muy simple "faq" donde la pregunta es el título de la publicación:

add_filter('posts_where','title_filter',10,2);
$s1 = new WP_Query( array(
    'post_type' => 'faq',
    'posts_per_page' => -1,
    'title_filter' => $q,
    'title_filter_relation' => 'OR',
    'post_status' => 'publish',
    'orderby'     => 'title', 
    'order'       => 'ASC',
    'meta_query' => array(
        'relation' => 'OR',
        array(
            'key' => 'faq_answer',
            'value' => $q,
            'compare' => 'LIKE'
        )
    )
));
remove_filter('posts_where','title_filter',10,2);
    
respondido por el David Choy 29.04.2015 - 00:44
5

Con una solución vulnerable publicada aquí, vengo con una versión un poco simplificada e higienizada.

Primero, creamos una función para el filtro posts_where que le permite mostrar solo las publicaciones que coinciden con condiciones específicas:

function cc_post_title_filter($where, &$wp_query) {
    global $wpdb;
    if ( $search_term = $wp_query->get( 'cc_search_post_title' ) ) {
        $where .= ' AND ' . $wpdb->posts . '.post_title LIKE \'%' . $wpdb->esc_like( $search_term ) . '%\'';
    }
    return $where;
}

Ahora agregamos cc_search_post_title en nuestros argumentos de consulta:

$args = array(
    'cc_search_post_title' => $search_term, // search post title only
    'post_status' => 'publish',
);

Y finalmente envuelva el filtro alrededor de la consulta:

add_filter( 'posts_where', 'cc_post_title_filter', 10, 2 );
$query = new WP_Query($args);
remove_filter( 'posts_where', 'cc_post_title_filter', 10 );

Usando get_posts ()

Ciertas funciones que recuperan publicaciones no ejecutan filtros, por lo que las funciones de filtro posts_where que adjuntas no modificarán la consulta. Si planea usar get_posts() para consultar sus publicaciones, debe establecer suppress_filters en falso en su matriz de argumentos:

$args = array(
    'cc_search_post_title' => $search_term,
    'suppress_filters' => FALSE,
    'post_status' => 'publish',
);

Ahora puedes usar get_posts() :

add_filter( 'posts_where', 'cc_post_title_filter', 10, 2 );
$posts = get_posts($args);
remove_filter( 'posts_where', 'cc_post_title_filter', 10 );

¿Qué pasa con el parámetro s ?

El parámetro s está disponible:

$args = array(
    's' => $search_term,
);

Mientras agrega su término de búsqueda al trabajo de parámetro s y buscará el título de la publicación, también buscará el contenido de la publicación.

¿Qué pasa con el parámetro title que se agregó con WP 4.4?

Pasando un término de búsqueda al parámetro title :

$args = array(
    'title' => $search_term,
);

Es sensible a mayúsculas y minúsculas y LIKE , no %LIKE% . Esta búsqueda significa que hello no devolverá la publicación con el título Hello World o Hello .

    
respondido por el Christine Cooper 19.04.2018 - 14:58

Lea otras preguntas en las etiquetas