Show ACF fields only on certain page in the backend

I have created some custom fields with Advanced Custom Fields and set them to appear in my custom post type named X (post type is equal to X).

But I only need them to display on a particular single page from this custom post type, not on all of them.

Read More

How would I do that?

Related posts

Leave a Reply

3 comments

  1. Couldn’t you do this through ACF settings page? You can select Post and set it equal to the title.

    Edit

    Updated image for clarification

    enter image description here

    Edit 2

    It turns out ACF does not query for custom type when display the title drop down. To include all post type, in /core/admin/meta_box_location.php, change

    <div rel="post">
        <?php 
    
        $choices = array();
        foreach(get_posts(array('numberposts'=>'-1')) as $v)
        {
            $choices[$v->ID] = $v->post_title;
        }
    
        $this->create_field(array(
            'type'  =>  'select',
            'name'  =>  'location[rules]['.$k.'][value]',
            'value' =>  $rule['value'],
            'choices' => $choices,
        ));
    
        ?>
    </div>
    

    To

    <div rel="post">
        <?php 
    
        $choices = array();
        foreach(get_posts(array('numberposts'=>'-1', 'post_type'=>'any')) as $v)
        {
            $choices[$v->ID] = $v->post_title;
        }
    
        $this->create_field(array(
            'type'  =>  'select',
            'name'  =>  'location[rules]['.$k.'][value]',
            'value' =>  $rule['value'],
            'choices' => $choices,
        ));
    
        ?>
    </div>
    
  2. If you are referring to removing certain fields that you have added via PHP on post.php or post-new.php, when the post type meets a certain condition, then you can use the acf_remove_local_field( $key ) function – see https://www.advancedcustomfields.com/resources/register-fields-via-php/

    I went with something along these lines:

    <?php
    // Add Local Field Groups and Local Fields
    add_action('init', array($this, 'function_to_add_fields_to_all_post_types'), 999);
    
    // Notice how the priority is higher on this set of add_action functions so it runs after the initial setup of the fields
    
    // Remove Fields From Edit Post Screen
    if ( $pagenow == 'post.php' && get_post_type($_GET['post']) != 'cpt' ) {
        add_action('init', array($this, 'remove_fields_from_cpt'), 9999);
    }
    
    // Remove Fields From New Post Screen
    if ( $pagenow == 'post-new.php' ) {
        if(!isset($_GET['post_type']) || $_GET['post_type'] != 'cpt'){
            add_action('init', array($this, 'remove_fields_from_cpt'), 9999);
        }
    }
    
    function function_to_add_fields_to_all_post_types(){
        // Add Local Fields using acf_add_local_field_group() or acf_add_local_field()
    }
    
    function remove_fields_from_cpt(){
        // Note: The 'key' for your field is not the same as it's 'name'
        acf_remove_local_field( 'key');
    }
    

    I found that only adding the specific fields on specific admin screens broke some of the Ajax lookup functions, hence adding to all and then removing from specific admin screens.

    There is probably a much more efficient way to do this, but this is working for me.

  3. The following is a more efficient method:

    This checks for both EDIT and ADD screen and uses the “acf_remove_local_field($key)” function to remove the selected field by the key.

    add_action('init', 'remove_fields_from_cpt', 9999);
    function remove_fields_from_cpt(){
        global $pagenow;
        // Remove ACF fields from add/edit post
        if ( in_array( $pagenow, array( 'post.php', 'post-new.php' ), true )  
        && isset($_GET['post']) || isset($_GET['post_type']) 
        && in_array('YOUR_POST_TYPE', array(get_post_type( $_GET['post']), 
        get_post_type( $_GET['post_type']) )) ) {
            $key = 'FIELD_KEY';
            acf_remove_local_field($key);
        }   
    }