WordPress插件开发教程手册 — 自定义文章类型

WordPress的自定义文章类型存储在 wp_psots 数据表中,开发人员可以注册自己的文章类型。本章节中,我们将讨论如何注册自定义文章类型,如何从数据库中获取自定义文章类型内容,以及如何把这些内容显示给用户

为什么使用自定义文章类型

自定义文章类型也可以成为自定义内容类型,可以把不同类型的文章区分开,方便管理。

不同的文章类型往往有不同的字段、适合的内容展示模版也不一样。WordPress基于自定义文章类型把不同类型的文章在程序上做了区分,我们可以为自定义文章类型设置单独的自定义Metabox,设置独立的自定义分类方法,也可以很方面的为其设置自定义模版。

注册自定义文章类型

WordPress 默认有 5 种文章类型:post, page, attachment, revision, menu。我们开发插件时,可能需要创建自定义文章类型,例如,电子商务网站中的 「产品」,在线学习网站中的 「作业」或者视频网站中的 「电影」。

我们可以使用 register_post_type() 函数来注册自定义文章类型,注册之后,WordPress 会自动帮我们添加一个新文章类型菜单到后台,我们可以通过这个菜单管理和创建文章。

建议在插件而不是主题中创建自定义文章类型,这样,如果我们更换了主题,文章类型还会存在。

以下示例将在数据库中创建名称为 “产品” 的自定义文章类型 “wporg_product”。

function wporg_custom_post_type() {
   register_post_type( 'wporg_product',
      [
         'labels'      => [
            'name'          => __( 'Products' ),
            'singular_name' => __( 'Product' ),
         ],
         'public'      => true,
         'has_archive' => true,
      ]
   );
}

add_action( 'init', 'wporg_custom_post_type' );

请参考 register_post_type() 的函数说明以查看所有参数。

我们必须在 admin_init 钩子之前,after_setup_theme 之后调用 register_post_type(),一个比较好的选择是 init 钩子。

命名最佳实践

在文章类型名称前面加一个主题或插件名称作为前缀是一个比较好的做法,这样可以避免与其他插件产生冲突,也可以让其他开发者了解该文章类型的来源。

为了确保向前兼容,请不要使用 wp_ 作为文章类型前缀,WordPress 核心使用了这个前缀。确保自定义文章类型名称不超过 20 个字符,因为在post_type数据库中,该列是长度为 20 的 VARCHAR 字段。如果我们使用的名称过于通用-例如:product。可能会与其他插件或主题冲突。

网址

如果我们需要为自定义文章类型设置一个别名,可以在 register_post_type() 的 rewrite 参数中添加一个 key => value 键值对。如下:

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

add_action( 'init', 'wporg_custom_post_type' );

使用上面代码创建的自定义文章类型的 URL 结构为:http://example.com/products/%product_name%

使用过于通用的别名可能会与其他主题或插件产生冲突。
与自定义文章类型标识符不同,我们可以通过更改其中一个冲突文章类型的 slug,轻松解决文章类型 slug 冲突的问题。如果插件作者足够聪明,可以在参数中使用 apply_filters() 创建一个自定义 Filter 钩子,然后其他开发者可以通过这个钩子重写 register_post_type() 的参数完成这个操作。我们没有办法在不禁用一个冲突的文章类型的前提下来解决文章类型标识符冲突的问题。

使用自定义文章类型

我们可以为自定义文章类型创建模版,也可以使用 single.php 和 archive.php 显示文章内容和存档,自定义文章类型模版的创建方法如下:

  • single- {post_type} .php – 用于自定义文章类型类型内容的模版
  • archive- {post_type} .php – 用于显示自定义文章类型文章列表的模版

其中 {post_type}是 register_post_type() 函数的 $post_type 参数。

例如,我们可以为“wporg_product” 文章类型创建 single-wporg_product.php 文章类型内容模版和 archive-wporg_product.php 存档模版。

或者,我们可以在任何模版文件中使用 is_post_type_archive() 函数来检查当前页面是否为指定文章类型存档页面,然后使用 post_type_archive_title() 函数来了显示自定义文章类型标题。

通过自定义文章类型参数查询文章

我们可以使用 post_type 参数通过 WP_Query 来查询指定文章类型的文章,如:

$args = [
   'post_type'      => 'product',
   'posts_per_page' => 10,
];
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) {
   $loop->the_post();
   ?>
    <div class=entry-content>
      <?php the_title(); ?>
      <?php the_content(); ?>
    </div>
   <?php
}

上面的查询获取最新 10 个产品文章,并逐个显示他们的标题和内容。

修改主查询

注册自定义文章类型并不会自动添加到主查询中,如果我们需要把自定义文章类型显示在默认存档上,或者包含在其他文章类型存档页面,我们可以使用 pre_get_posts Action 钩子修改主查询,把自定义文章类型参数添加到主查询上,如下:

function wporg_add_custom_post_types( $query ) {
    if ( is_home() && $query->is_main_query() ) {
        $query->set( 'post_type', [ 'post', 'page', 'movie' ] );
    }

    return $query;
}

add_action( 'pre_get_posts', 'wporg_add_custom_post_types' );

我们提供 WordPress主题和插件定制开发服务

本站长期承接 WordPress主题、插件、基于 WooCommerce 的商店商城开发业务。 我们有 10 年WordPress开发经验,如果你想 用WordPress开发网站, 请联系微信: iwillhappy1314,或邮箱: amos@wpcio.com 咨询。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

*