Support

Account

Home Forums Backend Issues (wp-admin) Using acf_form in admin

Solving

Using acf_form in admin

  • So I’m adding a feature to my theme where in Appearance->Menu, a custom advanced menu property will appear in the menu structure item. (in addition to the default fields like Link Target, Title Attribute, CSS Classes etc.) I want this field to be an ACF Post Relationship field. This way the user can associate any random post with a menu item. The idea is that in my custom nav walker, I’ll be able to look up this association and get data from the post.

    So, I’ve hooked into the menu admin correctly and acf_form() inserts a form with my post relationship field, but it’s blank and doesn’t list any posts to choose from. I’m sure this is due to the acf-pro-input.min.js?ver=5.3.8.1:1 Uncaught ReferenceError: acf is not defined I’m getting so that’s my first question.

    Backing up a bit, I’ve simply added this to functions.php. This alone causes the above js error. Any ideas why? I’m using the latest ACF Pro and WP.

    
    function dcdc_on_admin_head (  ) {
        do_action('acf/input/admin_head');
        do_action('acf/input/admin_enqueue_scripts');
    }
    add_action( 'admin_head', 'dcdc_on_admin_head' );
    

    I’ve read other posts where @elliot suggests learning from core/input.php but I’m not getting it.

  • Still no luck, but I did notice that acf.php and acf-pro.php each use wp_register_script() with different dependency params where the latter has none. Why is that?

  • Hi @joelstransky

    Just throwing this out there.. why can’t you have the user set the relationship between the menu items post/page/category/whatever and any random posts? And then in your walker fetch those values from the object you added as a menu item.. The only limitation to this that I can see is if you have custom URL links in your wp nav menu.

  • Thanks for the suggestion @jonathan
    I actually got it working by manually enqueueing acf-input rather than go the do_action() route. Race conditions I guess.

    
    add_action('admin_enqueue_scripts', 'on_admin_enqueue_scripts' );
    function on_admin_enqueue_scripts() {
      // global
      global $pagenow;
      if ( 'nav-menus.php' != $pagenow ) {
        return;
      }
      wp_enqueue_script('acf-input');
    }
    
  • Ah okay cool! Glad you worked it out ๐Ÿ˜‰

    Best of luck with the project!

  • Hey @joelstransky, would you mind sharing the code you used to get an ACF field in the menu structure item? I’m trying to add a field in there myself and it would be hugely helpful if I could just use ACF to do it.

  • It actually required a bit of a hack. I can’t post the entire plugin but I can try to hit the highlights. These are just snippets from my larger code base so try and just grasp the concepts.

    First enqueue ACF

    
    add_action('admin_enqueue_scripts', array( $this, 'on_admin_enqueue_scripts' ) );
    	function on_admin_enqueue_scripts() {
    		// global
    		global $pagenow;
    		if ( 'nav-menus.php' != $pagenow ) {
    			return;
    		}
    
    	  	wp_enqueue_script('acf-input');
    	  	wp_enqueue_style('acf-mpa');
    	}
    

    Now you need to dequeue the native walker that normally renders the menu admin and replace it with one you copied and edited to include the acf field.

    
    include_once( 'edit_custom_walker.php' );
    add_filter( 'wp_edit_nav_menu_walker', array( $this, 'acf_menu_edit_walker'), 1, 2 );
    function acf_menu_edit_walker($walker, $menu_id) {
    		$options = get_option( 'dcdc_menu_partials' );
    		$keys = array_keys($options['menu_ids']);
    		if ( in_array($menu_id, $keys) ) {
    			remove_all_filters('wp_edit_nav_menu_walker' );
    	    	return 'Walker_Nav_Menu_Edit_Custom';
    		} 
    		return $walker;	    
    	}
    

    Part of your custom walker needs an acf_form()

    
    <!-- end normal -->
    				    <p>
    				        <?php 
    				        $GLOBALS['current_menu_item_id'] = $item_id;
    					    $acf_options = array(
    					    	'post_id' => $item_id,
    					    	'form' => false,
    					    	/* (array) An array of field group IDs/keys to override the fields displayed in this form */
    					    	'field_groups' => array('group_573e71ff44db1'),
    					    	'return' => '',
    					    );
    					    acf_form( $acf_options );
    				        ?>
    				    </p>
    				    <!-- end acf -->
    

    Then you have to catch the acf form value when the menu is being saved

    
    add_action( 'wp_update_nav_menu_item', array( $this, 'update_custom_nav_fields'), 10, 3 );
    function update_custom_nav_fields ($menu_id, $menu_item_db_id, $args) {
    		if ( isset( $_REQUEST['acf']['field_573e727f24ef4'] ) && is_array( $_REQUEST['acf']['field_573e727f24ef4'] ) ) {
    			$field_value = $_REQUEST['acf']['field_573e727f24ef4'][$menu_item_db_id];
    		    $field = get_field_object('field_573e727f24ef4', $menu_item_db_id, false, false);
    		    acf_update_value( $field_value, $menu_item_db_id, $field );
    		}
    	}
    

    This also a requires a custom nav walker for the front end in order to pick up on the field data. Hope that helps

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

You must be logged in to reply to this topic.