• mvanboordt

    (@mvanboordt)


    Hi all,

    I’m currently creating a widget for one of my clients.
    The idea of the widget is to show data from an post that is published somewhere else on the site.

    The widget has two dropdowns where the user can select from two different kinds of posts.

    I have the basics set up but I can’t figure out how to get the chosen dropdown item shown on the website.

    Please bare with me when you go through the code.

    <?php
    /**
     * Plugin Name: Select Post
     * Description: A Widget to select a post
     * Version: 0.1
     * Author: Michel van Boordt
     * Author URI: http://www.besidespurple.nl
     */
    
    add_action( 'widgets_init', 'sp' );
    
    function sp() {
    	register_widget( 'sp' );
    }
    
    class sp extends WP_Widget {
    
    	function sp() {
    		$widget_ops = array( 'classname' => 'sp', 'description' => __('Een widget om tekst te plaatsen', 'sp') );
    
    		$control_ops = array( 'width' => 300, 'height' => 350, 'id_base' => 'sp' );
    
    		$this->WP_Widget( 'sp', __('sp', 'sp'), $widget_ops, $control_ops );
    	}
    
    	function widget( $args, $instance ) {
    		extract( $args );
    
    		//Our variables from the widget settings.
    		$title = apply_filters('widget_title', $instance['title'] );
    		$content = $instance['content'];
    
    		echo $before_widget;
    
    		// Display the widget title
    		if ( $title )
    			echo $before_title . $title . $after_title;
    
    		//Display the name
    		if ( $content )
    			printf( __('<span style="padding-right:15px;">'.$instance['content']). '</span>', 'sp');
    
    		if ( $show_info )
    			printf( $name );
    
    		echo $after_widget;
    	}
    
    	//Update the widget 
    
    	function update( $new_instance, $old_instance ) {
    		$instance = $old_instance;
    
    		//Strip tags from title and name to remove HTML
    		$instance['title'] = strip_tags( $new_instance['title'] );
    		$instance['title'] = strip_tags( $new_instance['title'] );
    
    		return $instance;
    	}
    
    	function form( $instance ) {
    
    		//Set up some default widget settings.
    		$defaults = array( 'title' => __('sp', 'sp'));
    		$instance = wp_parse_args( (array) $instance, $defaults ); ?>
    		<p>
    			<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e('Titel:', 'sp'); ?></label>
    			<input id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo $instance['title']; ?>" style="width:100%;" />
    		</p>
    
            <p>
                 <select name="<?php echo $this->get_field_id( 'select_post' ); ?>" id="<?php echo $this->get_field_id( 'select_post' ); ?>">
                 <?php
                 global $post;
    			 $args = array( 'numberposts' => -1);
                 $posts = get_posts($args);
                 foreach( $posts as $post ) : setup_postdata($post); ?>
                 <option value="<?php echo $post->ID; ?>"<?php selected( $instance['select_post'], 'select_post' ); ?>><?php the_title(); ?></option>
    nt'], 'title' ); ?><?php the_title(); ?></option>
                 <?php endforeach; ?>
                 </select>
            </p>
            <p>
                 <select name="<?php echo $this->get_field_id( 'select_job' ); ?>" id="<?php echo $this->get_field_id( 'select_job' ); ?>">
                 <?php
                 global $post;
    			 $args = array( 'post_type' => 'jobman_job');
                 $posts = get_posts($args);
                 foreach( $posts as $post ) : setup_postdata($post); ?>
                 <option value="<?php echo $post->ID; ?>"><?php the_title(); ?></option>
                 <?php endforeach; ?>
                 </select>
            </p>
    	<?php
    	}
    }
    
    ?>
Viewing 3 replies - 1 through 3 (of 3 total)
  • Moderator bcworkz

    (@bcworkz)

    The Widgets API isn’t that clear about how data moves about in widgets, I’m hoping if I explain it some that you’ll have a better direction to investigate further.

    Keep in mind $instance in all cases is the data from the backend form saved in the database and passed in each function as an array. You’ve more or less gotten the backend form fleshed out in form(). It appears you have the currently stored value being displayed as the default selection in the first option list, but not the second. If that’s by design, then fine, otherwise consider doing something similar for the second list.

    When this form is submitted, it is passed through update() for validation. The function is passed both the stored data and the new data so you can evaluate what has changed for your own purposes. Whatever form of $instance returned here becomes the new values saved in the DB.

    When the frontend sidebar wants to display the widget, the widget() function is called. The $args array contains HTML that should be echoed out in appropriate places, such as before and after widget, title, etc. Again, $instance has the values from the DB. Based on this, collect your data and prepare it, then echo out the appropriate content as required.

    I hope this helps you figure out what you need to do.

    Thread Starter mvanboordt

    (@mvanboordt)

    I can appriciate the answer you gave me. This was and now is pretty clear for me.

    However the problem lies in the connection from widget content to the db and to the front-end.

    Like this.

    I have the options list setup in the widget with an foreach loop

    <select name="<?php echo $this->get_field_id( 'berichten' ); ?>" id="<?php echo $this->get_field_id( 'berichten' ); ?>">
                 <?php
                 global $post;
    			 $args = array( 'numberposts' => -1);
                 $posts = get_posts($args);
                 foreach( $posts as $post ) : setup_postdata($post); ?>
                 <option value="<?php echo get_permalink($post->ID);?>" ); ?>><?php the_title(); ?></option>
                 <?php endforeach; ?>
                 </select>

    I see everywhere that the value of an input field is a $instance[‘name’]

    I don’t know where to put this in the option list because the value must be the url of the post!

    If I can figure that out then I know what is saved to the db and can select if at the front-end.

    Moderator bcworkz

    (@bcworkz)

    A kind way to say I have not told you anything new 🙂
    Apologies, it is often difficult to know what people know or do not know. It was not a waste though, as it caused you to ask a more specific question.

    You use the value in $instance, the last URL selected, to match against the option list values so your script knows where to add the ‘selected’ attribute. If the previous selection is not important, you can ignore the value in $instance. If you do use it, you must also account for the initial state where there is no value in $instance if it is important for a particular option to be the default.

    When the new value from the option list is submitted, it is passed to update(). The receipt of the POST data and parsing it into $instance is done for you behind the scene by class private methods. You do not need to do anything special. In update() you should ensure the submitted value is a valid value. It’s possible for a user to submit any value under the field name, be sure it’s one of your values. Whatever update() returns is then stored in the DB, again, behind the scene. Once you return $instance, the rest is handled for you.

    Then, of course widget() is called and passed the value in the DB for it’s use in displaying appropriate content.

    I know I’m going over familiar territory again, but I’m still not clear exactly where you are not making the right connection, so I’m inclined to give a lot of information in hopes some part makes the connection for you.

    Or maybe a different approach will make things easier to see. Even though the permalink is perhaps what you ultimately need to show the needed data in the frontend, it does not need to be what is stored in the DB.

    Consider storing the post ID instead. The option list values are assigned post IDs. Validating an ID in update() is trivial. When widget() is passed the ID, it can then get the permalink for output. It’s also much easier to get other post data based on ID. It’s less easy to get post data from an URL.

    As you can see, you can store anything in the DB, as long as it can be correlated with the actual data needed when widget() is called. I hope this time you can see how to proceed. If not, rephrase your question and I will try again to answer.

Viewing 3 replies - 1 through 3 (of 3 total)
  • The topic ‘Widget get_posts’ is closed to new replies.