April 27, 2016

How to add custom meta boxes to specific page templates.

Let’s say you have a theme with custom page templates, all of which support custom content like specific gallery styles, multi-image head sliders and hours of operation. How do you do it? Here’s how!

Throw this into your ‘functions.php’ file.

// Add New Custom Fields to page Templates
define('MY_WORDPRESS_FOLDER',$_SERVER['DOCUMENT_ROOT']);
define('MY_THEME_FOLDER',str_replace("\\",'/',dirname(__FILE__)));
define('MY_THEME_PATH','/' . substr(MY_THEME_FOLDER,stripos(MY_THEME_FOLDER,'wp-content')));

add_action('admin_init','my_meta_init');

function my_meta_init(){

// YOU CAN SPECIFY CUSTOM CSS FILE TO STYLE YOUR CUSTOM META BOXES. 
	wp_enqueue_style('my_meta_css', MY_THEME_PATH . '/includes/meta.css');
	$post_id = $_GET['post'] ? $_GET['post'] : $_POST['post_ID'] ;
	$template_file = get_post_meta($post_id,'_wp_page_template',TRUE);

// I'VE USED VARIABLES TO STORE ALL THE INCLUDE FILES FOR THE META-BOX HTML.
		$var1 = 'homepage_slider_meta.php';
		$var2 = 'homepage_headline_meta.php';
		$var3 = 'homepage_video_meta.php';
		$var4 = 'training_section1_meta.php';
		$var5 = 'training_inperson_meta.php';
		$var6 = 'training_online_meta.php';
		$var7 = 'coaching_section1_meta.php';
		$var8 = 'coaching_phases_meta.php';
		$var9 = 'about_jane_meta.php';
		$var10 = 'contact_info_meta.php';

	// THE IF STATEMENT CHECKS FOR THE PAGE TEMPLATE FILENAME BEING USED
	if ($template_file == 'homepage.php'){
		add_meta_box('home_meta_slider', 'Header Slide Content', 'meta_setup', 'page', 'advanced', 'high',array('include'=>$var1));
		add_meta_box('home_meta_headline', 'Section 1 Headline', 'meta_setup', 'page', 'advanced', 'high',array('include'=>$var2));
		add_meta_box('home_meta_video', 'Video Section', 'meta_setup', 'page', 'normal', 'high',array('include'=>$var3));
	}
	if ($template_file == 'professional_training.php'){
		add_meta_box('training_meta_section', 'Section 1 Content', 'meta_setup', 'page', 'advanced', 'high',array('include'=>$var4));
		add_meta_box('training_meta_inperson', 'In-Person Training', 'meta_setup', 'page', 'advanced', 'high',array('include'=>$var5));
		add_meta_box('training_meta_online', 'Online Training', 'meta_setup', 'page', 'advanced', 'high',array('include'=>$var6));
	}
	if ($template_file == 'online_coaching.php'){
		add_meta_box('coaching_section1', 'Section 1', 'meta_setup', 'page', 'advanced', 'high',array('include'=>$var7));
		add_meta_box('coaching_phases', 'Phases', 'meta_setup', 'page', 'advanced', 'high',array('include'=>$var8));
	}
	if ($template_file == 'about_us.php'){
		add_meta_box('about_jane', 'About Jane', 'meta_setup', 'page', 'advanced', 'high',array('include'=>$var9));
	}
	if ($template_file == 'contact.php'){
		add_meta_box('contact_info', 'Contact Info.', 'meta_setup', 'page', 'advanced', 'high',array('include'=>$var10));

	}
	add_action('save_post','my_meta_save');
}

// THIS IS A REUSABLE FUNCTION THAT SETS UP THE CUSTOM FIELDS ON 
// A PAGE TEMPLATE. THE ONLY THING YOU'RE PASSING INTO IT IS '$thing'. '$post' IS A GIVEN.

function meta_setup($post, $thing){
	global $post;
	$meta = get_post_meta($post->ID,'_custom_meta',TRUE);
	include(MY_THEME_FOLDER . '/includes/'.$thing['args']['include']);
	echo '<input type="hidden" name="home_meta_noncename" value="' . wp_create_nonce(__FILE__) . '" />';
}

// SAVING ALL META-BOX DATA TO A SINGLE ARRAY OBJECT IN THE DATABASE 
// THIS REDUCES DB CALLS AND CLEANS UP YOUR SAVE CODE IMMENSELY  

function my_meta_save($post_id){
	if (!wp_verify_nonce($_POST['home_meta_noncename'],__FILE__)) return $post_id;
	if ($_POST['post_type'] == 'page'){
		if (!current_user_can('edit_page', $post_id)) return $post_id;
	}else{
		if (!current_user_can('edit_post', $post_id)) return $post_id;
	}
	$current_data = get_post_meta($post_id, '_custom_meta', TRUE);  
	$new_data = $_POST['_custom_meta'];
	my_meta_clean($new_data);
	if ($current_data){
		if (is_null($new_data)) delete_post_meta($post_id,'_custom_meta');
		else update_post_meta($post_id,'_custom_meta',$new_data);
	}elseif (!is_null($new_data)){
		add_post_meta($post_id,'_custom_meta',$new_data,TRUE);
	}
	return $post_id;
}

function my_meta_clean(&$arr){
	if (is_array($arr)){
		foreach ($arr as $i => $v){
			if (is_array($arr[$i])){
				my_meta_clean($arr[$i]);
				if (!count($arr[$i])){
					unset($arr[$i]);
				}
			}else{
				if (trim($arr[$i]) == ''){
					unset($arr[$i]);
				}
			}
		}
		if (!count($arr)){
			$arr = NULL;
		}
	}
}

// MOVE ALL META BOXES MARKED AS 'ADVANCED' ABOVE THE CONTENT, JUST BELOW THE TITLE
add_action('edit_form_after_title', function() {
    global $post, $wp_meta_boxes;
    do_meta_boxes(get_current_screen(), 'advanced', $post);
    unset($wp_meta_boxes[get_post_type($post)]['advanced']);
});
 ?>
Add Custom Meta-Boxes to Page Templates

Here is an example of how to set up your meta-box HTML. Note: this approach automatically pushes the new fields into the ‘_custom_meta’ array.

<div class="my_meta_control">
<label>About Us Accordion:</label>


<textarea name="_custom_meta[about_us_meta]">

<!-- HERE YOU'RE CHECKING IF THE FIELD EXISTS. THEN YOU'RE GRABBING AND POPULATING IT'S DATA IF IT EXISTS, OR CREATING THE ENTRY IF IT DOESN'T EXIST -->

<?php if(!empty($meta['about_us_meta'])) echo $meta['about_us_meta']; ?>

</textarea>


<span class="small">Put your About Us text here.</span>

<label>Our Story Accordion:</label>

<textarea name="_custom_meta[about_story_meta]"><?php if(!empty($meta['about_story_meta'])) echo $meta['about_story_meta']; ?></textarea>

<span class="small">Put your About Story text here.</span>

</div>
Internal Meta-Box HTML EXAMPLE