This took a bit to sort out. 🙂
You are trying to use $instance['post_types']
in your update()
function but are not setting that value at all in the form. I altered a couple of things so that the two match up.
Leaving your form (mostly) as it is, your update()
needs to be…
// save the widget settings
function update( $new_instance, $old_instance ) {
$instance = $old_instance;
$instance['num_posts'] = strip_tags( $new_instance['num_posts'] );
// start of the change
foreach (get_post_types() as $post_type) {
$instance[$post_type] = $new_instance[$post_type];
}
// end of the change
return $instance;
}
Now, that will get things to save but it won’t look like it because your checked()
is a little off, so your form()
needs to be altered just a little bit. Change the code for the list items to…
<input name="<?php echo $this->get_field_name( $post_type ); ?>" type="checkbox" <?php echo checked( $instance[$post_type] ,'on' ); ?> />
<label for="<?php echo $this->get_field_name( $post_type ); ?>" /><?php echo $post_type; ?></label>
Notice that the checked()
function went from checked( $this->get_field_name( $post_type ) );
to checked( $instance[$post_type] ,'on' );
‘on’ is the ‘true’ value.
You were trying to use a ‘post_types’ array but that didn’t match what was in the form, so I altered the update function to match the form. You could do it the other way around and alter the form to create an array. I think my way is easier though.
Some bits of the code you really don’t need, like…
foreach ( get_post_types() as $post_type ) {
$instance['post_types'][$post_type] = '';
}
And that will cause trouble if you try to use the ‘post_types’ array. It will overwrite that variable every time.