Мне нужно иметь 3 пользовательских типа записей на моем сайте WordPress, каждый из которых является родителем другого.
Курсы> Серия> Эпизоды
Я полностью создал файл функций, который регистрируетпользовательский тип записей и переписывает URL-адреса.Все это прекрасно работает, за исключением эпизодов, которые просто возвращают «Страница не найдена».
То, как он работает в данный момент, - это когда пользователь создает курс.Затем, когда они создают серию, появляется дополнительный мета-блок, чтобы выбрать курс, дочерний элемент которого.Затем они создают эпизод, и на странице эпизода есть дополнительный мета-блок для выбора серии, дочерней по которой он является.
Существует функция, которая перезаписывает постоянную ссылку на странице для создания тегов замены строкив URL, затем при сохранении сообщения строки заменяются именами сообщений курсов и серий.
<?php
/* ----------------------------------------------------------------------------------------------------------
Register our custom post types
---------------------------------------------------------------------------------------------------------- */
function create_post_type() {
//Courses
register_post_type( 'course',
[
'labels' => array(
'name' => __( 'Courses' ),
'singular_name' => __( 'Course' )
),
'description' => 'All courses',
'public' => true,
'hierarchical' => true,
'rewrite' => array(
'slug' => 'system/courses',
),
'menu_icon' => 'dashicons-welcome-learn-more',
'supports' => ['title', 'custom_fields', 'page-attributes']
]
);
//Series
register_post_type( 'series',
[
'labels' => array(
'name' => __( 'Series' ),
'singular_name' => __( 'Series' )
),
'show_ui' => true,
'show_in_menu' => 'edit.php?post_type=course',
'description' => 'Course series',
'hierarchical' => false,
'public' => true,
'supports' => ['title', 'custom_fields']
]
);
//Episodes
register_post_type( 'episodes',
[
'labels' => array(
'name' => __( 'Episodes' ),
'singular_name' => __( 'Episode' )
),
'show_ui' => true,
'show_in_menu' => 'edit.php?post_type=course',
'description' => 'Series Episodes',
'hierarchical' => false,
'public' => true,
'supports' => ['title', 'custom_fields']
]
);
}
add_action( 'init', 'create_post_type' );
/* ----------------------------------------------------------------------------------------------------------
Add our meta boxes to our series and episode add/edit page
---------------------------------------------------------------------------------------------------------- */
function my_add_meta_boxes() {
add_meta_box( 'series-parent', 'Course', 'series_attributes_meta_box', 'series', 'side', 'high' );
add_meta_box( 'episodes-parent', 'Series', 'episodes_attributes_meta_box', 'episodes', 'side', 'high' );
}
add_action( 'add_meta_boxes', 'my_add_meta_boxes' );
function series_attributes_meta_box( $post ) {
$post_type_object = get_post_type_object( $post->post_type );
$pages = wp_dropdown_pages( array( 'post_type' => 'course', 'selected' => $post->post_parent, 'name' => 'parent_id', 'show_option_none' => __( '(no parent)' ), 'sort_column'=> 'menu_order, post_title', 'echo' => 0 ) );
if ( ! empty( $pages ) ) {
echo $pages;
}
}
function episodes_attributes_meta_box( $post ) {
$post_type_object = get_post_type_object( $post->post_type );
$select = "<select name='parent_id' id='parent_id'>";
$select .= "<option value=''>(No Parent)</option>";
//Get Series
$args = [
'post_type' => 'series',
'posts_per_page' => -1,
'meta_key' => 'series_number',
'orderby' => 'meta_value_num',
'order' => 'ASC'
];
$seriesQuery = new WP_Query($args);
//Loop the series
while($seriesQuery->have_posts()){
$seriesQuery->the_post();
$select .= "<option " . (get_the_ID() == $post->post_parent ? 'selected' : '') . " class='level-0' value='" . get_the_ID() . "'>" . get_the_title(wp_get_post_parent_id(get_the_ID())) . ' - ' . get_the_title() . "</option>";
}
wp_reset_postdata();
$select .= "</select>";
echo $select;
}
/* ----------------------------------------------------------------------------------------------------------
Rewrite permalinks
---------------------------------------------------------------------------------------------------------- */
function my_add_rewrite_rules() {
//Series
add_rewrite_tag('%series%', '([^/]+)', 'series=');
add_permastruct('series', 'system/%course%/%series%', [ 'walk_dirs' => false ]);
add_rewrite_rule('^series/([^/]+)/([^/]+)/([^/]+)/?','index.php?series=$matches[1]','top');
//Episodes
add_rewrite_tag('%episodes%', '([^/]+)', 'episode=');
add_permastruct('episodes', 'system/%course%/%series%/%episodes%', [ 'walk_dirs' => false ]);
add_rewrite_rule('^episodes/([^/]+)/([^/]+)/([^/]+)/([^/]+)/?','index.php?episodes=$matches[1]','top');
}
add_action( 'init', 'my_add_rewrite_rules' );
/* ----------------------------------------------------------------------------------------------------------
String replace on the permalinks before we save them
---------------------------------------------------------------------------------------------------------- */
function series_permalinks($permalink, $post, $leavename) {
$post_id = $post->ID;
if($post->post_type != 'series' || empty($permalink) || in_array($post->post_status, array('draft', 'pending', 'auto-draft'))){
return $permalink;
}
$parent = $post->post_parent;
$parent_post = get_post( $parent );
$permalink = str_replace('%course%', $parent_post->post_name, $permalink);
return $permalink;
}
add_filter('post_type_link', 'series_permalinks', 10, 3);
function episodes_permalinks($permalink, $post, $leavename) {
$post_id = $post->ID;
if($post->post_type != 'episodes' || empty($permalink) || in_array($post->post_status, array('draft', 'pending', 'auto-draft'))){
return $permalink;
} else {
$parent_post = get_post( $post->post_parent );
$grandparent_post = get_post( $parent_post->post_parent );
$permalink = str_replace('%course%', $grandparent_post->post_name, $permalink);
$permalink = str_replace('%series%', $parent_post->post_name, $permalink);
return $permalink;
}
}
add_filter('post_type_link', 'episodes_permalinks', 10, 3);
?>
По правде говоря, большая часть кода была получена из многочисленных сообщений о переполнении стека и из Интернета.инструкции, чтобы получить его в текущем положении.
Моя проблема сейчас заключается в том, что всякий раз, когда я создаю эпизод, постоянная ссылка для эпизода не работает (даже после повторной очистки моих постоянных ссылок).Он просто возвращает «страница не найдена».
Я делаю что-то не так с перезаписью постоянной ссылки?
Примечание - перезапись system / необходима, яиспользуя плагин для нескольких тем, поэтому все должно начинаться с 'system / '.