web-dev-qa-db-ja.com

パーマリンク内の階層ページを削除する

私のサイトでは、いくつかのページが階層的に設定されています。現在、サイトのページとURLはこのようになっています。

Page name        | Current URL           | Preferred URL 
-----------------|----------------------------------------
Page AAA         | /pageAAA/             | /pageAAA/
|-- Page BBB     | /pageAAA/pageBBB/     | /pageBBB/
Page CCC         | /pageCCC/             | /pageCCC/
Page DDD         | /pageDDD/             | /pageDDD/
|-- Page EEE     | /pageDDD/pageEEE/     | /pageEEE/

URLからページ階層を取り除き、代わりにページ名を使用したいと思います。私は "パーマリンク"を/%postname%/に設定したので、現在これは "POSTS"の問題ではありません。

編集: /私がこれをやりたいのはその理由です。既存のサイトをワードプレスにインポートしています。既存のサイトにはページ(メニュー)の階層がありますが、フラットなURL構造があります。これがSEOに追加のメリットがあるかどうかはわかりませんが、URL構造を古いサイトと同じにしたいです。

5

誰かがこれに対するより良い解決策を見つけることができれば私は興味があるでしょう。これが私が思いついたものです:

function wpse_91821_flatten_page_paths( $wp ) {
    if ( false !== strpos( $wp->matched_query, 'pagename=' ) && isset( $wp->query_vars['pagename'] ) && $wp->query_vars['pagename'] && false === strpos( $wp->query_vars['pagename'], '/' ) ) {
        if ( !get_page_by_path( $wp->query_vars['pagename'] ) ) {
            $page = get_posts( array(
                'name'        => $wp->query_vars['pagename'],
                'post_type'   => 'page',
                'post_status' => 'publish',
                'numberposts' => 1
            ) );
            if ( $page && isset( $page[0] ) ) {
                $wp->query_vars['pagename'] = get_page_uri( $page[0]->ID );
                $wp->request = $wp->query_vars['pagename'];
            }
        }
    }
}
add_action( 'parse_request', 'wpse_91821_flatten_page_paths', 5 );

ここでやっていることはparse_requestを傍受していて、それがpagenameリクエストで、pagenameに "/"が含まれていない場合、正しい名前の投稿が見つかるかどうかを確認します。ページを見つけたら、クエリvarを設定します。これは、WordPress が考える リクエストが完全に階層的なものであるため、残りのリクエストチェーンを通常どおりに処理できるようにします。

あなたのリンクが正しく生成されるようにpost_type_linkにフィルタを追加したいでしょう(そうでなければそれらは階層的であり続けるでしょう)。

1
Matthew Boynes
function wpse_91821_flatten_page_paths( $wp ) {
    if ( false !== strpos( $wp->matched_query, 'pagename=' ) && isset( $wp->query_vars['pagename'] ) && $wp->query_vars['pagename'] && false === strpos( $wp->query_vars['pagename'], '/' ) ) {
        if ( !get_page_by_path( $wp->query_vars['pagename'] ) ) {
            $page = get_posts( array(
                'name'        => $wp->query_vars['pagename'],
                'post_type'   => 'page',
                'post_status' => 'publish',
                'numberposts' => 1
            ) );
            if ( $page && isset( $page[0] ) ) {
                $wp->query_vars['pagename'] = get_page_uri( $page[0]->ID );
                $wp->request = $wp->query_vars['pagename'];
            }
        }
    }
}
add_action( 'parse_request', 'wpse_91821_flatten_page_paths', 5 );

function custom_permalinks_page_link( $permalink, $post_id ) {
    if ( empty( $post_id ) ) return $permalink;
    $post = get_post( $post_id );
    return home_url( $post->post_name . "/");
}
add_filter( 'page_link', 'custom_permalinks_page_link', 10, 2 );

function custom_rewrite() {
    add_rewrite_rule('^([^/]+)?', 'index.php?pagename= $matches[1]', 'top');
}
add_action( 'init', 'custom_rewrite' );

use_verbose_page_rulesがトリガされ、get_page_by_path呼び出しがpage親とurl内の存在をチェックするので(!)、evilを追加することでこの予期しないコアチェックを回避できます。https://github.com/weaveworks/wordepress/blob/master/plugin/wordepress/wordepress.php#L91 のようにスペース

これは、もちろん、非常に壊れやすいので、おそらく避けるべきです:)

このプレゼンテーションはより良い答えを含んでいるかもしれませんが、私はそれを理解することができませんでした: https://www.slideshare.net/MikeSchinkel/hardcore-url-routing-2014?next_slideshow=1

0
ptica

私はページのパーマリンクの振る舞いを変えないでしょう。もっとシンプルで安全な解決策は、フラットページ階層を設定することです(本当にフラットにしたい場合)。

あなたがメニューの階層を持ちたいのであれば、あなたはまだそれを持つことができます - あなたはカスタムメニューを作成し、wp_nav_menu関数でそれを表示することができます。

0