十年专注,只做WordPress定制开发一件事

从WordPress的URL中删除自定义文章类型名称

王超
2023-01-08
主题开发
1,085 次

从WordPress的URL中删除自定义文章类型名称

以下文章将向您展示如何在没有插件的情况下从WordPress中的自定义帖子类型中删除别名,方法是向您的网站添加一些自定义代码。

每当您在WordPress中添加新的帖子类型时,各个帖子将具有以下格式的URL:

site.com/post_type_name/post-slug

虽然这可能对各种网站结构有意义,但您可能不希望在 url 中使用帖子类型的 slug。

为什么WordPress在URL中添加自定义文章类型的名称?

WordPress在URL中添加自定义文章类型名称的原因是为了防止不同文章类型之间的冲突。例如:假设您将一张名为“new-york”的图片上传到您的网站,但您还创建了一个名为“places”的自定义帖子类型,其中您的一个帖子带有 slug “New-York”。如果自定义帖子类型没有 slug(places),它最终会得到与图像相同的 url。在这种情况下,您将永远无法查看帖子,而是在尝试访问时显示图像附件页面 site.com/new-york/

如何去除URL中的自定义文章类型的名称?

将此代码段复制并粘贴到您WordPress主题的functions.php文件、自定义插件或通过代码片段插件,然后更改 $this->types 数组,让数组包含要从中删除 slug 的帖子类型的数组。

//从WordPress中的URL中删除自定义帖子类型子域
//WordPress日记、WordPress中文社区
//https://www.wp-diary.com
final class My_Remove_Post_Type_Slugs {

    /**
     * Define our $types variable.
     */
    protected $types = [];

    /**
     * Constructor.
     */
    public function __construct() {

        // CHANGE THIS ARRAY
        $this->types = [
            'team' => 'team',
        ];

        add_filter( 'post_type_link', [ $this, 'post_type_link' ], 10, 3 );
        add_action( 'pre_get_posts', [ $this, 'parse_request' ] );
        add_action( 'template_redirect', [ $this, 'template_redirect' ] );
    }

    /**
     * Remove the post type name from the post type link.
     */
    public function post_type_link( $post_link, $post, $leavename ) {
        $post_type = $post->post_type;

        if ( ! array_key_exists( $post_type, $this->types ) || 'publish' !== $post->post_status ) {
            return $post_link;
        }

        $post_link = str_replace( '/' . $this->types[$post_type] . '/', '/', $post_link );

        return $post_link;
    }

    /**
     * Trick WordPress to allow our post types to render without a custom slug.
     */
    public function parse_request( $query ) {
        if ( ! $query->is_main_query() ) {
            return;
        }

        // Only noop our very specific rewrite rule match.
        if ( 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) {
            return;
        }

        // 'name' will be set if post permalinks are just post_name, otherwise the page rule will match.
        if ( ! empty( $query->query['name'] ) ) {
            $array = [ 'post', 'page' ];
            $array = array_merge( $array, array_keys( $this->types ) );
            $query->set( 'post_type', $array );
        }
    }

    /**
     * Redirect the old URL's with the slugs.
     */
    public function template_redirect() {
        if ( is_admin() || is_preview() || ! is_singular( array_keys( $this->types ) ) ) {
            return;
        }
        $post_permalink = trailingslashit( get_permalink() );
        $current_url    = trailingslashit( $this->get_current_url() );
        $post_slug      = get_post_field( 'post_name', get_post() );
        if ( ( $post_permalink && $current_url )
            && ( $post_permalink !== $current_url )
            && ( false !== strpos( $post_permalink, $post_slug ) && false !== strpos( $current_url, $post_slug ) )
        ) {
            wp_safe_redirect( $post_permalink, 301 );
            exit;
        }
    }

    /**
     * Get the current URL helper method.
     */
    protected function get_current_url() {
        global $wp;
        if ( $wp ) {
            return home_url( add_query_arg( [], $wp->request ) );
        }
    }

}
new My_Remove_Post_Type_Slugs;

根据您的需要修改要删除的自定义文章类型的名称

将代码添加到站点后,您需要进行一些编辑才能使其正常工作。此代码段不会遍历所有帖子类型并删除 slug,因为这效率低下并导致与第三方插件冲突。所以你需要修改代码。

找到以下内容:

// CHANGE THIS ARRAY 
$this->types = [ 
    'team' => 'team',
];

需要修改此数组以包含要修改的帖子类型。请注意,您必须如何将帖子类型名称定义为键,将帖子类型数据域定义为值。虽然WordPress中自定义帖子类型的默认slug是帖子类型名称,但情况可能并非总是如此。因此,为了使代码正常工作,它需要知道每个帖子类型的名称和 slug。

例:

假设您的站点上有以下“cities, states, countries”自定义帖子类型,别名分别是“城市,州,国家”,您的数组将如下所示:

$this->types = [
    'cities'    => 'city',
    'states'    => 'state',
    'countries' => 'country',
];

代码的工作原理?

此类有 3 个主要部分。

  1. 首先,我们挂接到post_type_link,从帖子链接中删除帖子类型名称,这是 get_permaink() 返回的链接。
  2. 其次,我们挂钩pre_get_posts以确保帖子内容将显示。默认情况下,只允许帖子和页面具有没有 cpt slug 的 URL,因此我们需要将我们的帖子类型包含在 post_type 参数中。
  3. 最后,我们挂钩到template_redirect,以便重定向包含帖子类型名称 slug 的帖子类型 URL。这可以防止潜在的 404 错误或重复内容问题。

重要说明

为了使代码正常工作,您需要记住几件事。

重新保存永久链接:将代码添加到网站并对其进行修改以包含帖子类型后,您需要转到“阅读设置”>重新保存永久链接设置,否则将不起作用。

仅在需要时更改URL:通常最好在URL中保留帖子类型的slug以防止冲突,它甚至可以帮助网站结构和SEO。仅当您绝对需要时才删除它们。

WordPress日记主要承接WordPress主题定制开发PSD转WordPressWordPress仿站以及以WordPress为管理后端的小程序、APP,我们一直秉持“做一个项目,交一个朋友”的理念,希望您是我们下一个朋友。如果您有WordPress主题开发需求,可随时联系QQ:919985494 微信:18539976310

搜索

嘿,有问题找我来帮您!