WP_Query avec "post_title LIKE 'something%'"?
5 réponses
- votes
-
- 2011-05-30
Je résoudrais cela avec unfiltre sur
WP_Query
.Celui qui détecte une variable de requête supplémentaireet l'utilise commepréfixe dutitre.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 cettefaçon,vouspouveztoujours appeler
WP_Query
,il vous suffit depasser letitre comme argumentwpse18703_title
(ou de changer lenomen quelque chose deplus court).I would solve this with a filter on
WP_Query
. One that detects an extra query variable and uses that as the prefix of the title.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; }
This way you can still call
WP_Query
, you just pass the title as thewpse18703_title
argument (or change the name to something shorter).-
Celui-cimanqueen quelque sorte le `$ wpdb->prepare ()`.This one is somehow missing the `$wpdb->prepare()`.
- 1
- 2012-11-06
- kaiser
-
@kaiser: Celafait longtemps,maisje pense que cen'étaitpaspossible avec `prepare ()`.`$ wpdb->prepare ('LIKE"% s %% "','banana')` renverrait `" LIKE ''banana '%' "`,doncnous devons construire la requêtenous-mêmes,et faire aussi l'échappement.@kaiser: It's been a long time, but I think this was not possible with `prepare()`. `$wpdb->prepare('LIKE "%s%%"', 'banana')` would return `"LIKE ''banana'%'"`, so we have to construct the query ourselves, and do the escaping too.
- 0
- 2012-11-06
- Jan Fabry
-
@JanFabry Heureux de vous voir agaaaaaaaain!:) Venez discuter quelquetemps,hm?StopPress serait heureux de vous voir.Àpropos de ça `prepare ()`.Ouais,c'est délicatet j'ai dûessayer çaplusieursfois,avant de le contourner.Àpartir de quelque chose queje viens defaire: `$ wpdb->prepare ('AND {$ wpdb->posts} .post_title LIKE% s',esc_sql ('%'. Like_escape (trim ($term)). '%'))`.Etje suis àpeuprès sûr que le `esc_sql ()`estinutileet justeparanoïaque.@JanFabry Happy to see you agaaaaaaaain! :) Drop by in chat some time, hm? StopPress would be happy to see you. About that `prepare()`. Yeah, that's tricky and I had to try that several times, before I got around it. From something I just made: `$wpdb->prepare( ' AND {$wpdb->posts}.post_title LIKE %s ', esc_sql( '%'.like_escape( trim( $term ) ).'%' ) )`. And I'm pretty sure the `esc_sql()` is unnecessary and just paranoid.
- 1
- 2012-11-07
- kaiser
-
Il semble que vousne pouvezpas rechercher une chaîne avec `` '' (apostrophe) à l'intérieur.Je suppose que c'est à cause de lafuite?Jen'aipasencoretrouvé la solutionIt seems that you can't search a string with `'` (apostrophe) inside. I guess it's because of escaping ? I didn't find the solution yet
- 0
- 2018-08-30
- Vincent Decaux
-
- 2013-04-19
Simplifié:
function title_filter( $where, &$wp_query ) { global $wpdb; // 2. pull the custom query in here: 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, // 1. define a custom query var here to pass your term through: '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 ); return $wp_query;
Simplified:
function title_filter( $where, &$wp_query ) { global $wpdb; // 2. pull the custom query in here: 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, // 1. define a custom query var here to pass your term through: '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 ); return $wp_query;
-
Veuillezinclure uneexplication avec votre code.Please include an explanation along with your code.
- 13
- 2013-04-19
- s_ha_dum
-
Grande simplificationGreat simplification
- 2
- 2014-11-10
- Timo Huovinen
-
Jepense que le code s'expliquepar lui-même,dumoinspourmoi.Merci d'avoirpartagé le script complet.Code is i think self explained, atleast for me. Thanks for sharing complete script.
- 2
- 2017-08-08
- Hassan Dad Khan
-
Utilisez '$ wpdb->esc_like (' au lieu de 'esc_sql (like_escape ('Use '$wpdb->esc_like (' instead of 'esc_sql( like_escape('
- 2
- 2018-02-19
- fdrv
-
@fdrv Vous avez raison,mais selon wp docs,$ wpdb->esc_like aencorebesoin deesc_sql ().Doncje pense que le code correct seraitesc_sql ($ wpdb->esc_like ($ search_term))@fdrv You are right but according to wp docs $wpdb->esc_like still need esc_sql(). So I think the correct code would be esc_sql( $wpdb->esc_like( $search_term ) )
- 0
- 2019-10-18
- Waqas Bukhary
-
`like_escape` obsolète 4.0.0 Utilisez` wpdb ::esc_like``like_escape` deprecated 4.0.0 Use `wpdb::esc_like`
- 0
- 2020-03-14
- Empty Brain
-
`remove_filter` utilise seulement 3 arguments,le dernierpeut être supprimé.`remove_filter` only uses 3 arguments, the last one can be removed.
- 2
- 2020-06-24
- Skatox
-
- 2015-01-02
Je voulaismettre àjour ce code sur lequel vous aveztravaillépour wordpress 4.0et supérieur,caresc_sql ()est obsolète dans la version 4.0 supérieure.
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; }
Le reste des chosesestidentique.
Jetiens également à souligner que vouspouvez utiliser la variable s dans les arguments WP_Querypourtransmettre destermes de recherche,qui rechercheront également letitre dumessage,je crois.
Comme ceci:
$args = array( 'post_type' => 'post', 's' => $search_term, 'post_status' => 'publish', 'orderby' => 'title', 'order' => 'ASC' ); $wp_query = new WP_Query($args);
Wanted to update this code you guys worked on for the wordpress 4.0 and above as esc_sql() is deprecated in 4.0 higher.
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; }
Rest of the stuff is same.
Also I want to point out you can use s variable within WP_Query arguments to pass search terms, which will also search for post title i believe.
Like this:
$args = array( 'post_type' => 'post', 's' => $search_term, 'post_status' => 'publish', 'orderby' => 'title', 'order' => 'ASC' ); $wp_query = new WP_Query($args);
-
Qu'est-ce que «search_prod_title»exactement?Dois-je changer celaen autre chose?What exactly `search_prod_title` is? Should i change this to something else?
- 0
- 2017-03-24
- Antonios Tsimourtos
-
Depuis quand `esc_sql`est-il déprécié?Cen'estpas.`$ wpdb->escape`estbien ... https://developer.wordpress.org/reference/functions/esc_sql/Since when is `esc_sql` depricated? It's not. `$wpdb->escape` is though... https://developer.wordpress.org/reference/functions/esc_sql/
- 0
- 2018-02-02
- Jeremy
-
Notez que leparamètre s recherche également le contenu de l'article,ce quipeutne pas être l'objectif souhaité.=)Note that the s parameter searches the post content as well, which may not be the desired aim. =)
- 1
- 2018-04-19
- Christine Cooper
-
`like_escape` obsolète` 4.0.0` Utilisez `wpdb ::esc_like``like_escape` deprecated `4.0.0` Use `wpdb::esc_like`
- 0
- 2020-03-14
- Empty Brain
-
- 2018-04-19
Avec une solution vulnérablepubliéeici,je viens avec une version unpeu simplifiéeet désinfectée.
Tout d'abord,nous créons unefonctionpour lefiltre
posts_where
qui vouspermet d'afficher uniquement les articles correspondant à des conditions spécifiques: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; }
Nous ajoutonsmaintenant
cc_search_post_title
dansnos arguments de requête:$args = array( 'cc_search_post_title' => $search_term, // search post title only 'post_status' => 'publish', );
Etenfin enroulez lefiltre autour de la requête:
add_filter( 'posts_where', 'cc_post_title_filter', 10, 2 ); $query = new WP_Query($args); remove_filter( 'posts_where', 'cc_post_title_filter', 10 );
Utilisation deget_posts ()
Certainesfonctions qui récupèrent les articlesn'exécutentpas defiltres,donc lesfonctions defiltreposts_where que vous attachezne modifierontpas la requête. Si vousprévoyez d'utiliser
get_posts()
pourinterroger vosmessages,vous devez définirsuppress_filters
surfalse dans votretableau d'arguments:$args = array( 'cc_search_post_title' => $search_term, 'suppress_filters' => FALSE, 'post_status' => 'publish', );
Vouspouvezmaintenant utiliser
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'enest-il duparamètre
s
?Leparamètre
s
est disponible:$args = array( 's' => $search_term, );
Lors de l'ajout de votreterme de recherche dans leparamètre
s
fonctionneet il recherchera letitre de l'article,il recherchera également le contenu de l'article.Qu'enest-il duparamètre
title
qui a été ajouté avec WP 4.4?Passer unterme de recherche dans leparamètre
title
:$args = array( 'title' => $search_term, );
Est sensible à la casseet
LIKE
,pas%LIKE%
. Cette recherchemoyenne dehello
ne renverrapas lemessage avec letitreHello World
ouHello
.With some vulnerable solution posted here, I come with a bit simplified and sanitized version.
First, we create a function for the
posts_where
filter which allows you to only show posts matching specific conditions: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; }
Now we add
cc_search_post_title
into our query arguments:$args = array( 'cc_search_post_title' => $search_term, // search post title only 'post_status' => 'publish', );
And finally wrap the filter around the query:
add_filter( 'posts_where', 'cc_post_title_filter', 10, 2 ); $query = new WP_Query($args); remove_filter( 'posts_where', 'cc_post_title_filter', 10 );
Using get_posts()
Certain functions which retrieve posts do not run filters, so the posts_where filter functions you attach will not modify the query. If you plan to use
get_posts()
to query your posts, you need to setsuppress_filters
to false in your argument array:$args = array( 'cc_search_post_title' => $search_term, 'suppress_filters' => FALSE, 'post_status' => 'publish', );
Now you can use
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 );
What about the
s
parameter?The
s
parameter is available:$args = array( 's' => $search_term, );
While adding your search term into the
s
parameter work and it will search the post title, it will also search the post content.What about the
title
parameter which was added with WP 4.4?Passing a search term into the
title
parameter:$args = array( 'title' => $search_term, );
Is case sensitive and
LIKE
, not%LIKE%
. This mean search forhello
will not return post with titleHello World
orHello
.-
Excellent.Je cherchais 'post_title' commeparamètreet,évidemment,je n'ai rientrouvé.Excellent. I was looking for 'post_title' as a parameter and, obviously, didn't find anything.
- 0
- 2019-09-13
- MastaBaba
-
J'obtiens uneerreur avec la requête wp ouj'obtiens desmessages: "E_WARNING Erreur dans lefichier» class-wp-hook.php «à la ligne 288: Leparamètre 2 à cc_post_title_filter () devrait être une référence,valeur donnéeI'm getting an error with wp query or get posts: "E_WARNING Error in file »class-wp-hook.php« at line 288: Parameter 2 to cc_post_title_filter() expected to be a reference, value given
- 0
- 2020-03-03
- Elkrat
-
@Elkrat Supprimez le `&` de `& $ wp_query` dans` cc_post_title_filter`.@Elkrat Remove the `&` from `&$wp_query` in `cc_post_title_filter`.
- 0
- 2020-05-05
- Mattimator
-
- 2015-04-28
Enm'appuyant sur d'autres réponses avantmoi,pour offrir de laflexibilité dans la situation où vous souhaitez rechercher unmessage contenant unmot dans un champméta OU dans letitre dumessage,je donne cette option via l'argument "title_filter_relation". Dans cetteimplémentation,je n'autorise que lesentrées "OR" ou "AND" avec une valeurpar défaut 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; }
Voici unexemple de codeen actionpour unmessagetrès simple detype "faq" où la questionest letitre dumessage lui-même:
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);
Building on other answers before me, to provide flexibility in the situation where you want to search a post that contains a word in a meta field OR in the title of the post, I give that option via the argument "title_filter_relation." In this implementation, I only allow for "OR" or "AND" inputs with a default of "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; }
Here's an example of the code in action for a very simple post type "faq" where the question is the post title itself:
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);
-
Bonneperspicacité,ajout de "variables de requête"personnalisées aux arguments de requêtepassés à `WP_Query` afin depouvoir y accéder dans lefiltre`posts_where`.Good insight, adding custom "query vars" to the query args passed to `WP_Query` in order to be able to access them within the `posts_where` filter.
- 1
- 2017-02-04
- Tom Auger
Je doisfaire une
WP_Query
avec unLIKE
sur lepost_title
.J'ai commencé avec cette
WP_Query
classique:Mais ce queje veuxfaire ressemble à cecien SQL:
La sortieimprime les résultats quej'attends,maisj'utilise le
<?php while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?>
pour afficher les résultats.Et celane fonctionnepas avec
$wpdb->get_results()
.Commentpuis-je réaliser ce quej'ai décritici?