Удаляем в 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.