Удаляем в URL префикс главной страницы у дочерних страниц
Для главной страницы сайта установлена статическая страница и у нее есть подстраницы. Задача: убрать в УРЛ префикс этой родительской страницы когда мы переходим на дочернюю.
Немного пояснений на примерах. Допустим имя родительской страницы (префикс который нужно убрать) main-page
. Тогда ссылки должны выглядеть следующим образом:
- Главная страница:
/main-page
→/
- Дочерняя страница:
/main-page/podstranica
→/podstranica
- Дочерняя страница:
/main-page/podstranica/vnuk
→/podstranica/vnuk
Также в коде:
- Предусмотрено, чтобы теперь неправильные URL отдавали 404 страницу.
- Отключен файл шаблона front-page.php, вместо него нужно использовать базовый вариант шаблона страницы page-*.php.
- Подправлены хлебные крошки (главный элемент крошек) (для моего плагина Kama Breadcrumbs).
# Delete main page prefix for subpages. # Works only if static page is set for front page. Delete_Base_Prefix_For_Front_Sub_Pages::init(); final class Delete_Base_Prefix_For_Front_Sub_Pages { // WP_Post|false if current request is front sub page static $sub_post = false; // WP_Post|false if specific page is set for front page static $front_post = 0; static $origin_REQUEST_URI = ''; static function init(){ self::$front_post = ( 'page' === get_option('show_on_front') && $ID = get_option('page_on_front') ) ? get_post( $ID ) : 0; if( self::$front_post ){ // change permalink add_filter( 'page_link', [ __CLASS__, 'fix_page_link' ] ); // change request add_filter( 'do_parse_request', [ __CLASS__, 'replace_uri' ] ); add_filter( 'request', [ __CLASS__, 'replace_uri_back' ] ); // remove `front-page.php` template file from template hierarchy // if static page set for front page. Use, basic `page-*.php` template file in this case. add_filter( 'frontpage'.'_template_hierarchy', '__return_empty_array' ); // 404 for URL with main page prefix add_action( 'pre_handle_404', [ __CLASS__, 'block_wrong_url' ] ); // for plugin Kama Breadcrumbs add_filter( 'kama_breadcrumbs_filter_elements', [ __CLASS__, 'fix_breadcrumbs' ] ); } } static function fix_page_link( $link ){ // url begin with prefix if( self::$front_post && strpos( $link, self::$front_post->post_name ) && preg_match( '~^/'. self::$front_post->post_name .'/([^?]+)~', parse_url( $link, PHP_URL_PATH ), $mm ) ) return str_replace( $mm[0], "/$mm[1]", $link ); return $link; } static function replace_uri( $true ){ list( $req_uri ) = explode( '?', $_SERVER['REQUEST_URI'] ); self::$origin_REQUEST_URI = $_SERVER['REQUEST_URI']; $page_real_path = self::$front_post->post_name .'/'. trim( $req_uri, '/' ); if( self::$sub_post = get_page_by_path( $page_real_path ) ) $_SERVER['REQUEST_URI'] = $page_real_path; return $true; } static function replace_uri_back( $foo ){ if( self::$origin_REQUEST_URI ) $_SERVER['REQUEST_URI'] = self::$origin_REQUEST_URI; return $foo; // for filter } static function block_wrong_url( $false ){ if ( preg_match( '~^/'. self::$front_post->post_name .'(?:/([^?]+)|/?$)~', self::$origin_REQUEST_URI) ) { global $wp_query; $wp_query->set_404(); status_header( 404 ); nocache_headers(); return true; // for hook break } return $false; } static function fix_breadcrumbs( $elms ){ if( self::$sub_post && ! empty( $elms['singular_hierar']['page__page_crumbs'] ) ){ $elms['home'] = array_shift( $elms['singular_hierar']['page__page_crumbs'] ); } return $elms; } }
Код можно вставлять в файл темы functions.php.