skip to Main Content

I am trying to add a new select field to the page properties sidebar, but I am having trouble getting it to save the value.

This is what I have at the moment:

<?php

function addMyMeta() {
    add_meta_box( 'my_custom_metabox', 'My Meta', 'setMyMeta', 'page', 'side', 'default' );
}
add_action( 'add_meta_boxes', 'addMyMeta' );

function setMyMeta() {
    global $page;
    $value = get_post_meta( $page->ID, 'my_custom_metabox', true );
    ?>
    <fieldset>
        <select name="my_custom_metabox" id="my_custom_metabox" autocomplete="off">
            <option value="">Default</option>
            <option value="my-value" <?php if($value == 'my-value') {echo ' selected ';}; ?>>My Value</option>
        </select>
    </fieldset>
    <?php
}

function saveMyMeta( $page_id, $page ) {
    if ( !isset( $_POST['my_custom_metabox'] ) ) {
        update_post_meta( $page->ID, 'my_custom_metabox', $_POST['my_custom_metabox'] );
    }
}
add_action( 'save_post', 'saveMyMeta', 1, 2 );

?>

2

Answers


  1. Change global $page; to global $post; and $value = get_post_meta( $post->ID, 'my_custom_metabox', true );

    function setMyMeta() {
        global $post;
       
       $value = get_post_meta( $post->ID, 'my_custom_metabox', true );
        ?>
        <fieldset>
            <select name="my_custom_metabox" id="my_custom_metabox" autocomplete="off">
                <option value="">Default</option>
                <option value="my-value" <?php if($value == 'my-value') {echo ' selected ';}; ?>>My Value</option>
            </select>
        </fieldset>
        <?php
    }
    
    Login or Signup to reply.
  2. You should use isset instead of !isset in saveMyMeta function. Why would you want to run the update_post_meta if the value is not even set?

    I prefer to add meta boxes using OOP because it’s easy and saves you from having to worry about naming collisions in the global namespace.

    Things to consider using while adding meta boxes:

    1. wp_nonce_field() to validate that the contents of the form came from the location on the current site and not somewhere else.
    2. selected() for select fields.
    3. array_key_exists() to check if the key exists.
    4. Sanitizing the values before saving or updating by using: sanitize_text_field(), sanitize_textarea_field(), intval(), floatval() etc.
    5. Adding post_type suffix to save_post action hook. in your case it will be save_post_page.

    Here is the full OOP code:

    abstract class My_Custom_MetaBox {
    
      /**
       * Set up and add the meta box.
       */
      public static function add() {
    
        add_meta_box(
          'my_custom_metabox', // Unique ID
          'My Meta', // Box title
          [ self::class, 'html' ], // Content callback, must be of type callable
          'page', // Post type
          'side', // The context within the screen where the box should display
          'default' // Priority
        );
    
      }
    
      /**
       * Display the meta box HTML to the user.
       */
      public static function html( $post ) {
    
        // Add an nonce field so we can check for it later.
        wp_nonce_field('my_custom_meta_box', 'my_custom_meta_box_nonce');
    
        $value = get_post_meta($post->ID, '_my_custom_metabox', true);
    
        ?>
          <fieldset>
            <select name="my_custom_metabox" id="my_custom_metabox" autocomplete="off">
              <option value="" <?php selected($value, ''); ?>>Default</option>
              <option value="my-value" <?php selected($value, 'my-value'); ?>>My Value</option>
            </select>
          </fieldset>
        <?php
    
      }
    
      /**
       * Save the meta box selections.
       */
      public static function save( int $post_id ) {
    
        // Check if our nonce is set.
        if ( !isset($_POST['my_custom_meta_box_nonce']) ) {
          return $post_id;
        }
    
        $nonce = $_POST['my_custom_meta_box_nonce'];
    
        // Verify that the nonce is valid.
        if ( !wp_verify_nonce($nonce, 'my_custom_meta_box') ) {
          return $post_id;
        }
    
        // If this is an autosave, our form has not been submitted,
        // so we don't want to do anything.
        if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) {
          return $post_id;
        }
    
        // Check the user's permissions.
        if ( 'page' == $_POST['post_type'] ) {
          if ( !current_user_can('edit_page', $post_id) ) {
            return $post_id;
          }
        } else {
          if ( !current_user_can('edit_post', $post_id) ) {
            return $post_id;
          }
        }
    
        // Saving or Updating the data
        if ( array_key_exists('my_custom_metabox', $_POST) ) {
          $selected_value = sanitize_text_field($_POST['my_custom_metabox']);
          update_post_meta( $post_id, 'my_custom_metabox', $selected_value);
        }
    
      }
    
    }
    add_action( 'add_meta_boxes', ['My_Custom_MetaBox', 'add'] );
    add_action( 'save_post_page', ['My_Custom_MetaBox', 'save'] );
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search