Meta Box on Custom Post Type not saving
-
16-10-2019 - |
Question
I have a custom post type which is working fine, however the meta box does isn't saving.
Long & short, i'm stumped!
add_action('init', 'portfolio');
function portfolio() {
$args = array(
'label' => __('Portfolio'),
'singular_label' => __('Portfolio'),
'public' => true,
'show_ui' => true,
'menu_position' => 5,
'capability_type' => 'page',
'hierarchical' => false,
'rewrite' => true,
'show_in_nav_menus' => true,
'supports' => array('title', 'editor', 'thumbnail', 'excerpt'),
'has_archive' => true
);
register_taxonomy( 'type', 'portfolio',
array(
'hierarchical' => false,
'label' => __('Project Type'),
'query_var' => 'type',
'rewrite' => array('slug' => 'portfolio/type' )
)
);
register_post_type( 'portfolio' , $args );
}
add_action("admin_init", "admin_init");
add_action('save_post', 'save_meta_data');
function admin_init(){
add_meta_box("portfolio_text", "Main Text", "portfolio_options", "portfolio", "normal", "high");
}
/* Meta Values for Shorts */
function portfolio_options() {
global $post;
$custom = get_post_custom($post->ID);
$short_embed = $custom["portfolio_text"][0]; ?>
<textarea name="portfolio_text" cols="40" rows="1" style="width:98%; height:100px"/><?php echo get_option('portfolio_text'); ?></textarea>
<?php }
/* Save Changes */
function save_meta_data($ID = false, $post = false) {
if($post->post_type != 'portfolio')
return;
update_post_meta($ID, 'portfolio_text', $_POST['portfolio_text']);
}
Your help is appreciated!
Cheers, George
Solution
Hi @George Wiscombe:
So close, yet so far! (I know the pain, I'm there often. :) You almost had it but are using the wrong hook to do the post meta update. Use the 'wp_insert_post_data'
hook instead of the 'save_post'
hook:
<?php
if (!class_exists('YourSite_Portfolio')) {
class YourSite_Portfolio {
static function on_load() {
add_action('init',array(__CLASS__,'init'));
add_action("admin_init",array(__CLASS__,'admin_init'));
add_action('wp_insert_post_data',array(__CLASS__,'wp_insert_post_data'),10,2);
}
static function init() {
register_post_type( 'portfolio',array(
'label' => __('Portfolio'),
'singular_label' => __('Portfolio'),
'public' => true,
'show_ui' => true,
'menu_position' => 5,
'capability_type' => 'page',
'hierarchical' => false,
'rewrite' => true,
'show_in_nav_menus' => true,
'supports' => array('title', 'editor', 'thumbnail', 'excerpt'),
'has_archive' => true
));
register_taxonomy( 'type', 'portfolio', array(
'hierarchical' => false,
'label' => __('Project Type'),
'query_var' => 'type',
'rewrite' => array('slug' => 'portfolio/type' )
));
}
static function admin_init(){
add_meta_box('portfolio_text','Main Text',array(__CLASS__,'portfolio_options'),'portfolio','normal','high');
}
static function portfolio_options($post,$metabox) {
$portfolio_text = get_post_meta($post->ID,'portfolio_text',true);
$html =<<<HTML
<textarea name="portfolio_text" cols="40" rows="1" style="width:98%; height:100px"/>{$portfolio_text}</textarea>
HTML;
echo $html;
}
static function wp_insert_post_data($data,$postarr) {
if ($postarr['post_type'] == 'portfolio') {
update_post_meta($postarr['ID'], 'portfolio_text', $postarr['portfolio_text']);
}
return $data;
}
}
YourSite_Portfolio::on_load();
}
The 'wp_insert_post_data'
hook is where WordPress captures the values from the $_POST
array; by the time you reach 'save_post'
WordPress has reloaded the post and that's why 'portfolio_text'
empty when you are trying to save it.
OTHER TIPS
the problem is with your portfolio_options function in this line:
<textarea name="portfolio_text" cols="40" rows="1" style="width:98%; height:100px"/><?php echo get_option('portfolio_text');** ?></textarea>
its being saved and have been before but you are not calling it the right way, you are using get_option('portfolio_text') and that's not right because it not an option is a post metadata
so change get_option('portfolio_text') to get_post_meta($post->ID, 'portfolio_text', true);
so your function will look like this:
/* Meta Values for Shorts */
function portfolio_options() {
global $post;
$custom = get_post_custom($post->ID);
$short_embed = $custom["portfolio_text"][0]; ?>
<textarea name="portfolio_text" cols="40" rows="1" style="width:98%; height:100px"/><?php echo get_post_meta($post->ID, 'portfolio_text', true); ?></textarea>
<?php }
that should do it!