删除不适用于子页面的自定义POST类型插件

时间:2019-05-07 作者:Andy

我希望我的自定义帖子类型products不要使用slug,例如:domain。com/产品名称。下面的代码很好地解决了这一问题,但它无法处理子页面,例如:域。com/产品名称/产品名称功能,it 404s。

我最初尝试将自定义帖子类型的重写段标为“/”,虽然这对自定义帖子类型很好,但它杀死了普通页面(404)。因此,如果解决方案是使用“/”,然后修复普通页面,也可以。

// Post Type

function base_types() {

    $labels = array(
        \'name\'               => \'Products & Features\',
        \'singular_name\'      => \'Product\',
        \'add_new\'            => \'Add New\',
        \'add_new_item\'       => \'Add New Product / Feature\',
        \'edit_item\'          => \'Edit Product\',
        \'new_item\'           => \'New Product\',
        \'all_items\'          => \'All\',
        \'view_item\'          => \'View Product / Feature\',
        \'search_items\'       => \'Search Product / Feature\',
        \'not_found\'          => \'None found\',
        \'not_found_in_trash\' => \'None found in Trash\',
        \'parent_item_colon\'  => \'\',
        \'menu_name\'          => \'Products / Features\'
    );

    $args = array(
        \'labels\'             => $labels,
        \'public\'             => true,
        \'publicly_queryable\' => true,
        \'show_ui\'            => true,
        \'show_in_menu\'       => true,
        \'query_var\'          => true,
        \'rewrite\'            => array( \'slug\' => \'product\', \'with_front\' => false ),
        \'capability_type\'    => \'page\',
        \'has_archive\'        => false,
        \'hierarchical\'       => true,
        \'menu_position\'      => 10,
        \'with_front\'         => false,
        \'menu_icon\'          => \'dashicons-chart-bar\',
        \'supports\'           => array( \'title\', \'editor\', \'author\', \'page-attributes\' )
    );

    register_post_type( \'product\', $args );

}

add_action( \'init\', \'base_types\' );


// Rewrites

function remove_slug( $post_link, $post, $leavename ) {

    if ( \'product\' != $post->post_type || \'publish\' != $post->post_status ) {
        return $post_link;
    }
    if( $post->post_parent ) {

        $parent = get_post($post->post_parent);
        $post_link = str_replace( \'/\' . $post->post_type . \'/\' . $parent->post_name . \'/\', \'/\' . $parent->post_name . \'/\', $post_link );

    }

    else {

        $post_link = str_replace( \'/\' . $post->post_type . \'/\', \'/\', $post_link );
    }
    return $post_link;
}

add_filter( \'post_type_link\', \'remove_slug\', 10, 3 );


function parse_request( $query ) {

    if ( ! $query->is_main_query() || 2 != count( $query->query ) || ! isset( $query->query[\'page\'] ) ) {
        return;
    }

    if ( ! empty( $query->query[\'name\'] ) ) {
        $query->set( \'post_type\', array( \'post\', \'product\', \'page\' ) );
    }
}

add_action( \'pre_get_posts\', \'parse_request\' );
第一级页面按预期工作。子页面获得了正确的永久链接,但它们是404。

有人能帮忙或指出正确的方向吗?非常感谢。

2 个回复
最合适的回答,由SO网友:Andy 整理而成

这可以通过使用Permalink设置来解决:自定义结构/%post\\u id%/

在其他地方找不到这个答案,所以我自己加了进去。

SO网友:Abhishek R

试试这个。它将替换段塞product 父页和子页都没有404错误。

/**
 * Strip the slug out of a hierarchical custom post type
 */

if ( !class_exists( \'product_Rewrites\' ) ) :

class product_Rewrites {

private static $instance;

public $rules;

private function __construct() {
    /* Don\'t do anything, needs to be initialized via instance() method */
}

public static function instance() {
    if ( ! isset( self::$instance ) ) {
        self::$instance = new product_Rewrites;
        self::$instance->setup();
    }
    return self::$instance;
}

public function setup() {
    add_action( \'init\',                array( $this, \'add_rewrites\' ),            20 );
    add_filter( \'request\',             array( $this, \'check_rewrite_conflicts\' )     );
    add_filter( \'product_rewrite_rules\', array( $this, \'strip_product_rules\' )           );
    add_filter( \'rewrite_rules_array\', array( $this, \'inject_product_rules\' )          );
}

public function add_rewrites() {
    add_rewrite_tag( "%product%", \'(.+?)\', "product=" );
    add_permastruct( \'product\', "%product%", array(
        \'ep_mask\' => EP_PERMALINK
    ) );
}

public function check_rewrite_conflicts( $qv ) {
    if ( isset( $qv[\'product\'] ) ) {
        if ( get_page_by_path( $qv[\'product\'] ) ) {
            $qv = array( \'pagename\' => $qv[\'product\'] );
        }
    }
    return $qv;
}

public function strip_product_rules( $rules ) {
    $this->rules = $rules;
    # We no longer need the attachment rules, so strip them out
    foreach ( $this->rules as $regex => $value ) {
        if ( strpos( $value, \'attachment\' ) )
            unset( $this->rules[ $regex ] );
    }
    return array();
}

public function inject_product_rules( $rules ) {
    # This is the first \'page\' rule
    $offset = array_search( \'(.?.+?)/trackback/?$\', array_keys( $rules ) );
    $page_rules = array_slice( $rules, $offset, null, true );
    $other_rules = array_slice( $rules, 0, $offset, true );
    return array_merge( $other_rules, $this->rules, $page_rules );
}
}

product_Rewrites::instance();

endif;

相关推荐

如何列出带有摘录的子页,例如[Child-Pages Depth=“1”Excerpt=“1”]

我想构建一个快捷码函数来生成父页面的子页面的HTML列表,并包含摘录。类似这样:<ul> <li> <h3>Child Page Title 1</h3> <p>Excerpt 1</p> <li> <li> <h3>Child Page Title 2</h3> <p>Exc