J'ai eu quelque chose qui fonctionne vraiment bien - une page de recherche avec une URL personnalisée. Cela fonctionne bien sauf lorsque j'ajoute la page 404.php à mon thème. Puis la page 404s. Et si je l'enlève, ça recommence à fonctionner.
Existe-t-il un moyen de rechercher un 404 pour cette URL et de "l'annuler"? J'ai essayé, en quelque sorte, en vérifiant $GLOBALS['wp_query']->is_404 = false;
mais cela n'a pas fonctionné. Puis-je placer mes fonctions dans une action qui s'exécute avant le contrôle 404? J'ai essayé de créer un article avec cette limace, mais cela m'amène évidemment à cette page, pas à ma page personnalisée.
Voici le code avec lequel j'ai créé l'URL personnalisée:
add_action( 'parse_request', 'allow_blank_search');
function allow_blank_search(){
$path = $_SERVER['REQUEST_URI'];
if(substr($path, 0, 16) == '/catalog-of-work'){
$_GET['s'] = '';
$GLOBALS['wp_query']->is_search = true;
}
$GLOBALS['wp_rewrite']->search_base = 'catalog-of-work';
}
function search_url_rewrite_rule() {
if (!empty($_GET['s'])) {
wp_redirect(home_url("/catalog-of-work/") . urlencode(get_query_var('s')));
exit();
}
}
add_action('parse_request', 'search_url_rewrite_rule');
Tout d’abord, votre fonction de redirection doit être connectée tôt: vous ne vous fiez pas aux variables de requête, vous pouvez donc utiliser init
hook:
function search_redirect() {
if (!empty($_GET['s'])) {
$home = trailingslashit(home_url('catalog-of-work'));
wp_safe_redirect($home.urlencode(get_query_var('s')));
exit();
}
}
add_action('init', 'search_redirect');
La raison en est que cela redirigera la demande beaucoup plus tôt, ce qui économisera beaucoup de traitement.
Désormais, vous devez indiquer à WordPress que, lorsque l'URL /catalog-of-work
est visitée, il doit prendre en compte une demande de recherche.
function custom_search_query_var($do, $wp) {
$path = trim(parse_url(esc_url_raw(add_query_arg([])), PHP_URL_PATH), '/');
$home_path = trim(parse_url(esc_url_raw(home_url()), PHP_URL_PATH), '/');
$home_path and $path = trim(substr($path, strlen($home_path)), '/');
if (strpos($path, 'catalog-of-work') === 0) {
$wp->query_vars['s'] = trim(substr($path, 15), '/');
$do = false;
}
return $do;
}
add_action('do_parse_request', 'custom_search_query_var', 10, 2);
Il y a quelques points à noter dans le code ci-dessus:
do_parse_request
hook au lieu de parse_request
. Cela me permet d’empêcher complètement l’analyse de règles d’analyse de WordPress lorsque l’URL /catalog-of-work
est visité. Le traitement des vars de requête pouvant être un processus lent, cela pourrait améliorer les performances de votre page.add_query_arg
au lieu de diriger l'accès à $_SERVER
. C'est mieux parce que la fonction prend en charge certains cas Edge.example.com/wp
au lieu de example.com
. Comme l'URL de la maison peut facilement être modifiée, la fonction est ainsi plus stable et fonctionnera dans différentes situations.$wp->query_vars
. $wp
est l'instance actuelle de WP
class transmise par le hook do_parse_request
. C'est mieux pour deux raisons: $wp_query
n'est pas fiable sur do_parse_request
(ni sur parse_request
que vous avez utilisé) car ces points d'ancrage se produisent avant que $wp_query
ne soit traité et qu'une réinitialisation puisse encore s'y produire, supprimant la requête s
. En définissant la requête var sur $wp
objet, il veillera à transmettre les variables à $wp_query
.Faire des choses comme je l'ai décrit, avoir un modèle 404 n'affecte en rien, car WordPress ne fait pas définit le statut 404 pour les requêtes de recherche.
Cependant, mon code (tout comme votre code, du moins le code que vous avez posté) n'agit pas sur le modèle, donc, par défaut, WordPress chargera search.php
.
Il est très possible que votre modèle search.php
(ou le modèle que vous utilisez) vérifie la présence de have_posts()
et charge le modèle 404 (s'il est trouvé) lorsqu'il n'y a aucune publication.
Cela dépend vraiment du thème que vous utilisez.
Par exemple, le thème Twentyfifteen contient quelque chose comme:
<?php if ( have_posts() ) : ?>
// ... redacted loop code here...
else :
// If no content, include the "No posts found" template.
get_template_part( 'content', 'none' );
endif;
?>
Si votre thème contient quelque chose comme ceci, le modèle 404 peut être chargé lorsqu'il n'y a aucune publication, ce qui se produit lorsque la requête de recherche est vide.
Si tel est le problème, vous devez modifier votre modèle de recherche (ou si le thème est une tierce partie ou un thème principal, vous devez créer un thème child ) pour que le modèle de recherche traite le cas de non-publication en fonction de vos besoins. .
Je pense que vous cherchez une solution dans la mauvaise direction. Au lieu d'essayer d'empêcher une recherche avec zéro résultat de finir au gabarit 404, j'essaierais de l'attraper ici. En d'autres termes, dans votre modèle 404, incluez un test si la recherche a échoué et si oui, redirigez. Comme ça:
if (!empty($_GET['s']))
{ search_url_rewrite_rule();}
else
{ normal 404 }