Support

Account

Home Forums Backend Issues (wp-admin) Alter field group settings per content type

Solved

Alter field group settings per content type

  • We have a field group that we wish to appear above the content when editing most post types, but need that same group to appear below the content when editing another post type. I’ve tried altering the group settings using the load_field_group and get_field_group filters, but have been unsuccessful so far. I believe the problem is that we are also using the ACF Local JSON feature and the load_json is firing after the load_field_group and get_field_group filters.

    Is there another hook that I can use to alter settings after load_json or some other workaround to make it possible to have different settings per content type for a field group?

  • The filters only fire after the field group is loaded. The problem could be that the field groups are loaded before what you are using to determine how to change the group. What code are you using here?

  • Hi John. Thanks for jumping in. We’re using a custom plugin to include the json save and load.

    function ts_acf_json_load( $paths ) {
    	$paths[] = trailingslashit( WP_CONTENT_DIR ) . 'acf-json';
    	return $paths;
    }
    add_filter( 'acf/settings/load_json', 'ts_acf_json_load' );

    Then, in the functions.php within the theme, we have this code to alter it for a specific post type.

    function toind_get_flexible_content( $field_group ) {
    	if ( 'group_5c76d2e8213cf' === $field_group['key'] && 'event' == $GLOBALS['post_type'] ) {
    		$field_group['menu_order'] = 7;
    		$field_group['position']   = 'normal';
    	}
    	return $field_group;
    }
    add_filter( 'acf/get_field_group', 'toind_get_flexible_content' );
  • How you are loading the json does not matter. acf/load_field_group is called after every field group is loaded.

    I don’t know anything about $GLOBALS['post_type'] Is this set at the point that you are checking it? I don’t know, but I am going to assume that it isn’t and you’re probably going to need to find another way to determine the post type.

    
    function toind_get_flexible_content( $field_group ) {
        var_dump($GLOBALS['post_type']);
        .................................
    
  • I added the var_dump and verified that it is set. It output /Users/nrackleff/Sites/toind/web/wp-content/themes/ts_toind/functions.php:356:string 'event' (length=5)

    I also added a breakpoint inside the if statement and the code is getting executed. The breakpoint does get hit when I run the code, so that doesn’t seem to be the problem.

    What is the difference between get_field_group and load_field_group? Do they both get called after the json has loaded? Just want to make sure I’m using the correct hook.

  • The only difference in the hooks is that one is an older hook and one is a newer hook. I don’t know which is which, neither is documented on this site, so it’s hard to say. They are called one right after the other, so it shouldn’t matter which one you use.

    I did some testing and I think that you are running afoul of WP’s meta box order setting. When someone edits a post the order the meta boxes are in are saved so that the next time that user edits another post of the same post type the boxes are in the same place. In my test I could not effect the position of existing groups in any way, but I could change the position of a new group that had never been used before.

    Go into the db, in the usermeta table and find the meta key “meta-box-order_event” for your user ID and delete it. Then load an event page and see what happens.

  • Continued testing has also revealed that you are correct about field groups loaded from JSON and the acf/load_field_group hook is not used.

    Use this hook acf/validate_field_group

    $field_group = apply_filters( 'acf/validate_field_group', $field_group );

    You’ll need to test again if the global variable is set when this hook is called for groups loaded from json files.

  • Thank you again John. I’m not quite sure how/where to use the code you mentioned above. I tried replacing the other hook with this one:

    function toind_alter_flexible_content( $field_group ) {
    	//var_dump( $GLOBALS['post_type'] );
    	if ( 'group_5c76d2e8213cf' === $field_group['key'] && 'event' == $GLOBALS['post_type'] ) {
    		$field_group['menu_order'] = 7;
    		$field_group['position']   = 'normal';
    	}
    	return $field_group;
    }
    add_filter( 'acf/validate_field_group', 'toind_alter_flexible_content' );

    Which is not what you showed above, but I don’t understand where I would put that code that you showed and how I would work my alteration into the process.
    The code above did get hit, but once again, no change in the position of the field group on the edit screen.

  • Try

    
    add_filter( 'acf/validate_field_group', 'toind_alter_flexible_content', 20 );
    

    I’m not sure this will work at all. After digging through the code of ACF I do know that neither acf/load_field_group or acf/get_field_group are used when loading a field group from a .json file. The above hook was the only place that a change might be possible.

    I don’t know what other issues there might be. For example json files may be loaded before $GLOBALS[‘post_type’] is set, or you could still be seeing interference from the WP user metabox order, or for that matter, the filter hook will not work at all. I tested and it did work for me.

  • Sorry to say still no luck. My function gets executed and returns the altered field_group, but no change to the order on the editing screen. It still appears that acf/settings/load_json hook is getting fired again afterward as the breakpoint I put in that hook gets hit after my function to alter the group.

    I tried testing it with the post type check removed and it worked, so I think you are right about finding a different way to check the post type. I’ll look into that and let you know what I find out. The strange thing is that the breakpoint inside the if statement gets hit, so I assumed the post_type check was working.

    Thanks again for all your help.

  • The WordPress global $post is not set yet either…but…the ACF at some point knows the post type because it needs to know the post type in order to know whether or not to show the field group based on the location settings. Wondering what info I do have access to from my function?

  • Yes, all of my testing was without any checking and basically altering every field group setting just to make sure it could be done. So it is possible to alter them, you just need to find the way to only do it for a specific post type. You might want to grab the post ID from $_GET and use that to get the post type.

  • As far as “…ACF at some point knows…”, not really. ACF doesn’t need to know that until the field groups are shown and in some cases ACF only determines what field groups to make visible while there may be other field groups included in the code are not visible because they do not match the location rules.

    When not using JSON, ACF does not load the field groups until they are needed. On the other hand, it loads all field groups from JSON early so that it does not load a field group from the DB if it is already added via JSON. When ACF is loading the JSON it doesn’t care if it belongs on a specific page, it’s just calling acf_add_local_field_group() to add the ones loaded from JSON.

  • Using $_GET to grab the post id worked great. Thanks so much.

    Here’s the final function:

    function toind_alter_flexible_content( $field_group ) {
    	if ( isset( $_GET['post'] ) ) {
    		$post_id   = intval( $_GET['post'] );
    		$post_type = get_post_type( $post_id );
    		if ( 'group_5c76d2e8213cf' === $field_group['key'] && 'event' === $post_type ) {
    			$field_group['menu_order'] = 7;
    			$field_group['position']   = 'normal';
    		}
    	}
    	return $field_group;
    }
    add_filter( 'acf/validate_field_group', 'toind_alter_flexible_content', 20 );
    

    Thank you again so much for all of your help.

Viewing 14 posts - 1 through 14 (of 14 total)

You must be logged in to reply to this topic.