插件开发文档

注册自定义文章类型

💡 云策文档标注

概述

本文档介绍了如何在 WordPress 中注册自定义文章类型,以扩展默认内容类型(如文章、页面),适用于插件开发中创建特定内容类型(如产品、作业或电影)。

关键要点

  • 使用 register_post_type() 函数注册自定义文章类型,推荐在插件中实现以确保内容可移植性。
  • 注册时机应在 after_setup_theme 钩子之后、admin_init 钩子之前,通常使用 init 动作钩子。
  • 命名最佳实践:使用短前缀(避免 wp_)标识函数和类型,确保标识符不超过 20 字符且不通用以防冲突。
  • 自定义文章类型默认获得独立的管理界面和 URL 结构(如 http://example.com/wporg_product/%product_name%),可通过 rewrite 参数自定义 slug。
  • 标识符冲突可能导致无法解决的重复问题,而 slug 冲突可通过修改参数轻松解决。

代码示例

function wporg_custom_post_type() {
	register_post_type('wporg_product',
		array(
			'labels'      => array(
				'name'          => __('Products', 'textdomain'),
				'singular_name' => __('Product', 'textdomain'),
			),
				'public'      => true,
				'has_archive' => true,
		)
	);
}
add_action('init', 'wporg_custom_post_type');

注意事项

  • 避免使用 wp_ 作为标识符前缀,因为它被 WordPress 核心保留。
  • 自定义 slug 应尽量具体,以减少与其他插件或主题的冲突风险。
  • 如果插件作者使用了 apply_filters(),可以通过编程方式覆盖 register_post_type() 的参数来解决 slug 冲突。

📄 原文内容

WordPress comes with five default post types: post, page, attachment, revision, and menu.

While developing your plugin, you may need to create your own specific content type: for example, products for an e-commerce website, assignments for an e-learning website, or movies for a review website.

Using Custom Post Types, you can register your own post type. Once a custom post type is registered, it gets a new top-level administrative screen that can be used to manage and create posts of that type.

To register a new post type, you use the register_post_type() function.

We recommend that you put custom post types in a plugin rather than a theme. This ensures that user content remains portable even if the theme is changed.

The following minimal example registers a new post type, Products, which is identified in the database as wporg_product.

function wporg_custom_post_type() {
	register_post_type('wporg_product',
		array(
			'labels'      => array(
				'name'          => __('Products', 'textdomain'),
				'singular_name' => __('Product', 'textdomain'),
			),
				'public'      => true,
				'has_archive' => true,
		)
	);
}
add_action('init', 'wporg_custom_post_type');

Please visit the reference page for register_post_type() for the description of arguments.

You must call register_post_type() before the <a href="https://developer.wordpress.org/reference/hooks/admin_init/">admin_init</a> hook and after the <a href="https://developer.wordpress.org/reference/hooks/after_setup_theme/">after_setup_theme</a> hook. A good hook to use is the <a href="https://developer.wordpress.org/reference/hooks/init/">init</a> action hook.

Naming Best Practices

It is important that you prefix your post type functions and identifiers with a short prefix that corresponds to your plugin, theme, or website.

Make sure your custom post type identifier does not exceed 20 characters as the post_type column in the database is currently a VARCHAR field of that length.
To ensure forward compatibility, do not use wp_ as your identifier — it is being used by WordPress core.
If your identifier is too generic (for example: “product“), it may conflict with other plugins or themes that have chosen to use that same identifier.
Solving duplicate post type identifiers is not possible without disabling one of the conflicting post types.

URLs

A custom post type gets its own slug within the site URL structure.

A post of type wporg_product will use the following URL structure by default: http://example.com/wporg_product/%product_name%.

wporg_product is the slug of your custom post type and %product_name% is the slug of your particular product.

The final permalink would be: http://example.com/wporg_product/wporg-is-awesome.

You can see the permalink on the edit screen for your custom post type, just like with default post types.

A Custom Slug for a Custom Post Type

To set a custom slug for the slug of your custom post type all you need to do is add a key => value pair to the rewrite key in the register_post_type() arguments array.

Example:

function wporg_custom_post_type() {
	register_post_type('wporg_product',
		array(
			'labels'      => array(
				'name'          => __( 'Products', 'textdomain' ),
				'singular_name' => __( 'Product', 'textdomain' ),
			),
			'public'      => true,
			'has_archive' => true,
			'rewrite'     => array( 'slug' => 'products' ), // my custom slug
		)
	);
}
add_action('init', 'wporg_custom_post_type');

The above will result in the following URL structure: http://example.com/products/%product_name%

Using a generic slug like products can potentially conflict with other plugins or themes, so try to use one that is more specific to your content.
Unlike the custom post type identifiers, the duplicate slug problem can be solved easily by changing the slug for one of the conflicting post types.

If the plugin author included an apply_filters() call on the arguments, this can be done programmatically by overriding the arguments submitted via the register_post_type() function.