Question

I am trying to add a meta box to the "page" post type, in which I succeeded. In my meta box I would like to display a dropdown with titles from an other custom post type (named "Albums"). I also succeeded in that, but once I select a specific album in the dropdown and save the page, it changes the page permalink to the permalink of the chosen album.

<?php
add_action('add_meta_boxes', 'add_meta_box_album');
function add_meta_box_album() {
     add_meta_box('meta-box-album-id', 'Album', 'meta_box_album_callback', 'page', 'normal', 'high');
}

function meta_box_album_callback($post) {
     $values = get_post_custom($post->ID);
     $mytheme_custom_select = (isset($values['mytheme_custom_select'][0]) && '' !== $values['mytheme_custom_select'][0]) ? $values['mytheme_custom_select'][0] : '';
     wp_nonce_field('my_meta_box_nonce', 'meta_box_nonce');
?>
<p>
<label for="">Select album:</label><br>

<? $getAlbums = new WP_Query(array(
    'post_type' => 'albums',
));
?>
<select id="mytheme_custom_select" name="mytheme_custom_select">
    <option value="">Selecht an album...</option>
    <? while ($getAlbums->have_posts()):$getAlbums->the_post(); ?>
        <option
            value="<?php the_title($getAlbums->ID); ?>" <?php selected($mytheme_custom_select, the_title($getAlbums->ID), true); ?>><?php the_title($getAlbums->ID); ?></option>
    <? endwhile; ?>
    <? wp_reset_query(); ?>
</select>

<? }

add_action('save_post', 'cd_meta_box_save');
function cd_meta_box_save($post_id) {
     if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
     if (!isset($_POST['meta_box_nonce']) || !wp_verify_nonce($_POST['meta_box_nonce'], 'my_meta_box_nonce')) return;
     if (!current_user_can('edit_post', $post_id)) return;
     $allowed = array(
         'a' => array(
             'href' => array()
         )
     );
     if (isset($_POST['mytheme_custom_select'])) { // Input var okay.
         update_post_meta($post_id, 'mytheme_custom_select', sanitize_text_field(wp_unslash($_POST['mytheme_custom_select']))); // Input var okay.
     }
}
Was it helpful?

Solution

Here's the updated meta box callback function. I've used get_posts() instead of WP_Query as get_posts() is more performant as well as easy to use in this case. And removed get_post_custom() as it'll fetch all the custom metadata when you don't need them. So, I've replaced that with get_post_meta(). Hope your dropdown will work as expected now.

I'd suggest you save post id (album id) instead of the title.

function meta_box_album_callback( $post ) {
    wp_nonce_field( 'my_meta_box_nonce', 'meta_box_nonce' );

    $mytheme_custom_select = get_post_meta( $post->ID, 'mytheme_custom_select', true );
    $albums = get_posts( array(
        'post_type'      => 'albums',
        'post_status'    => 'publish',
        'posts_per_page' => -1
    ) );
    ?>

    <p>
        <label for="mytheme_custom_select">Select album:</label><br>
        <select id="mytheme_custom_select" name="mytheme_custom_select">
            <option value="">Selecht an album...</option>
            <?php foreach ( $albums as $album ) : ?>
                <option value="<?php echo esc_attr( $album->post_title ); ?>" <?php selected( $mytheme_custom_select, esc_attr( $album->post_title ) ); ?>><?php echo esc_html( $album->post_title ); ?></option>
            <?php endforeach; ?>
        </select>
    </p>

    <?php
}

OTHER TIPS

The above code is right but there is no save dropdown option. For save you can follow below code

function meta_box_album_callback( $post ) {
    wp_nonce_field( 'my_meta_box_nonce', 'meta_box_nonce' );

    $mytheme_custom_select = get_post_meta( $post->ID, 'mytheme_custom_select', true);
    $albums = get_posts( array(
        'post_type'      => 'albums',
        'post_status'    => 'publish',
        'posts_per_page' => -1
    ) );
    ?>

    <p>
        <label for="mytheme_custom_select">Select album:</label><br>
        <select id="mytheme_custom_select" name="mytheme_custom_select">
            <option value="">Selecht an album...</option>
            <?php foreach ( $albums as $album ) : ?>
                <option value="<?php echo esc_attr( $album->post_title ); ?>" <?php selected( $mytheme_custom_select, esc_attr( $album->post_title ) ); ?>><?php echo esc_html( $album->post_title ); ?></option>
            <?php endforeach; ?>
        </select>
    </p>

    <?php
}

// Here you can save choose value.

$mytheme_custom_select = $_POST['mytheme_custom_select'];
    update_post_meta( $post_id, 'mytheme_custom_select', $mytheme_custom_select );
Licensed under: CC-BY-SA with attribution
Not affiliated with wordpress.stackexchange
scroll top