web-dev-qa-db-ja.com

カスタムURLは404になります

私は本当にうまくいっているもの - カスタムURLを持つ検索ページ - を持っていました。テーマに404.phpページを追加したとき以外はうまくいきます。それからページ404s。そして、私がそれを取り除けば、それは再び働き始める。

このURLの404を確認して「キャンセル」する方法はありますか?私は$GLOBALS['wp_query']->is_404 = false;をチェックすることによってそれを試してみましたが、うまくいきませんでした。 404チェックが行われる前に自分の関数を実行するアクションに入れることはできますか?私はそのスラッグで投稿を作成しようとしましたが、明らかにそれは私のカスタムページではなくそのページに連れて行ってくれます。

これがカスタムURLを作成したコードです。

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

早めにリダイレクト

まず第一に、あなたのリダイレクト関数は早くフックされるべきです:あなたはそこで問い合わせ変数に頼っていないので、あなたはinitname__フックを使うことができます:

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

その理由は、これによりリクエストがはるかに早くリダイレ​​クトされ、多くの処理が節約されるためです。

クエリ変数を正しく設定する

さて、あなたはWordPressにURL /catalog-of-workが訪問されたとき、それは検索要求を考慮しなければならないことを伝える必要があります。

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

上記のコードには注意すべき点がいくつかあります。

  • 私はdo_parse_requestの代わりにparse_requestフックを使いました。これにより、URL /catalog-of-workにアクセスしたときにWordPressの解析規則を完全に防ぐことができます。クエリ変数の処理は処理が遅くなる可能性があるため、ページのパフォーマンスが向上する可能性があります。
  • 現在のURLを決定するための私のロジックは、add_query_argへのアクセスを指示する代わりに $_SERVER を使用します。関数がいくつかのEdgeのケースを処理するのでそれはより良いです。
  • 私の論理はあなたのホームURLがexample.com/wpではなくexample.comのようなものであるというケースを扱います。ホームURLは簡単に変更できるため、機能がより安定し、さまざまな状況で機能するようになります。
  • 私が使用したコードは、$wp->query_vars配列に "s"クエリ変数を設定します。 $wpは、do_parse_requestフックによって渡される WPname__ classの現在のインスタンスです。これは2つの理由でより良いです:
    1. グローバル変数に直接アクセスしないようにする
    2. グローバルな$wp_queryに変数を設定することはdo_parse_request上では信頼できません(あなたが使ったparse_request上でも)、そのフックは$wp_queryが処理される前に起こり、まだリセットが起こるかもしれません、sname__クエリ変数を削除します。クエリ変数を$wpオブジェクトに設定することで、変数を$wp_queryに渡すように注意します。

防止する404

私が説明したように404テンプレートを持っていても何も影響を受けません、なぜならWordPressは検索クエリに対してnotset 404 status)をしないからです。

しかし、私のコード(あなたのコード、少なくともあなたが投稿したコードと同じ)はテンプレートには作用しないので、デフォルトでは、WordPressはsearch.phpをロードします。

あなたのsearch.phpテンプレート(またはあなたが使っているテンプレート)がhave_posts()をチェックし、投稿がないときに404テンプレート(もしあれば)をロードする可能性が非常に高いです。

それは本当にあなたが使っているテーマによります。

たとえば、テーマTwentyfifteenには、次のようなものが含まれています。

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

テーマにこのようなものが含まれている場合、投稿がないときに404テンプレートがロードされる可能性があります。これは、検索クエリが空のときに発生します。

それが問題である場合は、検索テンプレートを編集して(またはテーマがサードパーティまたはコアテーマの場合は 子テーマ を作成する必要があります)、必要に応じて投稿のないケースを処理できるようにします。 。

1
gmazzap

私はあなたが解決策のために間違った方向を向いていると思います。 404個のテンプレートで結果がゼロになって検索が行われないようにする代わりに、それを見つけようとします。言い換えれば、あなたの404テンプレートにそれが失敗した検索であり、そうであればリダイレクトするかどうかのテストを含めてください。このような:

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