web-dev-qa-db-ja.com

異なる投稿タイプのスラグの前にカテゴリ名URLの書き換えを処理する

私はここで私が必要としているものに近い100の類似したトピックを調べました、しかし残念なことに、それが重複しているならば、このように謝罪を微調整できませんでした。

私はいくつかの投稿タイプ(EventsVenuesPlacesなど)を持っています、そしてまた私はPostsを使います。ここで、4つの投稿タイプは標準のWordPressのCategories分類法に関連しています。

私はそのようなパーマリンクを組み立てようとしてきました:

http://サイト名/ venues/61312/california-venue

venuesはカテゴリの名前です。 61312はpost_id、california-venueはポスト名です。

すべての投稿タイプは同じ構造をレンダリングする必要があります。

%category%/%post_id%/%postname%/

そのパーマリンク構造は、設定 - >パーマリンクの投稿に対してはうまく機能するように見えますが、他の投稿タイプに対してはうまくいきません。

with_front => falseを持つものは404を返し、他のものはうまく働きますが、post_type/postnameにリダイレクトします。

そのようなカスタムの書き換え規則があります。

array( 
  'regex'     => '^([^/]+)/([0-9]+)/([^/]+)?',  
  'query'       => 'category_name=$matches[1]&post_id=$matches[2]&pagename=$matches[3]', 
 )

post_type_linkをフィルタリングしてリダイレクトが停止するかどうかを確認しました。また、disable_redirect=1をクエリルールに追加して次のスニペットを試しました。

add_filter('query_vars', 'my_public_query_vars');
function my_public_query_vars($qv)
{
    $qv[] = 'disable_redirect';
    return $qv;
}
add_filter('wp_redirect', 'my_disable_redirect');
function my_disable_redirect($location)
{
    $disable_redirect = get_query_var('disable_redirect');
    if(!empty($disable_redirect)) return false;
    return $location;
}

それは単にWSODを引き起こしました。

各投稿タイプの単一ビューへのリダイレクトを防止し(単一投稿ビューは正常に機能するようです)、%category%/%post_id%/%postname%というURL構造を維持するにはどうすればよいですか。

4
Mario Peshev

T5 RewriteとHM Rewriteを使ったブレーンストーミングと試行錯誤の末、私は最も簡単な解決策を選びました。

パーマリンクは実際にはWordPressに傍受されていたので、追加の書き換え規則は必要ありませんでした(パフォーマンス以外は問題ありませんでしたが)。私はデフォルトのカスタムパーマリンクとして%category%/%post_id%/%postname%を残しました、そしてそれはこれまでのところすべての投稿タイプのために働くようです。

元のスラグも優雅に処理されます(残りのリンクが見つかった場合)が、新しいものがデフォルトです。

私は問題を見つけるためにtemplate_redirectrequestredirect_canonicalquery_varswp_redirect、その他のフックで遊んで、これで終わりました:

add_filter( 'request', 'sm_permalink_request_handler' );
function sm_permalink_request_handler( $request ) {
    if ( ! isset( $request['p'] ) ) {
        return $request;
    }

    // Get the post type, it's required to prevent the redirect
    $post_id = $request['p'];
    $post = get_post( $post_id );
    $request['post_type'] = $post->post_type;

    return $request;
} 


/**
 * Override get_permalink and prevent redirects
 */
function sm_fix_permalinks_for_post_types( $url, $post ) {
        $taxonomies = get_post_taxonomies();
        // See if categories are assigned to our CPT entry
        if ( ! empty( $taxonomies ) && in_array( 'category', $taxonomies ) ) {

            // Fetch all categories
            $categories = wp_get_post_categories( $post->ID, array() );

            if ( ! empty( $categories ) ) {
                // Get the main category in case there are more assigned
                // Somewhat arbitrary since it pops the last one.
                $main_category_id = array_pop( $categories );

                $main_category = get_category( $main_category_id );

                if( ! empty( $main_category ) ) {
                    $category_slug = $main_category->slug;
                    $post_id = $post->ID;
                    $post_name = $post->post_name;

                    $url = home_url( "$category_slug/$post_id/$post_name" );
                }
            }
        }

        return $url;
}

add_filter( 'post_type_link', 'sm_fix_permalinks_for_post_types', 10, 2 );

最初の問題は、リクエストとともに渡されたpost_typeの欠如に関連していました。私のパーマリンクはカテゴリ名と投稿IDでフィルタリングしていましたが、WordPressを妨げるposttypeにとらわれませんでした。 IDで投稿を取得し、post_typeを設定することで、状況は通常に戻りました。

2番目の問題は、管理者やフロントエンドのテンプレート周辺の新しい投稿へのパーマリンクに関連していました。別のフィルタリング部分がそこでトリックをした、そしてそれはサイト全体にわたって働く。

1
Mario Peshev