Support

Account

Home Forums ACF PRO Created Fields Programmatically

Solved

Created Fields Programmatically

  • Hi All,

    I’m attempting to create some custom fields programmatically and feel I’ve gotten really close, but I just can’t get over the line.

    For Custom Post Types I like to use a Page for controlling the content that is shown on the archive page, as I feel this makes the most sense to a client when they use the admin. I usually set this all up via ACF using an Options page and a post object selection, then I query this on the archive page to get the relevant content for the template.

    Today I’ve been attempting to build this programmatically, but have hit many walls throughout, and with each mini success another stumble follows; but I think I’m close.

    Below is the code that creates the custom fields, and this is all working correctly; but I’ve had to use ‘init’ instead of ‘acf/init’ within the add_action as ‘acf/init’ wasn’t allowing me to use get_post_types. I think this is due to the order that everything is run.

    
    /***
     *
     * Creates ACF Fields for CPT Archive Pages
     *
     ***/
    
    function add_archive_option_fields() {
    	$post_types = get_post_types( array ( '_builtin' => FALSE ), 'objects' );
    	
    	if ( $post_types ) {
    		if( function_exists('acf_add_local_field_group') ) {
    			acf_add_local_field_group( array(
    				'key' 		=> 'group_archive_pages',
    				'title' 	=> 'Archive Pages',
    				'fields' 	=> array (),
    				'location' 	=> array (
    					array (
    						array(
    							'param' 	=> 'options_page',
    							'operator' 	=> '==',
    							'value' 	=> 'archive-pages',
    						),
    					),
    				),
    			));
    			
    			foreach ( $post_types as $post_type => $properties ) {
    				$post_type_object = get_post_type_object( $post_type );
    				$post_type_label = $post_type_object->labels->singular_name;
    				
    				if ( $properties->has_archive ) {
    					acf_add_local_field(
    						array(
    							'key' 			=> ''.$post_type.'_archive_page',
    							'label' 			=> ''.$post_type_label.' Archive Page',
    							'name' 			=> ''.$post_type.'_archive_page',
    							'type' 			=> 'post_object',
    							'instructions' 	=> 'Select your archive page for the '.$post_type_label.' post type',
    							'required' 		=> 0,
    							'post_type' 	=> array( 0 => 'page' ),
    							'allow_null' 	=> 1,
    							'multiple' 		=> 0,
    							'return_format' => 'object',
    							'parent' 		=> 'group_archive_pages'
    						)
    					);
    					
    					acf_add_local_field(
    						array(
    							'key' 			=> ''.$post_type.'_per_page',
    							'label' 			=> ''.$post_type_label.' Per Page',
    							'name' 			=> ''.$post_type.'_per_page',
    							'type' 			=> 'range',
    							'instructions' 	=> 'Select the amount of posts that are shown before pagination for the '.$post_type_label.' post type',
    							'required' 		=> 0,					
    							'default_value' => '',
    							'min' 			=> 1,
    							'max' 			=> 99,
    							'step' 			=> 1,
    							'append' 		=> 'posts per page',
    							'parent' 		=> 'group_archive_pages'
    						)
    					);
    				}
    			}
    		}
    	}
    }
    add_action( 'init', 'add_archive_option_fields' );
    

    After the above code I run the two following pieces of code. If I create the above custom fields manually the below code all works fine, but using the above code rewrite rules don’t work. Once again I think this is due to the order of everything running?!

    
    /***
     *
     * Rewrite post type slug via ACF Options page
     *
     ***/
    
    function change_post_types_slug( $args, $post_type ) {
    	$site_url = get_site_url();
    	$full_site_url = $site_url . '/';
    	
    	if ( $post_type === $post_type ) {
    		$post_type_archive_page = get_field( ''.$post_type.'_archive_page', 'option' );
    		$post_type_archive_page_id = $post_type_archive_page->ID;
    		
    		if ( $post_type_archive_page_id ) {
    			$post_type_archive_page_link = get_the_permalink( $post_type_archive_page_id );
    			$post_type_archive_page_url = str_replace( $full_site_url, '', $post_type_archive_page_link);
    			$post_type_archive_page_url = rtrim( $post_type_archive_page_url,'/' );
    			
    			$args['rewrite']['slug'] = $post_type_archive_page_url;
    		}
    	}
    
    	return $args;
    }
    add_filter( 'register_post_type_args', 'change_post_types_slug', 10, 2 );
     
     
    /***
     *
     * Posts Per Page via ACF Options page
     *
     ***/
    
    function my_post_queries( $query ) {
    	if ( !is_admin() && $query->is_main_query() ){
    		$post_types = get_post_types();
    		
    		foreach ( $post_types as $post_type ) {
    			if ( is_post_type_archive( $post_type )){
    				$post_type_per_page = get_field( ''.$post_type.'_per_page', 'option' );
    				$query->set( 'posts_per_page', $post_type_per_page );
    			}
    		}
    	}
    }
    add_action( 'pre_get_posts', 'my_post_queries' );
    

    Is there anyway I can fire off the above code so that it would all work in the correct order?

    I’ve read up on the add_action side of things and I have attempted lots of different ways, but either the Custom Fields don’t get created due to not being able to loop through the Custom Post Types which are used to create the required fields; or everything seems to be getting created too late for the actual Post Object selection to have any affect on the rewrite rules I’m trying to use.

    The Pagination rules do all work though. So I assume this happens later.

    Many thanks for any help 🙂

    Archive Options Page

  • Hi All,

    The forum wasn’t displaying my post for a while and this pushed me to keep trying, and I managed to sort the issue. It was actually just a simple ->ID on constructing the rewrites that was missing, and then I added a higher priority on the init, and all seems to be working nicely.

    The code is below. If anyone can see any issues or ways I could make the code more efficient please let me know.

    
    /***
     *
     * Creates Option Page and ACF Fields for CPT Archive Pages
     *
     ***/
    
    function add_archive_option_fields() {
    	$post_types = get_post_types( array ( 'public'   => true, '_builtin' => FALSE ), 'objects' );
    	
    	if ( $post_types ) {
    		
    		// Creates Archive Pages Option Page
    		if ( function_exists( 'acf_add_options_page' ) ) {
    		    acf_add_options_page( array (
    		        'page_title' 	=> 'Archive Pages',
    		        'menu_title' 	=> 'Archive Pages',
    		        'menu_slug' 	=> 'archive-pages',
    		        'icon_url' 		=> 'dashicons-admin-page',
    		        'position' 		=> 20
    		    ));
    		}
    		
    		// Adds main Archive Page Custom Fields for all CPTs that are set as has_archive => true
    		if( function_exists('acf_add_local_field_group') ) {
    			acf_add_local_field_group( array (
    				'key' 		=> 'group_archive_pages',
    				'title' 	=> 'Archive Pages',
    				'fields' 	=> array (),
    				'location' 	=> array (
    					array (
    						array(
    							'param' 		=> 'options_page',
    							'operator' 	=> '==',
    							'value' 		=> 'archive-pages',
    						),
    					),
    				),
    			));
    			
    			foreach ( $post_types as $post_type => $properties ) {
    				$post_type_object = get_post_type_object( $post_type );
    				$post_type_label = $post_type_object->labels->name;
    				$post_type_singular_label = $post_type_object->labels->singular_name;
    				
    				if ( $properties->has_archive ) {
    					acf_add_local_field(
    						array(
    							'key' 			=> ''.$post_type.'_archive_page',
    							'label' 			=> ''.$post_type_singular_label.' Archive Page',
    							'name' 			=> ''.$post_type.'_archive_page',
    							'type' 			=> 'post_object',
    							'instructions' 	=> 'Select your archive page for the '.$post_type_label.'',
    							'required' 		=> 0,
    							'post_type' 	=> array( 0 => 'page' ),
    							'allow_null' 	=> 1,
    							'multiple' 		=> 0,
    							'return_format' => 'object',
    							'parent' 		=> 'group_archive_pages'
    						)
    					);
    					
    					acf_add_local_field(
    						array(
    							'key' 			=> ''.$post_type.'_per_page',
    							'label' 			=> ''.$post_type_singular_label.' Per Page',
    							'name' 			=> ''.$post_type.'_per_page',
    							'type' 			=> 'range',
    							'instructions' 	=> 'Select the amount of posts that are shown before pagination for the '.$post_type_label.'',
    							'required' 		=> 0,					
    							'default_value' => '',
    							'min' 			=> 1,
    							'max' 			=> 99,
    							'step' 			=> 1,
    							'append' 		=> 'posts per page',
    							'parent' 		=> 'group_archive_pages'
    						)
    					);
    				}
    			}
    		}
    	}
    }
    add_action( 'init', 'add_archive_option_fields', 99 );
    
    /***
     *
     * Rewrite post type slug via ACF Options page
     *
     ***/
    
    function change_post_types_slug( $args, $post_type ) {
    	$site_url = get_site_url();
    	$full_site_url = $site_url . '/';
    	
    	if ( $post_type === $post_type ) {
    		// Checks to see if CPT has_archive
    		$post_type_object = get_post_type_object( $post_type ); 
    		$has_archive = $post_type_object->has_archive;
    		
    		if ( $has_archive ) {
    			$post_type_archive_page = get_field( ''.$post_type.'_archive_page', 'option' );
    			
    			if ( $post_type_archive_page ) {
    				$post_type_archive_page_link = get_the_permalink( $post_type_archive_page );
    				$post_type_archive_page_url = str_replace( $full_site_url, '', $post_type_archive_page_link);
    				$post_type_archive_page_url = rtrim( $post_type_archive_page_url,'/' );
    				
    				$args['rewrite']['slug'] = $post_type_archive_page_url;
    			}
    		}
    	}
    
    	return $args;
    }
    add_filter( 'register_post_type_args', 'change_post_types_slug', 10, 2 );
    
    /***
     *
     * Posts Per Page via ACF Options page
     *
     ***/
    
    function my_post_queries( $query ) {
    	if ( !is_admin() && $query->is_main_query() ){
    		$post_types = get_post_types( array ( 'public'   => true, '_builtin' => FALSE ) );
    		
    		foreach ( $post_types as $post_type ) {
    			if ( is_post_type_archive( $post_type )){
    				$post_type_per_page = get_field( ''.$post_type.'_per_page', 'option' );
    				$query->set( 'posts_per_page', $post_type_per_page );
    			}
    		}
    	}
    }
    add_action( 'pre_get_posts', 'my_post_queries' );
    
Viewing 2 posts - 1 through 2 (of 2 total)

The topic ‘Created Fields Programmatically’ is closed to new replies.