Hello WordPress Answers!

I'm having trouble with the widget update function saving values correctly, but first let me explain the situation.

I'm writing a simple news ticker widget plugin, which filters the posts displayed by post type with check boxes in the widget settings form. To generate the check boxes I'm using a foreach loop over the available post types.

However, the widget update function isn't saving the post type values. I confirmed this by doing a print_r in the form function (values exist) and again in the widget function (values do not exist).

Here is my code:

class ami_newsticker_widget extends WP_Widget {

// process the widget
function ami_newsticker_widget () {

    $widget_ops = array(
        'classname' => 'ticketcontainer',
        'description' => 'Display a scrolling newsticker'
    $this->WP_Widget( 'ami_newsticker_widget', 'AMI News Ticker Widget', $widget_ops );

// build the widget settings form
function form( $instance ) {
    $defaults   = array( 'num_posts' => 5 );
    $instance   = wp_parse_args( (array) $instance, $defaults );
    $num_posts  = $instance['num_posts'];

foreach ( get_post_types() as $post_type ) {
  $instance['post_types'] .= $post_type . ',';
$post_types = $instance['post_types'];
    //echo '<pre>';
    //echo '</pre>';


        <p>Number of posts to show: <input class="widefat" name="<?php echo $this->get_field_name( 'num_posts' ); ?>" type="number" value="<?php echo esc_attr( $num_posts ); ?>" /></p>
        <p>Filter by Post Type: <ul>
        <?php foreach ( get_post_types() as $post_type ) { ?>
            <li><input name="<?php echo $this->get_field_name( $post_type ); ?>" type="checkbox" <?php checked( $this->get_field_name( $post_type ) ); ?> /><label for="<?php echo $this->get_field_name( $post_type ); ?>" /><?php echo $post_type; ?></label></li>
       } ?>

echo '<pre>';
echo '</pre>';

// save the widget settings
function update( $new_instance, $old_instance ) {
    $instance = $old_instance;
    $instance['num_posts'] = strip_tags( $new_instance['num_posts'] );
$instance['post_types'] = strip_tags( $new_instance['post_types'] );

    return $instance;

// display the widget
function widget( $args, $instance ) {
        global $wpdb;
        extract( $args );

  echo '<pre>';
  echo '</pre>';

        // load the widget settings
  //foreach ( $instance['post_types'] as $post_type ) {
    //if ( $post_type == 'on' ) {
      //$checked .= $instance['post_types'][$post_type] . ' ,';
  //echo $checked;

        // get and clean the db data
        $num_posts = intval( absint( $instance['num_posts'] ) );
        $sql = "SELECT post_title, guid
                        FROM {$wpdb->posts}
                        WHERE post_status = 'publish'
                        ORDER BY post_date DESC
                        LIMIT {$num_posts}";

        $results = $wpdb->get_results( $sql );

        // print the widget
        echo $before_widget;
        echo '<ul id="webticker">';

        foreach ($results as $result) {
            echo '<li><a href="' . $result->guid . '">' . $result->post_title . '</a></li>';

        echo '</ul>';
        echo $after_widget;


It seems like there is something obvious that I'm missing, but I've been banging my head against a wall on this!

Any help would be greatly appreciated. Thanks in advance!

  • 2
    I assume this is a class that extends WP_Widget? What is the generated output of the form? What does the HTML look like?
    – s_ha_dum
    Nov 29, 2012 at 15:52
  • Yes, sorry should have mentioned that. Nov 29, 2012 at 16:13
  • bronze, much better is to edit the Question and include all the relevant code. Oh, yes, welcome to WPSE!
    – brasofilo
    Nov 29, 2012 at 17:35
  • brasofilo, Got it. Updated my code to include the entire widget class. Nov 29, 2012 at 22:30

1 Answer 1


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.

  • That worked! Thank you so so much! It all makes sense now... :) Nov 30, 2012 at 16:12
  • Brilliant answer!
    – jdm2112
    Sep 6, 2018 at 4:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.