it-swarm.com.de

Benutzerdefinierte URL zu 404

Ich hatte etwas wirklich gut funktionierendes - eine Suchseite mit einer benutzerdefinierten URL. Es funktioniert einwandfrei, außer wenn ich die 404.php Seite zu meinem Theme hinzufüge. Dann die Seite 404s. Und wenn ich es entferne, fängt es wieder an zu arbeiten.

Gibt es eine Möglichkeit, nach einer 404 für diese URL zu suchen und diese abzubrechen? Ich habe das versucht, indem ich $GLOBALS['wp_query']->is_404 = false; überprüft habe, aber das hat nicht funktioniert. Kann ich meine Funktionen in eine Aktion einbinden, die ausgeführt wird, bevor die 404-Prüfung stattfindet? Ich habe versucht, einen Beitrag mit diesem Slug zu erstellen, aber das bringt mich offensichtlich zu dieser Seite, nicht zu meiner benutzerdefinierten Seite.

Hier ist der Code, mit dem ich die benutzerdefinierte URL erstellt habe:

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');
1
dgig

Früh umleiten

Zuallererst sollte Ihre Weiterleitungsfunktion frühzeitig eingebunden werden: Sie verlassen sich dort nicht auf Abfragevariablen, daher können Sie init hook verwenden:

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

Der Grund dafür ist, dass dadurch die Anforderung viel früher umgeleitet wird, wodurch viel Verarbeitungsaufwand gespart wird.

Stellen Sie die Abfragevariablen richtig ein

Jetzt müssen Sie WordPress mitteilen, dass beim Aufrufen der URL /catalog-of-work eine Suchanfrage berücksichtigt werden muss.

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

Im obigen Code sind einige Dinge zu beachten:

  • Ich habe do_parse_request hook anstelle von parse_request verwendet. Dadurch kann ich WordPress-Parsing-Regeln vollständig verhindern, wenn die URL /catalog-of-work aufgerufen wird. Da das Verarbeiten von Abfragevariablen ein langsamer Prozess sein kann, kann dies die Leistung Ihrer Seite verbessern.
  • Meine Logik zur Ermittlung der aktuellen URL verwendet add_query_arg , anstatt den Zugriff auf $_SERVER zu leiten. Das ist besser, weil sich die Funktion um einige Edge-Fälle kümmert.
  • Meine Logik behandelt den Fall, dass Ihre Heim-URL so etwas wie example.com/wp anstelle von example.com ist. Da die Heimat-URL leicht geändert werden kann, wird sichergestellt, dass die Funktion stabiler ist und in verschiedenen Situationen funktioniert.
  • Der verwendete Code setzt die Abfragevariable "s" im Array $wp->query_vars. $wp ist die aktuelle Instanz von WP class, die von do_parse_request hook übergeben wird. Dies ist aus zwei Gründen besser:
    1. sie vermeiden es, direkt auf globale Variablen zuzugreifen
    2. das Setzen von Variablen auf global $wp_query ist für do_parse_request nicht zuverlässig (und auch nicht für parse_request, den Sie verwendet haben), da diese Hooks vor der Verarbeitung von $wp_query auftreten und dort möglicherweise noch ein Reset stattfindet und die s query var gelöscht wird. Wenn Sie die Abfragevariable auf das Objekt $wp setzen, wird darauf geachtet, dass Variablen an $wp_query übergeben werden.

404 verhindern

Wenn Sie etwas tun, wie ich es beschrieben habe, hat das Vorhandensein einer 404-Vorlage keine Auswirkungen, da WordPress not den 404-Status für Suchanfragen festlegt.

Mein Code (genau wie Ihr Code, zumindest der von Ihnen veröffentlichte Code) wirkt sich jedoch nicht auf die Vorlage aus, sodass WordPress standardmäßig search.php lädt.

Es ist sehr wahrscheinlich, dass Ihre search.php-Vorlage (oder die von Ihnen verwendete Vorlage) nach have_posts() sucht und die 404-Vorlage lädt (falls gefunden), wenn keine Beiträge vorhanden sind.

Das hängt wirklich von dem Thema ab, das Sie verwenden.

Zum Beispiel enthält das Thema Fünfundzwanzig so etwas wie:

<?php if ( have_posts() ) : ?>
    // ... redacted loop code here...    
else :
    // If no content, include the "No posts found" template.
    get_template_part( 'content', 'none' );
endif;
?>

Wenn Ihr Design so etwas enthält, kann die Vorlage 404 geladen werden, wenn keine Beiträge vorhanden sind. Dies geschieht, wenn die Suchabfrage leer ist.

Wenn dies der Fall ist, sollten Sie Ihre Suchvorlage bearbeiten (oder wenn das Thema ein Thema eines Drittanbieters oder ein Kernthema ist, sollten Sie ein untergeordnetes Thema erstellen), damit die Suchvorlage den Fall behandelt, dass keine Beiträge Ihren Anforderungen entsprechen .

1
gmazzap

Ich denke, Sie suchen in die falsche Richtung nach einer Lösung. Anstatt zu verhindern, dass eine Suche mit null Ergebnissen auf der 404-Vorlage endet, würde ich versuchen, sie dort abzufangen. Mit anderen Worten, enthalten Sie in Ihrer 404-Vorlage einen Test, ob die Suche fehlgeschlagen ist und ob die Weiterleitung mit "Ja" abgeschlossen ist. So was:

if (!empty($_GET['s']))
  { search_url_rewrite_rule();}
else
  { normal 404 }
0
cjbj