只允许一个具有特定元值的帖子

时间:2015-11-19 作者:Capiedge

我正在使用一个自定义的元字段,来指定哪篇文章将作为特色文章出现在首页。

此元字段是通过ACF声明的真/假值。

我希望这个条件只适用于一篇文章,即当用户将一篇文章声明为“特色”并保存它时,所有其他选中此元值的文章(理论上只有最后一篇)都应该被关闭。

为了实现这一点,我声明了一个附加到“save\\u post”操作的函数,对于旧的特色帖子,该函数会将这个特定的帖子元值变为“false”。

这是我的近似值,但我遗漏了一些东西,因为它根本不起作用。

function only_one_agenda_featured( $post_id ) {

    // If this isn\'t a \'agenda\' post, don\'t update it.
    if ( \'agenda\' != $post->post_type ) {
        return;
    }

    // Stop when it is an autosave
    if (defined(\'DOING_AUTOSAVE\') && DOING_AUTOSAVE) {
        return;
    }

    // Prevent quick edit from clearing custom fields
    if (defined(\'DOING_AJAX\') && DOING_AJAX) {
        return;
    }

    $post_meta_value = get_post_meta( $post_id, \'agenda_featured\', TRUE );

    if ( $post_meta_value == \'1\' ) {
        $args = array(
            \'meta_key\'         => \'agenda_featured\',
            \'meta_value\'       => \'1\',
            \'post_type\'        => \'agenda\',
            \'post__not_in\'     => array($post_id),
            );
        $posts_to_update = get_posts( $args );
        foreach ( $posts_to_update as $post_to_update ) {
            update_post_meta( $post_to_update->ID, \'agenda_featured\', \'0\', \'1\' );
        }
    }
}
add_action( \'save_post\', \'only_one_agenda_featured\' );
任何帮助都将不胜感激。

3 个回复
SO网友:birgire

我希望这个条件只适用于一篇文章,即当用户将一篇文章声明为“特色”并保存它时,所有其他选中此元值的文章(理论上只有最后一篇)都应该被关闭。

然后,您可以尝试将唯一的特色帖子ID保存为选项。

这样就不需要用多个值污染post meta表。

SO网友:s_ha_dum

第一个问题是$post 不在回调的范围内。您需要修改代码以将其引入:

function only_one_agenda_featured( $post_id, $post ) {
  // ...
}
add_action( \'save_post\', \'only_one_agenda_featured\' ,10, 2);
考虑到这种变化,情况应该会更好,但代码过于复杂。除非你需要一段历史agenda_featured 发布时,只需删除旧字段,然后设置新字段。

function only_one_agenda_featured( $post_id, $post ) {

    // If this isn\'t a \'agenda\' post, don\'t update it.
    if ( \'agenda\' != $post->post_type ) {
        return;
    }

    // Stop when it is an autosave
    if (defined(\'DOING_AUTOSAVE\') && DOING_AUTOSAVE) {
        return;
    }

    // Prevent quick edit from clearing custom fields
    if (defined(\'DOING_AJAX\') && DOING_AJAX) {
        return;
    }

    if (!empty($_POST[\'agenda_featured\']) && true == $_POST[\'agenda_featured\']) {
        // delete
        delete_metadata ( \'agenda\', null, \'agenda_featured\', null, true );
        // and insert
        add_post_meta( $post_id, \'agenda_featured\', true);
    }

}
add_action( \'save_post\', \'only_one_agenda_featured\' ,10, 2);
通过使用post-type specific hook:

3580            do_action( "save_post_{$post->post_type}", $post_ID, $post, $update );
类似于:

function only_one_agenda_featured( $post_id, $post ) {

    // Stop when it is an autosave
    if (defined(\'DOING_AUTOSAVE\') && DOING_AUTOSAVE) {
        return;
    }

    // Prevent quick edit from clearing custom fields
    if (defined(\'DOING_AJAX\') && DOING_AJAX) {
        return;
    }

    if (!empty($_POST[\'agenda_featured\']) && true == $_POST[\'agenda_featured\']) {
        // delete
        delete_metadata ( \'agenda\', null, \'agenda_featured\', null, true );
        // and insert
        add_post_meta( $post_id, \'agenda_featured\', true);
    }

}
add_action( \'save_post_agenda\', \'only_one_agenda_featured\' ,10, 2);
使用直接SQL可以使删除/保存更加高效,但我像个好孩子一样坚持使用核心函数;)

SO网友:GigiSan

很抱歉恢复这篇旧帖子,但我也有类似的需求,并对这里发布的答案进行了一些调查。既然我找到了一种工作方式,就让我来分享吧。

我需要的是只有一个question 拥有first_question 已选中ACF标志。答案是建议将其引入选项,但我需要该标志来控制其他ACF字段的可见性。

我为解决方案提供的代码如下:

function update_first_question( $post_id ) {

    // If it\'s not the correct post type
    $post = get_post( $post_id );
    if ( $post->post_type != \'question\' ) {
        return;
    }
    // Stop when it is an autosave
    if (defined(\'DOING_AUTOSAVE\') && DOING_AUTOSAVE) {
        return;
    }
    // Prevent quick edit from clearing custom fields
    if (defined(\'DOING_AJAX\') && DOING_AJAX) {
        return;
    }

    // Check if the post being saved has first_question checked
    if (!empty($_POST[\'acf\'][\'field_5d19b7f96cb7f\']) && $_POST[\'acf\'][\'field_5d19b7f96cb7f\'] == TRUE) {

        // Delete \'first_question\' meta from all posts
        delete_metadata ( \'post\', NULL, \'first_question\', NULL, TRUE );

        // Set \'first_question\' meta for the post bring saved
        add_post_meta( $post_id, \'first_question\', TRUE);

    }

}
add_action( \'acf/save_post\', \'update_first_question\', 5, 2);
发布的答案有什么变化?

  • delete_metadata 不接受自定义帖子类型,因此必须使用\'post\'$_POST 数组,您必须检查acf 使用字段键数组以检查其值,因为我们使用的是ACF字段,所以最好将其挂接到acf/save_post 为了使ACF值$_POST. 钩子函数的优先级应小于10,以便在保存之前使用该值$post, 所以它必须由$post_ids_ha_dum\'s answer. 您需要的是以下内容:

    function only_one_agenda_featured( $post_id ) {
    
        // If it\'s not the correct post type
        $post = get_post( $post_id );
        if ( $post->post_type != \'agenda\' ) {
            return;
        }
        // Stop when it is an autosave
        if (defined(\'DOING_AUTOSAVE\') && DOING_AUTOSAVE) {
            return;
        }
        // Prevent quick edit from clearing custom fields
        if (defined(\'DOING_AJAX\') && DOING_AJAX) {
            return;
        }
    
        // Check if agenda_featured is being checked 
        if (!empty($_POST[\'acf\'][\'field_562100c6cd7ad\']) && $_POST[\'acf\'][\'field_562100c6cd7ad\'] == TRUE) {
            // delete
            delete_metadata ( \'post\', NULL, \'agenda_featured\', NULL, TRUE );
            // and insert
            add_post_meta( $post_id, \'agenda_featured\', TRUE);
        }
    
    }
    add_action( \'acf/save_post\', \'only_one_agenda_featured\' , 5, 2); 
    
    3年后,这可能对OP没有帮助,但我希望它能帮助别人!祝你今天愉快!

相关推荐

列出分类法:如果分类法没有POST,就不要列出分类法--取决于定制的POST-META?

这可能很难解释,我不知道是否有解决办法!?我有一个名为“wr\\u event”的自定义帖子类型和一个名为“event\\u type”的分层自定义分类法。自定义帖子类型有一个元框,用于event_date 并且与此帖子类型关联的所有帖子都按以下方式排序event_date. 我在循环中有一个特殊的条件来查询event_date 已经发生了-在这种情况下,它没有显示,但只列在我的档案中。就像你可以使用wp_list_categories() 我编写了一个自定义函数,它以完全相同的方式列出所有分类术语。现在