wake-up-neo.com

WP_Query mit "post_title LIKE 'something%'"?

Ich muss einen WP_Query mit einem LIKEauf dem post_title machen.

Ich habe mit diesem regulären WP_Query angefangen:

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

Aber was ich eigentlich machen möchte, sieht in SQL so aus:

$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);

Die Ausgabe druckt die Ergebnisse, die ich erwarte, aber ich benutze die reguläre Funktion <?php while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?>, um die Ergebnisse anzuzeigen.
Und das funktioniert nicht mit $wpdb->get_results().

Wie kann ich das erreichen, was ich hier beschrieben habe?

43
Ludo

Ich würde das mit einem Filter für WP_Query lösen. Eine, die eine zusätzliche Abfragevariable erkennt und diese als Präfix für den Titel verwendet.

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;
}

Auf diese Weise können Sie weiterhin WP_Query aufrufen. Sie übergeben lediglich den Titel als wpse18703_title-Argument (oder ändern den Namen in einen kürzeren Namen).

44
Jan Fabry

Vereinfacht:

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;
17
Rao

Wollte diesen Code aktualisieren, an dem ihr für WordPress 4.0 und höher gearbeitet habt, da esc_sql () in 4.0 höher veraltet ist.

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;
}

Der Rest des Zeugs ist dasselbe.

Ich möchte auch darauf hinweisen, dass Sie s variable in WP_Query-Argumenten verwenden können, um Suchbegriffe zu übergeben, die auch nach dem Titel des Beitrags suchen, glaube ich.

So was:

$args = array(
    'post_type' => 'post',
    's' => $search_term,
    'post_status' => 'publish',
    'orderby'     => 'title', 
    'order'       => 'ASC'        
);
$wp_query = new WP_Query($args);
16
Ashan Jay

Da hier eine verwundbare Lösung veröffentlicht wurde, habe ich eine etwas vereinfachte und bereinigte Version.

Zunächst erstellen wir eine Funktion für den posts_where-Filter, mit der Sie nur Posts anzeigen können, die bestimmten Bedingungen entsprechen:

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;
}

Jetzt fügen wir cc_search_post_title in unsere Abfrageargumente ein:

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

Und schließlich wickeln Sie den Filter um die Abfrage:

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

Get_posts () verwenden

Bestimmte Funktionen, die Posts abrufen, führen keine Filter aus, sodass die von Ihnen angehängten posts_where-Filterfunktionen die Abfrage nicht ändern. Wenn Sie get_posts() zum Abfragen Ihrer Posts verwenden möchten, müssen Sie suppress_filters in Ihrem Argumentarray auf false setzen:

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

Jetzt können Sie get_posts() verwenden:

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

Was ist mit dem Parameter s?

Der Parameter s ist verfügbar:

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

Wenn Sie Ihren Suchbegriff in den Parameter work s einfügen und der Beitragstitel durchsucht wird, durchsucht er auch den Inhalt des Beitrags.

Was ist mit dem Parameter title, der mit WP 4.4 hinzugefügt wurde?

Übergeben eines Suchbegriffs an den Parameter title:

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

Ist case sensitive und LIKE, nicht %LIKE%. Diese mittlere Suche nach hello gibt keinen Beitrag mit dem Titel Hello World oder Hello zurück.

9

Aufbauend auf anderen Antworten vor mir, um Flexibilität in der Situation zu bieten, in der Sie einen Beitrag suchen möchten, der ein Wort in einem Metafeld OR im Titel des Beitrags enthält, gebe ich diese Option über das Argument " title_filter_relation. " In dieser Implementierung erlaube ich nur "OR" - oder "AND" -Eingaben mit dem Standardwert "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;
}

Hier ist ein Beispiel für den Code in Aktion für einen sehr einfachen Beitragstyp "faq", bei dem die Frage der Beitragstitel selbst ist:

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);
7
David Choy