如何仅保存特定自定义帖子类型的元数据?


16

我正在尝试根据本教程设置自定义帖子类型。但是,我对如何/在何处实现感到困惑update_post_meta()。本教程建议这种模式:

add_action('save_post', 'save_my_metadata');

function save_my_metadata()
{
    global $post;
    update_post_meta($post->ID, 'my_metadata', $_POST['my_metadata']);
}

哪一个有效,但不幸的是,无论该元数据是否属于此自定义类型,都将元数据添加到每个帖子中。

我已经把上面的内容放进去了functions.php,我猜这可能是问题的一部分。我猜想我需要限制'save_post'操作以仅触发我的自定义类型的帖子。


很好的问题,鲍比·杰克(Bobby Jack),但我能否请您将问题改名为“如何只为特定的自定义帖子类型保存元数据”?因为您的标题太笼统,以至于人们在寻找解决此问题的方法时都无法识别。
MikeSchinkel 2010年

@Mike:完成了(完全同意您的建议,谢谢!)
Bobby Jack

Answers:


18
function save_my_metadata($ID = false, $post = false)
{
    if($post->post_type != 'your_post_type')
        return;
    update_post_meta($ID, 'my_metadata', $_POST['my_metadata']);
}

那应该工作。只需将“ your_post_type”替换为帖子类型的名称即可。同样,鲜为人知的事实:“ save_post”钩子将帖子的ID作为参数传递。

编辑

我更新了功能以反映Jan的评论。谢谢简!


1
它甚至将帖子本身添加为第二个参数,因此您无需使用全局变量。
Jan Fabry

这个解决方案确实有效。我已经在客户项目上使用过它,并且取得了很多成功。
EAMann

辉煌-就像魅力。而且我假设这样做是有意义的:“ if($ post-> post_type =='animal'){update_post_meta($ ID,“ number_of_legs”,$ _POST ['number_of_legs']);} else if($ post-> post_type =='vehicle'){update_post_meta($ ID,“ number_of_wheels”,$ _POST ['number_of_wheels']);} // ...等...处理几种不同的帖子类型?评论的格式化功能不佳!)
Bobby Jack

实际上,对于多个post-type,我建议改用switch语句。标记更少,性能更快,将来更容易添加案例。
EAMann

@EAMann-是的,在编写过程中,我意识到切换会更好,但是注释并不是开始编辑代码的理想之地,所以我很懒;)
Bobby Jack 2010年

4

如果要处理多种帖子类型,建议使用基本的switch语句:

add_action('save_post', 'save_my_metadata');

function save_my_metadata($ID = false, $post = false)
{
    switch($post->post_type) 
    {
        case 'post_type_1':
            // Do stuff for post type 1
            update_post_meta($ID, 'my_metadata', $_POST['my_metadata']); // Example...
            break;
        case 'post_type_2':
            // Do stuff for post type 2
            break;
        default:
            return;
    }
}

情况基本上与相同,if($post->post_type) == 'post_type_1') {}但不需要多个if-else块。default开关中的块处理您的自定义集中未包含帖子类型的情况。


4

@John P Bloch和@EAMann已经给出了很好的答案,所以我的还包括:

  1. 考虑在您的meta_keys前面加上下划线。这样做会将它们从发布后编辑屏幕上显示的自定义字段列表中隐藏起来,即

    函数save_my_metadata($ post_id,$ post = false){
       如果($ post-> post_type =='your_post_type')
          update_post_meta($ post_id,'_my_metadata',$ _POST ['my_metadata']);;
    }
    
    显然,这意味着您还需要一个自定义metabox才能编辑字段。这是上下文的编辑屏幕:



  2. 您可以做的另一件事是添加自己的挂钩,以简化保存特定帖子类型的操作,即您的挂钩可以为“ save_{$post_type}_post”;对于movie职位类型将是save_movie_post。这是您必须添加到主题functions.php文件或某个地方的插件中的内容:

    add_action('save_post','save_custom_post_type_posts',10,2);
    函数save_custom_post_type_posts($ post_id,$ post = false){
       do_action(“ save _ {$ post-> post_type} _post”);
    }
    
    这样,您就可以像这样重写原始代码(包括上面#1的下划线技巧):

    add_action('save_my_postype_post','save_my_postype_metadata',10,2);
    函数save_my_postype_metadata($ post_id,$ post){
        update_post_meta($ post_id,'_my_metadata',$ _POST ['my_metadata']);;
    }

1

就个人而言,我更喜欢遵循以下模式将自定义元处理程序添加到发布类型。通过以下内容,您可以通过调用add_post_type_support('my_post_type','subtitle');仅通过将supports键(在下面的示例中为“ subtitle”)添加到帖子类型的supports数组中,就可以将元支持添加到帖子类型。

class Subtitle_Meta_Handler {
    public function initialize() {
        add_action('add_meta_boxes', array($this, 'add_metabox'), 10, 2);
        add_action('save_post', array($this, 'update'));
    }

    public function add_metabox($post_type, $post)
    {
        if(post_type_supports($post_type, 'subtitle'))
        {
            add_meta_box('subtitle', 'Subtitle', array($this, 'metabox'), $post_type);
        }
    }

    public function metabox($post)
    {
        $subtitle = get_post_meta($post->ID, 'subtitle', true);
        if(!$subtitle)
        {
            $subtitle = '';
        }
        ?>
        <input type="text" style="width: 70%;" value="<?php echo esc_attr($subtitle);?>" name="subtitle" id="subtitle">
        <?php
        wp_nonce_field('update_subtitle', 'subtitle_nonce');
    }

    public function update($post_id)
    {
        if(wp_is_post_autosave($post_id) || wp_is_post_revision($post_id)) {
            return $post_id;
        }
        if(isset($_REQUEST['subtitle_nonce']) && wp_verify_nonce($_REQUEST['subtitle_nonce'], 'update_subtitle')) {
            $subtitle = trim(strip_tags($_REQUEST['subtitle'], '<b><strong><span><a>'));
            if(empty($subtitle)) {
                delete_post_meta($post_id, 'subtitle');
            } else {
                update_post_meta($post_id, 'subtitle', $subtitle);
            }
        }
    }
}
add_action('init', array(new Subtitle_Meta_Handler(), 'initialize'));

希望这样的事情很快会被添加到核心中。


0

在更新之前,请检查当前帖子是否属于您的帖子类型。这样可以确保您不保存所有帖子。

您还应该检查输入(在示例中是缺少的),并且紧接着记住,只有在该post-type处于活动状态时才可以添加操作。如果是这种情况,则以后无需检查该帖子类型。

获取帖子类型:get_post_type()$post->post_type;


0

我无法使它工作-不确定我在做什么错-但我试图使用post_updated钩子而不是save_post-因为我希望在更新帖子后插入这些值,以便我可以从其他自定义字段中检索值。

 function update_meta ($ID = false, $post = false) {
  update_post_meta($ID, 'rest_long', 'Test 1');
  update_post_meta($ID, 'rest_lat', 'Test 2');
}

add_action('post_updated', 'update_meta');

没关系-我想通了!
jrutter 2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.