WordPress 3.0中的自定义帖子类型
本文与WordPress3.0相关。此处发布的许多代码在以前的版本中将不起作用,并且某些信息可能会在较新的版本中更改。
WordPress已经在系统中内置了五种不同的内容类型。
帖子
这是标准的内容类型,通常是博客安装中使用最多的内容。帖子往往会汇总到页面上,但并非总是如此。
页数
这是静态内容类型,用于显示未聚合的页面。
附件
每次您通过WordPress上传文件时,都会在该区域存储记录。您可以转到管理区域中的“媒体”菜单项来查看此文件列表。这是在编辑帖子屏幕中的“添加和图像”对话框中单击“媒体库”选项卡时使用的。
修订版
每次在WordPress中保存帖子时,它都会创建该帖子的修订版,这些修订版将作为内容类型。修订仅显示与它们链接到的帖子有关,因此它们不会出现在管理菜单中。也可以停止WordPress创建它们。
导航菜单项
WordPress3.0具有出色的菜单编辑界面,该界面内部使用名为nav_menu_item的自定义帖子类型来创建菜单链接。
在整个这篇文章中,我将普通的WordPress帖子称为帖子,将自定义帖子类型称为自定义内容类型。这是为了避免在我提到帖子时对我的意思造成任何混淆。
从WordPress3.0开始,现在可以创建自己的自定义内容类型。WordPress提供了各种功能,可让您以不同的方式设置不同的内容类型,该功能取自系统中已经可用的其他内容类型。自定义内容类型还可以让您以比以前单独使用类别更好的方式来组织内容。结合这两个功能,意味着您可以为不同类型的不同事物添加信息框,以使它们不会全部出现在同一表单上,并且您必须花费一些时间来教育用户如何使用它。
尽管自beta版本发布以来,自定义内容类型已在WordPress3.0中提供,但我发现基础代码已发生太大变化,无法撰写有关该主题的文章。因此,我一直等到该功能上线之前,再专注于它。
通过使用该register_post_type()功能,可以创建自定义内容类型。此函数有两个参数,第一个是内容类型的机器可读名称,第二个是该内容类型的选项数组。有很多选项可供选择,但我们将简要介绍一下。要创建一个非常简单的内容类型,您可以使用以下代码,将其作为模块的一部分或作为主题使用。
//为该函数创建一个钩子,该钩子将添加我们的custompost类型。 add_action('init', 'create_custompost'); function create_custompost(){ //运行初始化操作时运行。 $customPost = new Custompost(); } class Custompost{ public function __construct(){ //注册自定义帖子类型 register_post_type('custompost', array( 'public' => true, //在adminui中显示帖子类型,并允许前端查询 ) ); } }
我们在这里所做的是创建一个名为“custompost”的自定义内容类型,并将公共状态设置为true。将public值设置为true是将许多其他选项设置为true的捷径,它将使该类型出现在管理界面和网站前端的搜索结果或单个页面中。现在,您将在管理界面左上角的评论项目附近看到另一个名为Posts的菜单项。在此菜单中,您将看到与文章和页面相同的表格列表,以及带有“添加新内容”的菜单项。单击“添加新项”将带您进入常规的创建帖子表单,但仅具有“标题”和“正文”表单元素的默认设置。激活后,新的自定义内容类型就是这样。
当然,拥有两个名为Posts的菜单项完全令人困惑,但是更改此菜单并不困难。我们需要做的就是在options数组中设置标签项。标签项目采用字符串数组,每个项目都与在管理员或前端内的特定上下文中该项目将被调用的内容有关。这里所需的最低限度是名称项,您可以如下设置。
//为简洁起见,删除了代码 register_post_type('custompost', array( 'public' => true, //在adminui中显示帖子类型,并允许前端查询 'labels' => array( 'name' => __('Custom Posts') ), ) ); //为简洁起见,删除了代码
这是可在标签阵列中使用的所有标签项目的列表。
name:这是帖子类型的通用名称,通常以复数形式显示。如果自定义内容类型为层次结构,则默认值为Page,否则为Post。这种分层命名是其余标签的典型名称。
singular_name:此帖子类型的一个对象的名称。默认值为“帖子/页面”。
add_new:对于分层(即页面)和非分层(即帖子)类型,默认均为“添加新项”。
add_new_item:创建新帖子时显示的标题。默认为添加新帖子/添加新页面
edit_item:编辑帖子时显示的标题。默认值为“编辑帖子/编辑页面”
new_item:这显示在admin菜单和admin标头的“收藏夹”菜单中。默认为新帖子/新页面
view_item:这是帖子页面上永久链接控件右侧的按钮标签,您可以通过该按钮查看帖子。默认值为“查看帖子/查看页面”
search_items:这是列表式帖子管理页面上搜索按钮的标签。默认为搜索帖子/搜索页面
not_found:在管理页面中未找到任何帖子时显示。默认为“未找到帖子/未找到页面”
not_found_in_trash:如果未找到帖子,则显示在垃圾箱页面上。默认值为“垃圾箱”中没有找到帖子/“垃圾箱”中没有找到页面
parent_item_colon:这是编辑帖子页面上父页面控件的标签。此字符串不用于非分层类型。在分层结构中,默认值为父页面:
如果您想确切查看这些标签在WordPress安装中的位置,则可以在register_post_type()声明中使用以下标签数组。请记住,仅当项目是分层的时才使用parent_item_colon。
'labels' => array( 'name' => __('name'), 'singular_name' => __('singular_name'), 'add_new' => __('add_new'), 'add_new_item' => __('add_new_item'), 'edit_item' => __('edit_item'), 'new_item' => __('new_item'), 'view_item' => __('view_item'), 'search_items' => __('search_items'), 'not_found' => __('not_found'), 'not_found_in_trash' => __('not_found_in_trash'), 'parent_item_colon' => __('parent_item_colon'), )
以这种方式设置标签后,编辑页面就是这样。
还有许多其他项目可以控制自定义内容类型的行为,我在这里逐一介绍了所有内容,并提供了完整的描述及其使用示例。
description
此设置使您可以添加有关自定义内容类型的简短描述性摘要。这不会出现在默认的WordPress安装中,您将需要使用其他一些插件设置来显示此文本。默认为空白。
'description'=>__('Somedescriptionaboutthecontenttype'),
public
此设置控制网站中内容类型在管理员和前端中的可见性。将此设置为true会将其他三个设置都设置为true,除非它们是分别设置的。这些设置是show_ui,excluded_from_search和publicly_queryable。
'public'=>true,
show_ui这将创建所有管理界面,例如添加和编辑帖子屏幕,管理部分中的菜单项以及列表列表。如果将其设置为false,则不会显示任何管理界面。在某些情况下,当您想创建用户无法直接编辑的内容类型时,这可能会很有用。
exclude_from_search告诉WordPress是否从搜索结果中排除内容类型。将此设置或公共设置设置为true都会导致此类型显示在前端的搜索结果页面中。
可以在网站的前端运行publicly_queryable帖子类型查询,以生成内容列表。如果将其设置为false,则可以禁用此功能。
'show_ui' => true, 'exclude_from_search' => true, 'publicly_queryable' => true,
menu_position
管理区域右侧的每个主菜单项(例如,帖子,用户)都有一个编号。这些数字在Dashboard链接上从0开始,并以5的块数递增到顶部。重要的是要注意,“注释”(菜单位置25)和“外观”(菜单位置60)菜单项之间存在间隙。下表显示了您需要使用的菜单位置。
因此,要使您的自定义帖子类型的菜单显示在“页面”菜单项的下方,您可以将此设置的值设置为20。要将菜单项放置在“工具”菜单的下面,请将该设置的值设置为75。此设置的默认值为使其出现在“评论”菜单项下方。
'menu_position'=>30
menu_icon
这是将菜单项添加到管理菜单时将使用的图像的URL。默认情况下使用帖子图标,这是一个小图钉。您的自定义图标可能会在您的插件目录中,因此要生成指向它的链接,您可以执行以下操作。
'menu_icon'=>WP_CONTENT_URL.'/plugins/'.plugin_basename(dirname(__FILE__)).'/images/customcontent.png'
capability_type
这是一个字符串,将在检查查看哪些用户有权读取,编辑和删除此自定义内容类型时使用。此设置默认为“发布”,但与功能设置结合使用以创建自定义功能。
'capability_type'=>'custompost'
功能
这是一个字符串数组,用于告诉WordPress不同的用户在此内容类型方面具有哪些功能。如果设置了capablity_type设置,则将使用该设置来设置每个设置。例如,edit_custompost用于需要编辑自定义帖子内容类型的用户。如果您想更好地控制用户可以使用自定义内容类型执行哪些操作,并且不想使用默认的WordPress功能,则可以创建功能。可用功能如下。
edit_post:这是一种元功能,允许用户编辑此内容类型的特定项目。默认为“edit_。$capability_type”(edit_post)。
edit_posts:此功能控制此内容类型的对象的编辑。默认为“edit_。$capability_type。s”(edit_posts)。
edit_others_posts:这控制了其他用户创建的内容类型项的编辑。默认为“edit_others_。$capability_type。s”(edit_others_posts)。
publish_posts:允许用户发布此内容类型的项目。默认为“publish_。$capability_type。s”(publish_posts)。
read_post:此功能控制是否允许用户阅读此内容类型的项目。默认为“read_。$capability_type”(read_post)。
read_private_posts:这控制对这种内容类型的私有物品的访问。默认为“read_private。$capability_type。s”(read_private_posts)。
delete_post:此功能允许用户删除此内容类型的项目。默认为“delete_。$capability_type”(delete_post)。
同时使用capability_type和capability,意味着您可以为自定义内容类型创建非常特定的权限模型。不幸的是,您将需要安装单独的插件,以允许站点管理员按角色设置这些权限。
分层的
如果为true,则导致内容类型充当具有分层结构的页面,如果为false,则充当帖子。将其设置为true将对类型的其他方面(例如某些标签)产生影响。默认为false。
'hierarchical'=>true
支持
在add_post_type_support()创建内容类型之后可以使用该功能,以便为该内容类型添加不同的功能。此设置是使用该功能的快捷方式。要使用支持,您需要向其传递项目数组,每个项目都是一个字符串,它将在编辑内容类型页面上添加某个项目。也可以同时使用功能和支持项来设置帖子中可用的字段。这是可用的不同控件的列表。
这里要注意的一件事是该add_post_type_support()功能不影响标题或内容编辑区域,这些项目仅受supports设置数组影响。此项目的默认设置为“无”,这在内部意味着仅显示标题和内容编辑区域。
您可能会注意到上面的列表中缺少类别。这些是使用分类法设置设置的,不受支持设置的控制。
'supports' => array( 'title', 'editor', 'comments', 'revisions', 'trackbacks', 'author', 'excerpt', 'page-attributes', 'thumbnail', 'custom-fields', ),
添加了所有支持项目后,我们的编辑页面将如下所示。
缺少的一件事是修订框,如下图所示。WordPress不仅显示此框,而且还包含有关修订的周围功能,例如差异。
register_meta_box_cb
有两种方法可以将meta框添加到自定义帖子类型中。第一个是通过使用此设置,第二个是在创建内容类型后使用标准的meta框功能。但是,它们都使用相同的函数调用,因此两者之间几乎没有区别。
register_meta_box_cb设置是对函数的回调,该函数在为编辑表单设置元框时将被调用。在此函数中,您可以使用该add_meta_box()函数向该内容类型注册元框。
'register_meta_box_cb'=>'addMeta'
您可以使用add_action添加对同一函数的调用,如下所示:
add_action('admin_menu','addMeta');
从这时起,这两种机制将以完全相同的方式工作。该addMeta()是一个函数,你定义将调用add_meta_box()函数的寄存器与您的内容类型元框。在此调用中,您还将包括一个操作,该操作告诉WordPress保存内容类型时要调用什么函数,从而使您能够保存元内容。这是一个实际的简单例子add_meta_box()。
function addMeta(){ add_meta_box('myplugin_sectionid', __( 'My Post Section Title', 'myplugin_textdomain'), 'addMetaContent', 'custompost', 'advanced' ); add_action('save_post', 'saveMetaContent'); }
如果您以常规方式创建了元框创建功能,那么您会发现框显示为正常,但是保存功能未运行。这是因为register_meta_box_cb设置会注册一个操作,该操作将在显示编辑帖子表单之前运行。现在注册表单的保存动作为时已晚,因此解决方案是在创建自定义内容类型以与save_post动作集成之后添加一个额外的动作。如果您使用register_meta_box_cb设置,则在register_post_type()函数调用下方的位置包含以下代码。
add_action('save_post','saveMetaContent');
该add_meta_box()函数创建对另一个函数的调用,该函数会将元数据表单添加到自定义内容类型编辑表单的内容中。在此示例中,我将此函数称为addMetaContent()。
function addMetaContent(){ $args = func_get_args(); $currentObject = $args[0]; echo ''; //$metaContent = get_metadata('custompost', $currentObject->ID, 'custompost_subtitle', true); //$metaContent = get_post_meta($currentObject->ID, 'custompost_subtitle', true); $metaContent = get_metadata('post', $currentObject->ID, 'custompost_subtitle', true); //数据输入的实际字段 echo ' '; echo ''; }
在适当位置设置此函数调用后,我们的编辑页面现在如下所示。
此代码将需要元数据的当前值才能将其加载到内容中。有三种在WordPress中加载(和保存)元数据的单独方法,以上均已使用了所有方法,但只有一种处于活动状态。在WordPress中加载和保存元数据的通常方法是使用该get_post_meta()功能。此函数将始终使用wp_postmeta表(取决于前缀)来加载帖子和页面的元数据值。该get_metadata()功能与该功能具有相同的作用get_post_meta(),但是该功能的第一个参数是用于从中加载元数据的表的名称。因此,在上面的代码中,可以从名为wp_custompost的表中加载元数据值,而不是使用wp_postmeta表。
我应该注意,在依赖表之前确保表存在很重要,因为get_metadata()如果表不存在,该函数将返回false值。
调用后,add_meta_box()我还注册了一个动作,saveMetaContent()当WordPress保存帖子时,该动作将调用一个函数(称为)。由于此功能不是特定于内容的,因此我们需要在保存元数据之前检查是否正在处理正确的内容类型。
下面的代码包括三种与内容元数据进行交互的方式,但是仅启用了与wp_postmeta表进行交互的机制。在编写自己的插件时,重要的是选择所需的功能类型并删除其他两项。在插件源代码中包含很多注释的代码是一种不好的做法。
function saveMetaContent($post_id){ //验证正确的帖子类型。 if ($_POST['post_type'] != 'custompost') { return $post_id; } //验证这是否来自我们的屏幕并获得适当的授权, //因为save_post可以在其他时间触发 if (!wp_verify_nonce($_POST['myplugin_noncename'], plugin_basename(__FILE__))) { return $post_id; } //验证这是否是自动保存例程。如果是我们的表格尚未提交,那么我们不想 //做任何事 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return $post_id; } //检查权限 if ('custompost' == $_POST['post_type']) { if (!current_user_can('edit_post', $post_id)) { return $post_id; } } //好的,我们已通过身份验证:我们需要查找并保存数据 //$meta_value=get_metadata('custompost',$post_id,'custompost_subtitle',true); //$meta_value=get_post_meta($post_id,'custompost_subtitle',true); $meta_value = get_metadata('post', $post_id, 'custompost_subtitle', true); $new_meta_value = stripslashes($_POST['custompost_subtitle']); if (!is_null($new_meta_value) && '' == $meta_value) { //add_metadata('custompost',$post_id,'custompost_subtitle',$new_meta_value,true); //add_post_meta($post_id,'custompost_subtitle',$new_meta_value,true); add_metadata('post', $post_id, 'custompost_subtitle', $new_meta_value, true); } elseif ('' == $new_meta_value) { //delete_metadata('custompost',$post_id,'custompost_subtitle',$meta_value); //delete_post_meta($post_id,'custompost_subtitle',$meta_value); delete_metadata('post', $post_id, 'custompost_subtitle', $meta_value); } elseif ($new_meta_value != $meta_value) { //update_metadata('custompost',$post_id,'custompost_subtitle',$new_meta_value); //update_post_meta($post_id,'custompost_subtitle',$new_meta_value); update_metadata('post', $post_id, 'custompost_subtitle', $new_meta_value); } }
分类法
这是将为自定义内容类型注册的分类法标签的数组,默认设置为无分类法。WordPress中用于自定义帖子类型的默认现有类别为post_tag和Categories。都可以使用以下设置。
'taxonomies'=>array('post_tag','category')
分类法也可以使用register_taxonomy()或register_taxonomy_for_object_type()功能进行注册。
add_action('init', 'createCustomTaxonomies', 0); function createCustomTaxonomies(){ register_taxonomy('type', 'custompost', array( 'hierarchical' => false, 'label' => __('Type'), 'query_var' => true, 'rewrite' => true ) ); }
然后,您可以使用名称作为参考,以与以前相同的方式注册使用自定义内容类型创建的分类法。
'taxonomies'=>array('post_tag','category','type')
permalink_epmask
此设置允许您为自定义帖子类型设置自己的永久链接掩码。该值的默认设置为EP_PERMALINK。WordPress如何使用这些掩码很复杂,并且可能是另一篇文章的主题。
'permalink_epmask'=>EP_PERMALINK
rewrite
将此设置设置为false可以防止重写自定义内容类型的URL。此设置可以采用一组关联的值,这些值告诉WordPress创建哪种类型的永久链接。默认值是使用内容类型作为参数,尽管可以将其设置为false以防止URL重写。此设置还可以采用一组值来定制永久链接结构。slug值将用作永久链接结构的开始,以便将您的自定义内容URL设置为类似以下内容:
podcasts/my-podcast-post
在重写设置中使用以下值。
'rewrite'=>array('slug'=>'podcasts')
query_var
可以将其设置为false以防止查询,也可以将其设置为用于此帖子类型的query_var值的字符串。
'query_var'=>'custompost',
can_export
这控制是否在导出工具中使用内容类型。如果为true,则它将包含在所有导出输出中,否则将被排除。
'can_export'=>true,
show_in_nav_menus
此控件控制是否可以在WordPress3.0中可用的新导航菜单功能中选择内容类型。通常,只有“页面类型”和“类别”可供选择,但是将其设置为true将使您的内容类型出现在这些菜单中。默认设置为true。
'show_in_nav_menus'=>true,
既然我们有了一个非常简单的自定义内容类型,那么查看它们在WordPress前端的显示方式就很重要。这可能是将内容类型与网站前端集成的最佳观察点。
有几种方法可以打印页面上的帖子列表,这仅取决于您需要执行的操作。如果要显示在特定页面上创建的定制内容类型帖子,则最好使用posts方法页面并传递post_type参数。以下代码可用于创建WP_Query对象,该对象可用于打印出特定类型的所有帖子。
$args = array( 'caller_get_posts' => 1, 'post_type' => 'custompost' ); $my_query = new WP_Query($args);
您可能想要做的另一件事是通过将自定义帖子类型汇总到首页上,从而将它们集成到网站的其余部分中。为此,您需要使用add_filter()函数添加一个过滤器。使用此功能之前,应确保未从站点的admin部分运行代码,因为这可能会导致一些奇怪的问题。下面的代码片段使用该is_admin()函数来确保我们位于站点的前端,然后注册一个函数,该函数getCustomPosts()在从数据库查询帖子之前注册要运行的函数。
if (!is_admin()) { add_filter('pre_get_posts', 'getCustomPosts'); }
该getCustomPosts()函数进行了一些额外的检查,以确保我们不在页面上(否则将不会加载该页面),并且我们正在查看主页,存档页面或类别页面。此函数接收当前的WP_Query对象,该对象会被函数更改为包含我们的自定义内容类型,然后再返回。
function getCustomPosts($query){ if (!is_page() || is_home() || is_archive() || is_category()) { $query->set('post_type', array('post', 'custompost')); } return $query; }
WordPress现在允许的一件事是包含用于特定内容类型的模板。WordPress将使用一个名为的文件single.php来呈现单个帖子的内容。对于自定义内容类型仍然如此,但是WordPress还将查找与您的自定义内容类型相关的模板文件,并优先使用该文件。如果您创建一个名为single-custompost.php的文件,则WordPress将使用该文件来呈现该页面的内容。
关于自定义内容类型,要看的最后一件事是自定义admin部分中的帖子表。我们已经研究了如何更改此页面上可用的不同标签,但是也可以在内容类型中添加列,以便在此表中显示不同的内容。
要与此表进行交互,您需要结合使用过滤器和操作。该过滤器称为manage_edit_
该操作称为manage_posts_custom_column,用于逐个告诉WordPress您在特定列中想要的值。
这是将过滤器添加到WordPress的代码。
add_filter("manage_edit-custompost_columns", "custompostColumns"); add_action("manage_posts_custom_column", "custonpostRowValues");
创建表时,有许多默认列可以覆盖或保留,这些列由过滤器设置。这作为值的关联数组传递给函数,该键的键是列标识符,而值是列的标题。以下是可用的不同默认值的列表。
这些操作由您决定,但是您可以完全覆盖它们,更改一个值,甚至添加它们。以下代码片段显示了将列重置为一组完全不同的值,但保留cb和title的原因,因为这些很有用。这里还要注意的是,我已经分配了一个字段,以带回有关帖子的元数据值。
function custompostColumns($columns) { $columns = array( "cb" => "", "title" => "Title", "description" => "Description", "metavalue" => "MetaValue", ); return $columns; }
使用我们在操作中定义的函数来设置每列的值。此函数将被查看的列的名称作为单个参数接收。所有需要做的就是获取对当前$post对象的引用,该对象将包含我们的自定义类型数据,并将正确的数据打印到正确的位置。
function custonpostRowValues($column) { global $post; switch ($column) { case 'ID': print $post->ID break; case 'description': print $post->post_content break; case 'metavalue': print get_metadata('post', $post->ID, 'custompost_subtitle', true); break; } }
重新加载表以使用自定义内容类型,以查看对该表所做的更改(如果应类似于下图所示)。
自从WordPress3.0测试版发布以来,我一直在研究自定义内容类型,我认为这是一个很好的开始,并且能够将WordPress推向前所未有的高度。我认为可以使许多现有的插件(例如,事件创建插件)使用此系统,而不是使用通常的类别和笨拙的类别隐藏,这往往会导致问题。我能看到的唯一问题是,我们很快将对自定义内容类型充满市场兴趣,其中包含许多用于执行不同(或非常相似)操作的不同插件。
最好创建一个自定义内容类型创建插件,作者可以使用它创建自己的自定义内容类型,而无需编写任何代码。如果包括在内容中添加和删除字段的功能,那也是理想的。这相当于Drupal中的CCK模块,并且将使WordPress作为博客和完善的内容管理系统非常有用。已经发布了一些插件来执行此操作(例如,“自定义页面类型”UI),但它们并没有真正涵盖元数据之类的所有功能。
title:添加文本框,以允许编辑内容类型的标题。
编辑器:添加主要内容编辑区域。
评论:添加一个复选框,允许打开和关闭评论和引用。
修订版:添加了一个控件,允许编辑者查看内容类型的先前修订版。
trackbacks:添加一个文本区域,该区域允许编辑者添加更新帖子时将被ping通的URL。
author:添加一个选择框,允许选择其他作者。
摘录:添加一个文本区域,该摘录允许将摘录附加到内容类型。
page-attributes:这将为分层内容类型添加模板和分层控件。
thumbnail:添加一个控件,该控件允许将缩略图添加到内容类型。
custom-fields:添加允许内容类型的元数据编辑的控件。
cb:这是一个复选框,将用于标识相关帖子。
title:帖子的标题。
author:帖子的作者。
类别:帖子所属的类别。
tags:为帖子设置的标签。
comments:帖子包含的评论数。
日期:相关职位的日期。这将是已发布帖子的发布日期,是草稿帖子的创建日期等。