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

时间:2014-11-06 15:31:36

标签: php wordpress rewrite

以下成功地允许我在我的WordPress网站中使用程序计划常见问题解答作为自定义帖子类型,但我正在努力与页面的永久链接。

当我创建一个新的常见问题解答页面时,我将父级设置为程序,这很好,但它似乎无法正常工作。

如果一个程序被称为足球,我会访问domain.com/programmes/football然后我会创建一个名为足球的程序常见问题解答,并将父项设置为该计划的足球和常规赛的永久链接将成为domain.com/programme_faq/football/football

当我尝试访问该页面时,它会显示为404未找到。如果我从常见问题解答页面中删除父选项,那么永久链接将变为domain.com/programme_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.
}

1 个答案:

答案 0 :(得分:2)

这是我第一次回答Stack Overflow。请原谅格式和拼写问题。

<强>概要

代码中记录了达成解决方案的关键步骤。以下是摘要:

  1. 注册自定义帖子类型
  2. 在编辑屏幕上添加“父程序”元框
  3. 添加重写规则,以便WordPress正确解析自定义网址结构
  4. 过滤永久链接,以便正确呈现常见问题解答页面的链接
  5. <强> CODE:

    // 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);
    

    备注:

    我重复了原始问题中的代码,以反映一些重要的变化:

    • 解决方案需要NON-HIERARCHICAL帖子类型
    • 重命名函数以保持一致性
    • 更正了元框代码中的问题
    • 更正了“程序”与功能受影响的“程序”

    选择前缀“pfaq”,因为大多数自定义都围绕“计划常见问题解答”帖子类型。

    <强>学分:

    WordPress核心,WordPress Codex,@ justintadlock,@ tareq_cse