That $query->have_posts()
modifies the global $post
variable which is also used on the admin side, and on the front-end/public side of the site, you would simply call wp_reset_postdata()
to restore the global $post
back to the post before you call the $query->have_posts()
.
But on the admin side, you need to manually restore the variable like so, after your loop ends:
function module_group_callback( $post ) {
...
while ( $query->have_posts() ) : $query->the_post();
...
endwhile;
// Restore the global $post back to the one passed to your metabox callback.
$GLOBALS['post'] = $post;
}
But if you call global $post
in your code, then yes, you can use the backup method:
function module_group_callback( $post ) {
global $post; // this is required
$_post = $post; // backup the current $post variable in the global scope
...
while ( $query->have_posts() ) : $query->the_post();
...
endwhile;
$post = $_post; // restore
}
Alternatively, you could just omit the $query->have_posts()
and loop manually through $query->posts
:
function module_group_callback( $post ) {
...
// Don't use $post with the 'as'. Instead, use $p, $post2 or another name.
foreach ( $query->posts as $p ) {
echo '<option value="' . $p->ID . '">' . esc_attr( get_the_title( $p ) ) . '</option>';
}
}
Either way, if your code modifies the global $post
, then make sure to restore it later.
And btw, you would want to use esc_html()
there, because esc_attr()
is for escaping attribute values, e.g. <input value="<?php echo esc_attr( 'some <b>HTML</b>' ); ?>">
. 🙂