当然,已经有大神做出来了牛逼闪闪的插件,但我不想用······如果想和我一样手动修改文件的朋友继续看,否则请移步wp官网插件介绍页:Custom Field Template 。
先上我弄好的图吧,毕竟有图才有真相!首先是后台效果:

接着是前台显示效果,缩略图是另外调用的,可以忽略:

其实方法很简单,只要修改模板里的函数文件 functions.php,以及前台调用的页面模板即可。下面我先介绍笼统的做法。
一、定义 myCustomFields 类
- if ( !class_exists(‘myCustomFields’) ) {
- class myCustomFields {
- /**
- * @var string $prefix 自定义栏目名的前缀
- */
- var $prefix = ’mcf_’;
- /**
- * @var array $postTypes 包含了标准的“文章”、“页面”和自定义文章类型的数组,自定义栏目面板将出现在这些文章类型中
- */
- var $postTypes = array( “page”, “post” );
注意:如果自定义栏目名是以下划线(_)开头的,它将在 WordPress 自带的“自定义栏目”面板中隐藏。如果想保留 WordPress 自带“自定义栏目”面板,建议使用这个方法。
二、定义所有的自定义栏目
- /**
- * @var array $customFields 定义了所有的自定义栏目
- */
- var $customFields = array(
- array(
- “name” => “block-of-text”,
- “title” => “多行文本”,
- “description” => “”,
- “type” => “textarea”,
- “scope” => array( “page” ),
- “capability” => “edit_pages”
- ),
- array(
- “name” => “short-text”,
- “title” => “单行文本”,
- “description” => “”,
- “type” => “text”,
- “scope” => array( “post” ),
- “capability” => “edit_posts”
- ),
- array(
- “name” => “checkbox”,
- “title” => “复选框”,
- “description” => “”,
- “type” => “checkbox”,
- “scope” => array( “post”, “page” ),
- “capability” => “manage_options”
- )
- );
所有的自定义栏目都应该写在这里,当然要遵循这样的格式,不过这里只给出了单行文本框、多行文本框、富文本框、复选框四种类型,您可以在稍后自由添加(像我自己写的,就是一直重复“单行文本”的代码)。每一个字段包含的值为:
- 01: name: 自定义栏目的名称。这个名称将加上前缀存储在数据库中;
- title : 用于显示在自定义栏目面板的标题;
- description : 显示在每个自定义栏目的下方,给出提示;
- type : 定义了显示的类型,默认为单行文本(text);
- scope : 定义了每个自定义栏目的作用范围,例如 post 文章、page 页面;
- capability : 定义了编辑每个自定义栏目需要的权限,如果对此不太了解,参见这篇文章:《Users, roles, and capabilities in WordPress》。
三、用于初始化的相关函数
- /**
- * 用于兼容 PHP 4 的构造函数
- */
- function myCustomFields() { $this->__construct(); }
- /**
- * 用于 PHP 5 的构造函数
- */
- function __construct() {
- add_action( ’admin_menu’, array( &$this, ’createCustomFields’ ) );
- add_action( ’save_post’, array( &$this, ’saveCustomFields’ ), 1, 2 );
- // 如果想要保留 WordPress 自带“自定义栏目”面板,请注释下一行
- add_action( ’do_meta_boxes’, array( &$this, ’removeDefaultCustomFields’ ), 10, 3 );
- }
- /**
- * 移除 WordPress 自带“自定义栏目”面板
- */
- function removeDefaultCustomFields( $type, $context, $post ) {
- foreach ( array( ’normal’, ’advanced’, ’side’ ) as $context ) {
- foreach ( $this->postTypes as $postType ) {
- remove_meta_box( ’postcustom’, $postType, $context );
- }
- }
- }
- /**
- * 创建新的“自定义栏目”面板
- */
- function createCustomFields() {
- if ( function_exists( ’add_meta_box’ ) ) {
- foreach ( $this->postTypes as $postType ) {
- add_meta_box( ’my-custom-fields’, ’Custom Fields’, array( &$this, ’displayCustomFields’ ), $postType, ’normal’, ’high’ );
- }
- }
- }
其中包括了构造函数(注意 PHP 4 与 PHP 5 承认的构造函数并不相同,而 PHP 4 似乎没有析构函数),向 admin_menu 添加钩子以显示自定义栏目面板,向 save_post 添加钩子以在文章保存时也能保存自定义栏目中的信息,向 do_meta_boxes 添加钩子以移除 WordPress 自带“自定义栏目”面板(如果不需要可以将之注释)。
四、权限检查
- /**
- * 显示新的“自定义栏目”面板
- */
- function displayCustomFields() {
- global $post;
- ?>
- <div>
- <?php
- wp_nonce_field( ’my-custom-fields’, ’my-custom-fields_wpnonce’, false, true );
- foreach ( $this->customFields as $customField ) {
- // 范围检查
- $scope = $customField[ 'scope' ];
- $output = false;
- foreach ( $scope as $scopeItem ) {
- // 原作者在此处使用了 switch,估计是修改时忘记删掉了
- if ( $post->post_type == $scopeItem ) {
- $output = true;
- break;
- }
- }
- // 权限检查
- if ( !current_user_can( $customField['capability'], $post->ID ) )
- $output = false;
这一段是显示新的“自定义面板”的函数 displayCustomFields(),wp_nonce_field() 函数生成了一个包含随机数的隐藏字段,用于检查提交的内容来自合法的位置。首先检查的是自定义栏目的作用范围,如注释中所述,原作者在此处使用了 switch,估计是修改时忘记删掉了(因为前一个版本检查方式与现在有一些差别)。接着检查的是权限,检查通过后才会显示这个自定义栏目。
五、输出自定义栏目
- // 如果允许,则输出
- if ( $output ) { ?>
- <div>
- <?php
- switch ( $customField[ 'type' ] ) {
- case “checkbox”: {
- // 输出复选框
- echo ’<label for=“‘ . $this->prefix . $customField[ 'name' ] .’” style=“display:inline;”><b>’ . $customField[ 'title' ] . ’</b></label> ’;
- echo ’<input type=“checkbox” name=“‘ . $this->prefix . $customField['name'] . ’” id=“‘ . $this->prefix . $customField['name'] . ’” value=“yes”‘;
- if ( get_post_meta( $post->ID, $this->prefix . $customField['name'], true ) == “yes” )
- echo ’ checked=“checked”‘;
- echo ’“ style=”width: auto;“ />’;
- break;
- }
- case ”textarea“:
- case ”wysiwyg“: {
- // 输出多行文本框
- echo ’<label for=”‘ . $this->prefix . $customField[ 'name' ] .’“><b>’ . $customField[ 'title' ] . ’</b></label>’;
- echo ’<textarea name=”‘ . $this->prefix . $customField[ 'name' ] . ’“ id=”‘ . $this->prefix . $customField[ 'name' ] . ’“ columns=”30“ rows=”3“>’ . htmlspecialchars( get_post_meta( $post->ID, $this->prefix . $customField[ 'name' ], true ) ) . ’</textarea>’;
- // 输出富文本编辑框
- if ( $customField[ 'type' ] == ”wysiwyg“ ) { ?>
- <script type=”text/javascript“>
- jQuery( document ).ready( function() {
- jQuery( ”<?php echo $this->prefix . $customField[ 'name' ]; ?>“ ).addClass( ”mceEditor“ );
- if ( typeof( tinyMCE ) == ”object“ && typeof( tinyMCE.execCommand ) == ”function“ ) {
- tinyMCE.execCommand( ”mceAddControl“, false, ”<?php echo $this->prefix . $customField[ 'name' ]; ?>“ );
- }
- });
- </script>
- <?php }
- break;
- }
- default: {
- // 输出单行文本框
- echo ’<label for=”‘ . $this->prefix . $customField[ 'name' ] .’“><b>’ . $customField[ 'title' ] . ’</b></label>’;
- echo ’<input type=”text“ name=”‘ . $this->prefix . $customField[ 'name' ] . ’“ id=”‘ . $this->prefix . $customField[ 'name' ] . ’“ value=”‘ . htmlspecialchars( get_post_meta( $post->ID, $this->prefix . $customField[ 'name' ], true ) ) . ’” />’;
- break;
- }
- }
- ?>
- <?php if ( $customField[ 'description' ] ) echo ’<p>’ . $customField[ 'description' ] . ’</p>’; ?>
- </div>
- <?php
- }
- } ?>
- </div>
- <?php>
如果要添加新的显示类型,就是这里了。默认的展现形式是很烂的······大家可以稍微用style来定义下展现样式,以及p标签和b标签。
六、保存自定义栏目的值
- /**
- * 保存自定义栏目的值
- */
- function saveCustomFields( $post_id, $post ) {
- if ( !wp_verify_nonce( $_POST[ 'my-custom-fields_wpnonce' ], ’my-custom-fields’ ) )
- return;
- if ( !current_user_can( ’edit_post’, $post_id ) )
- return;
- if ( ! in_array( $post->post_type, $this->postTypes ) )
- return;
- foreach ( $this->customFields as $customField ) {
- if ( current_user_can( $customField['capability'], $post_id ) ) {
- if ( isset( $_POST[ $this->prefix . $customField['name'] ] ) && trim( $_POST[ $this->prefix . $customField['name'] ] ) ) {
- $value = $_POST[ $this->prefix . $customField['name'] ];
- // 为富文本框的文本自动分段
- if ( $customField['type'] == “wysiwyg” ) $value = wpautop( $value );
- update_post_meta( $post_id, $this->prefix . $customField[ 'name' ], $value );
- } else {
- delete_post_meta( $post_id, $this->prefix . $customField[ 'name' ] );
- }
- }
- }
- }
- } // End Class
- } // End if class exists statement
- // 实例化类
- if ( class_exists(‘myCustomFields’) ) {
- $myCustomFields_var = new myCustomFields();
- }
wp_verify_nonce验证了提交的数据是否可信。
七、完整代码:
请进入下一页进行查看,谢谢。