Php WordPress自定义帖子类型无法访问子页面

Php WordPress自定义帖子类型无法访问子页面,php,wordpress,rewrite,Php,Wordpress,Rewrite,下面的内容成功地让我在我的WordPress网站上使用程序和程序常见问题解答,作为自定义帖子类型,但我正在努力解决页面的永久链接问题 当我创建一个新的FAQ页面时,我将父级设置为程序这很好,但这是一个永久链接,我似乎无法开始工作 例如,如果一个程序名为Football,我将访问domain.com/programs/Football,然后我将创建一个名为Football的程序FAQ,并从该程序中将父级设置为Football,FAQ的永久链接将变为domain.com/programme\u常见问

下面的内容成功地让我在我的WordPress网站上使用程序程序常见问题解答,作为自定义帖子类型,但我正在努力解决页面的永久链接问题

当我创建一个新的FAQ页面时,我将父级设置为程序这很好,但这是一个永久链接,我似乎无法开始工作

例如,如果一个程序名为Football,我将访问
domain.com/programs/Football
,然后我将创建一个名为Football的程序FAQ,并从该程序中将父级设置为Football,FAQ的永久链接将变为
domain.com/programme\u常见问题解答/football/football

当我试图访问该页面时,它显示为404未找到。如果我从FAQ页面中删除父选项,则永久链接将变为
domain.com/program\u FAQ/football
,并且可以正常工作

理想情况下,我希望在节目常见问题解答中制作的页面最终成为
domain.com/programmes/football/FAQ

add_action( 'init', 'register_cpt_programmes' );
add_action( 'init', 'register_cpt_programmes_faq' );

function register_cpt_programmes() {

    $labels = array( 
        'name'               => __( 'Programmes', 'text_domain' ),
        'singular_name'      => __( 'single programme name', 'text_domain' ),
        'add_new'            => _x( 'Add Programme', '${4:Name}', 'text_domain' ),
        'add_new_item'       => __( 'Add Programme', 'text_domain}' ),
        'edit_item'          => __( 'Edit this Programme', 'text_domain' ),
        'new_item'           => __( 'New Programme', 'text_domain' ),
        'view_item'          => __( 'View Programme', 'text_domain' ),
        'search_items'       => __( 'Search Programmes', 'text_domain' ),
        'not_found'          => __( 'No Programmes found', 'text_domain' ),
        'not_found_in_trash' => __( 'No Programmes found in Trash', 'text_domain' ),
        'parent_item_colon'  => __( 'Parent single post type name:', 'text_domain' ),
        'menu_name'          => __( 'Programmes', 'text_domain' ),
    );

    $args = array( 
        'labels'              => $labels,
        'hierarchical'        => true,
        'description'         => 'description',
        //'taxonomies'          => array( 'category' ),
        'public'              => true,
        'show_ui'             => true,
        'show_in_menu'        => true,
        'menu_position'       => 5,
        //'menu_icon'         => '',
        'show_in_nav_menus'   => true,
        'publicly_queryable'  => true,
        'exclude_from_search' => false,
        'has_archive'         => true,
        'query_var'           => true,
        'can_export'          => true,
        'rewrite'             => true,
        'capability_type'     => 'page', 
        'supports'            => array( 
            'title', 'editor', 'author', 'page-attributes', 'thumbnail', 'excerpt', 'custom-fields', 'revisions', 'comments'
        ),
        'rewrite' => array(
            'with_front' => false,
            'slug'       => 'programmes'
        )
    );

    register_post_type( 'programmes', $args );
}

function register_cpt_programmes_faq() {

    $labels = array( 
        'name'               => __( 'Programme FAQ', 'text_domain' ),
        'singular_name'      => __( 'single programme faq', 'text_domain' ),
        'add_new'            => _x( 'Add Programme FAQ', '${4:Name}', 'text_domain' ),
        'add_new_item'       => __( 'Add Programme FAQ', 'text_domain}' ),
        'edit_item'          => __( 'Edit this Programme FAQ', 'text_domain' ),
        'new_item'           => __( 'New Programme FAQ', 'text_domain' ),
        'view_item'          => __( 'View Programme FAQ', 'text_domain' ),
        'search_items'       => __( 'Search Programme FAQ', 'text_domain' ),
        'not_found'          => __( 'No Programme FAQs found', 'text_domain' ),
        'not_found_in_trash' => __( 'No Programmes FAQs found in Trash', 'text_domain' ),
        'parent_item_colon'  => __( 'Parent single post type name:', 'text_domain' ),
        'menu_name'          => __( 'Programme FAQ', 'text_domain' ),
    );

    $args = array( 
        'labels'              => $labels,
        'hierarchical'        => true,
        'description'         => 'description',
        //'taxonomies'          => array( 'category' ),
        'public'              => true,
        'show_ui'             => true,
        'show_in_menu'        => true,
        'menu_position'       => 5,
        //'menu_icon'         => '',
        'show_in_nav_menus'   => true,
        'publicly_queryable'  => true,
        'exclude_from_search' => false,
        'has_archive'         => true,
        'query_var'           => true,
        'can_export'          => true,
        'rewrite'             => true,
        'capability_type'     => 'page', 
        'supports'            => array( 
            'title', 'editor', 'author', 'page-attributes', 'thumbnail', 'excerpt', 'custom-fields', 'revisions', 'comments'
        ),
        'rewrite' => array(
            'with_front' => false,
            'slug'       => 'programme_faq'
        )
    );

    register_post_type( 'programme_faq', $args );
}
add_action('admin_menu', function() {
    remove_meta_box('pageparentdiv', 'programme_faq', 'normal');
});

add_action('add_meta_boxes', function() {
    add_meta_box('programmes-parent', 'Programmes', 'programmes_attributes_meta_box', 'programme_faq', 'side', 'high');
});

function programmes_attributes_meta_box($post) {
    $post_type_object = get_post_type_object($post->post_type);
    if ( $post_type_object->hierarchical ) {
        $pages = wp_dropdown_pages(array('post_type' => 'programmes', '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;
        } // end empty pages check
    } // end hierarchical check.
}

这是我第一次回答堆栈溢出问题。请原谅格式和拼写问题。

摘要:

// 1a. register the Programmes post type
function register_cpt_programmes()
{
    $labels = array(
        'name'               => __('Programmes', 'text_domain'),
        'singular_name'      => __('single programme name', 'text_domain'),
        'add_new'            => _x('Add Programme', '${4:Name}', 'text_domain'),
        'add_new_item'       => __('Add Programme', 'text_domain}'),
        'edit_item'          => __('Edit this Programme', 'text_domain'),
        'new_item'           => __('New Programme', 'text_domain'),
        'view_item'          => __('View Programme', 'text_domain'),
        'search_items'       => __('Search Programmes', 'text_domain'),
        'not_found'          => __('No Programmes found', 'text_domain'),
        'not_found_in_trash' => __('No Programmes found in Trash', 'text_domain'),
        'parent_item_colon'  => __('Parent single post type name:', 'text_domain'),
        'menu_name'          => __('Programmes', 'text_domain'),
    );

    $args = array(
        'labels'              => $labels,
        'hierarchical'        => false,
        'description'         => 'description',
        'public'              => true,
        'show_ui'             => true,
        'show_in_menu'        => true,
        'menu_position'       => 5,
        'show_in_nav_menus'   => true,
        'publicly_queryable'  => true,
        'exclude_from_search' => false,
        'has_archive'         => true,
        'query_var'           => true,
        'can_export'          => true,
        'rewrite'             => true,
        'capability_type'     => 'page', 
        'supports'            => array(
            'title',
            'editor',
            'author',
            'page-attributes',
            'thumbnail',
            'excerpt',
            'custom-fields',
            'revisions',
            'comments'
        ),
        'rewrite' => array(
            'with_front' => false,
            'slug'       => 'programmes'
        )
    );
    register_post_type('programmes', $args);
}
add_action('init', 'register_cpt_programmes');

// 1b. register the Programme FAQ post type
function register_cpt_programme_faq()
{
    $labels = array(
        'name'               => __('Programme FAQ', 'text_domain'),
        'singular_name'      => __('single programme faq', 'text_domain'),
        'add_new'            => _x('Add Programme FAQ', '${4:Name}', 'text_domain'),
        'add_new_item'       => __('Add Programme FAQ', 'text_domain}'),
        'edit_item'          => __('Edit this Programme FAQ', 'text_domain'),
        'new_item'           => __('New Programme FAQ', 'text_domain'),
        'view_item'          => __('View Programme FAQ', 'text_domain'),
        'search_items'       => __('Search Programme FAQ', 'text_domain'),
        'not_found'          => __('No Programme FAQs found', 'text_domain'),
        'not_found_in_trash' => __('No Programmes FAQs found in Trash', 'text_domain'),
        'parent_item_colon'  => __('Parent single post type name:', 'text_domain'),
        'menu_name'          => __('Programme FAQ', 'text_domain'),
    );

    $args = array(
        'labels'              => $labels,
        'hierarchical'        => false,
        'description'         => 'description',
        'public'              => true,
        'show_ui'             => true,
        'show_in_menu'        => true,
        'menu_position'       => 5,
        'show_in_nav_menus'   => true,
        'publicly_queryable'  => true,
        'exclude_from_search' => false,
        'has_archive'         => true,
        'query_var'           => true,
        'can_export'          => true,
        'rewrite'             => true,
        'capability_type'     => 'page', 
        'supports'            => array(
            'title',
            'editor',
            'author',
            'page-attributes',
            'thumbnail',
            'excerpt',
            'custom-fields',
            'revisions',
            'comments'
        ),
        'rewrite' => array(
            'with_front' => false,
            'slug'       => 'programme_faq'
        )
    );
    register_post_type('programme_faq', $args);
}
add_action('init', 'register_cpt_programme_faq');

// 2a. meta box - add a custom meta box on the Programme FAQ edit page
function pfaq_add_meta_boxes($post)
{
    add_meta_box('pfaq-parent', 'Parent Programme', 'pfaq_parent_meta_box', $post->post_type, 'side', 'core');
}
add_action('add_meta_boxes_programme_faq', 'pfaq_add_meta_boxes');

// 2b. select box - add a select input inside the Parent Programme meta box
function pfaq_parent_meta_box($post)
{
    $parents = get_posts(
        array(
            'post_type'   => 'programmes',
            'orderby'     => 'title',
            'order'       => 'ASC',
            'numberposts' => -1
        )
    );

    if(!empty($parents))
    {
        echo '<select name="parent_id" class="widefat">';

        foreach($parents as $parent)
        {
            printf('<option value="%s"%s>%s</option>', esc_attr($parent->ID), selected($parent->ID, $post->post_parent, false), esc_html($parent->post_title));
        }

        echo '</select>';
    }
}

// 3. rewrite rule - teach WordPress to parse the custom URL pattern
function pfaq_rewrite_rule()
{
    add_rewrite_rule('^programmes/([^/]+)/faq/?', 'index.php?programme_faq=$matches[1]-faq', 'top');
}
add_action('init', 'pfaq_rewrite_rule');

// 4. permalink - filter all Programme FAQ permalinks to match the desired URL pattern
function pfaq_post_type_link($post_link, $post, $leavename, $sample)
{
    if($post->post_type == 'programme_faq')
    {
        $parent = get_post($post->post_parent);
        $post_link = get_bloginfo('url') . '/programmes/' . $parent->post_name . '/faq';
    }

    return $post_link;
}
add_filter('post_type_link', 'pfaq_post_type_link', 1, 4);
代码中记录了达成解决方案的关键步骤。以下是总结:

  • 注册自定义帖子类型
  • 在编辑屏幕上添加“父程序”元框
  • 添加重写规则,以便WordPress正确解析自定义URL结构
  • 过滤永久链接,以便正确呈现FAQ页面的链接
  • 代码:

    // 1a. register the Programmes post type
    function register_cpt_programmes()
    {
        $labels = array(
            'name'               => __('Programmes', 'text_domain'),
            'singular_name'      => __('single programme name', 'text_domain'),
            'add_new'            => _x('Add Programme', '${4:Name}', 'text_domain'),
            'add_new_item'       => __('Add Programme', 'text_domain}'),
            'edit_item'          => __('Edit this Programme', 'text_domain'),
            'new_item'           => __('New Programme', 'text_domain'),
            'view_item'          => __('View Programme', 'text_domain'),
            'search_items'       => __('Search Programmes', 'text_domain'),
            'not_found'          => __('No Programmes found', 'text_domain'),
            'not_found_in_trash' => __('No Programmes found in Trash', 'text_domain'),
            'parent_item_colon'  => __('Parent single post type name:', 'text_domain'),
            'menu_name'          => __('Programmes', 'text_domain'),
        );
    
        $args = array(
            'labels'              => $labels,
            'hierarchical'        => false,
            'description'         => 'description',
            'public'              => true,
            'show_ui'             => true,
            'show_in_menu'        => true,
            'menu_position'       => 5,
            'show_in_nav_menus'   => true,
            'publicly_queryable'  => true,
            'exclude_from_search' => false,
            'has_archive'         => true,
            'query_var'           => true,
            'can_export'          => true,
            'rewrite'             => true,
            'capability_type'     => 'page', 
            'supports'            => array(
                'title',
                'editor',
                'author',
                'page-attributes',
                'thumbnail',
                'excerpt',
                'custom-fields',
                'revisions',
                'comments'
            ),
            'rewrite' => array(
                'with_front' => false,
                'slug'       => 'programmes'
            )
        );
        register_post_type('programmes', $args);
    }
    add_action('init', 'register_cpt_programmes');
    
    // 1b. register the Programme FAQ post type
    function register_cpt_programme_faq()
    {
        $labels = array(
            'name'               => __('Programme FAQ', 'text_domain'),
            'singular_name'      => __('single programme faq', 'text_domain'),
            'add_new'            => _x('Add Programme FAQ', '${4:Name}', 'text_domain'),
            'add_new_item'       => __('Add Programme FAQ', 'text_domain}'),
            'edit_item'          => __('Edit this Programme FAQ', 'text_domain'),
            'new_item'           => __('New Programme FAQ', 'text_domain'),
            'view_item'          => __('View Programme FAQ', 'text_domain'),
            'search_items'       => __('Search Programme FAQ', 'text_domain'),
            'not_found'          => __('No Programme FAQs found', 'text_domain'),
            'not_found_in_trash' => __('No Programmes FAQs found in Trash', 'text_domain'),
            'parent_item_colon'  => __('Parent single post type name:', 'text_domain'),
            'menu_name'          => __('Programme FAQ', 'text_domain'),
        );
    
        $args = array(
            'labels'              => $labels,
            'hierarchical'        => false,
            'description'         => 'description',
            'public'              => true,
            'show_ui'             => true,
            'show_in_menu'        => true,
            'menu_position'       => 5,
            'show_in_nav_menus'   => true,
            'publicly_queryable'  => true,
            'exclude_from_search' => false,
            'has_archive'         => true,
            'query_var'           => true,
            'can_export'          => true,
            'rewrite'             => true,
            'capability_type'     => 'page', 
            'supports'            => array(
                'title',
                'editor',
                'author',
                'page-attributes',
                'thumbnail',
                'excerpt',
                'custom-fields',
                'revisions',
                'comments'
            ),
            'rewrite' => array(
                'with_front' => false,
                'slug'       => 'programme_faq'
            )
        );
        register_post_type('programme_faq', $args);
    }
    add_action('init', 'register_cpt_programme_faq');
    
    // 2a. meta box - add a custom meta box on the Programme FAQ edit page
    function pfaq_add_meta_boxes($post)
    {
        add_meta_box('pfaq-parent', 'Parent Programme', 'pfaq_parent_meta_box', $post->post_type, 'side', 'core');
    }
    add_action('add_meta_boxes_programme_faq', 'pfaq_add_meta_boxes');
    
    // 2b. select box - add a select input inside the Parent Programme meta box
    function pfaq_parent_meta_box($post)
    {
        $parents = get_posts(
            array(
                'post_type'   => 'programmes',
                'orderby'     => 'title',
                'order'       => 'ASC',
                'numberposts' => -1
            )
        );
    
        if(!empty($parents))
        {
            echo '<select name="parent_id" class="widefat">';
    
            foreach($parents as $parent)
            {
                printf('<option value="%s"%s>%s</option>', esc_attr($parent->ID), selected($parent->ID, $post->post_parent, false), esc_html($parent->post_title));
            }
    
            echo '</select>';
        }
    }
    
    // 3. rewrite rule - teach WordPress to parse the custom URL pattern
    function pfaq_rewrite_rule()
    {
        add_rewrite_rule('^programmes/([^/]+)/faq/?', 'index.php?programme_faq=$matches[1]-faq', 'top');
    }
    add_action('init', 'pfaq_rewrite_rule');
    
    // 4. permalink - filter all Programme FAQ permalinks to match the desired URL pattern
    function pfaq_post_type_link($post_link, $post, $leavename, $sample)
    {
        if($post->post_type == 'programme_faq')
        {
            $parent = get_post($post->post_parent);
            $post_link = get_bloginfo('url') . '/programmes/' . $parent->post_name . '/faq';
        }
    
        return $post_link;
    }
    add_filter('post_type_link', 'pfaq_post_type_link', 1, 4);
    
    /1a。注册课程职位类型
    功能寄存器\u cpt\u程序()
    {
    $labels=数组(
    “名称”=>“‘程序’、‘文本域’”,
    “单数_名称”=>uu('单个程序名称','文本_域'),
    'add_new'=>_x('add program','${4:Name}','text_domain'),
    'add_new_item'=>_uuu('add program','text_domain}'),
    “编辑项目”=>“‘编辑此程序’、‘文本域’”,
    “新项目”=>“‘新程序’、‘文本域’”,
    “查看项目”=>“‘查看程序’、‘文本域’”,
    “搜索项目”=>“‘搜索程序’、‘文本域’”,
    “未找到”=>“‘未找到程序’、‘文本域’”,
    'not_found_in_trash'=>,
    'parent_item_colon'=>'('parent single post type name:','text_domain'),
    “菜单名称”=>“‘程序’、‘文本域’”,
    );
    $args=数组(
    “标签”=>$labels,
    “分层”=>false,
    “说明”=>“说明”,
    “public”=>正确,
    'show_ui'=>true,
    “在菜单中显示”=>true,
    “菜单位置”=>5,
    “在导航菜单中显示”=>true,
    “公开可查询”=>正确,
    “从搜索中排除”=>false,
    “has_archive”=>true,
    'query_var'=>true,
    “can_export”=>true,
    “重写”=>正确,
    “能力类型”=>“页面”,
    '支持'=>数组(
    “头衔”,
    "编辑",,
    “作者”,
    “页面属性”,
    “缩略图”,
    "摘录",,
    “自定义字段”,
    "修订",,
    “评论”
    ),
    “重写”=>数组(
    'with_front'=>false,
    “slug”=>“程序”
    )
    );
    注册后类型('programmes',$args);
    }
    添加行动(“初始”、“注册”cpt“计划”);
    //1b。注册节目常见问题帖子类型
    功能寄存器\u cpt\u程序\u常见问题解答()
    {
    $labels=数组(
    “名称”=>“‘程序常见问题解答’、‘文本域’”,
    “单数_名称”=>uuuuuu(“单一程序常见问题解答”、“文本_域”),
    'add_new'=>_x('add program FAQ'、'${4:Name}、'text_domain'),
    'add_new_item'=>uuuu('add program FAQ','text_domain}'),
    “编辑项目”=>“‘编辑此节目常见问题解答’、‘文本域’”,
    “新项目”=>“‘新计划常见问题解答’、‘文本域’”,
    “查看项目”=>“(“查看节目常见问题”、“文本域”),
    “搜索项目”=>“‘搜索程序常见问题解答’、‘文本域’”,
    “未找到”=>“‘未找到程序常见问题解答’、‘文本域’”,
    “未在垃圾箱中找到”=>“‘在垃圾箱中找不到程序常见问题解答’、‘文本域’”,
    'parent_item_colon'=>'('parent single post type name:','text_domain'),
    “菜单名称”=>“‘程序常见问题解答’、‘文本域’”,
    );
    $args=数组(
    “标签”=>$labels,
    “分层”=>false,
    “说明”=>“说明”,
    “public”=>正确,
    'show_ui'=>true,
    “在菜单中显示”=>true,
    “菜单位置”=>5,
    “在导航菜单中显示”=>true,
    “公开可查询”=>正确,
    “从搜索中排除”=>false,
    “has_archive”=>true,
    'query_var'=>true,
    “can_export”=>true,
    “重写”=>正确,
    “能力类型”=>“页面”,
    '支持'=>数组(
    “头衔”,
    "编辑",,
    “作者”,
    “页面属性”,
    “缩略图”,
    "摘录",,
    “自定义字段”,
    "修订",,
    “评论”
    ),
    “重写”=>数组(
    'with_front'=>false,
    “slug”=>“节目常见问题”
    )
    );
    注册\发布\类型('Program\ u faq',$args);
    }
    添加行动(“初始”、“注册”cpt“计划”faq);
    //2a。元框-在程序FAQ编辑页面上添加自定义元框
    函数pfaq_add