First of all, sorry for my English, I'll try to make it understandable. I'm new on WordPress; I already have created a few plugins but they didn't needed admin configuration. Now I'd like to make an other one that creates a widget where the administrator can choose a post of a custom post type from a dropdown. I have a custom post type "event type 1" and another "event type 2", and I am trying to create a dropdown that lists posts of both of these post types.

I thought to make a request to list all post in a dropdown and then save the ID of this post. But I'm not sure it's the good way to do it, and I'm not even sure how I can do it in Wordpress.

If anybody has any tips on this, I would appreciate that.

For now this is a simple widget from a tutorial. I will change the display to have the information of the post I want and I have to add the dropdown for choosing the post. The current code is as follows:

// Creating the widget 
class event_widget extends WP_Widget {

    function __construct() {
            // Base ID of your widget

            // Widget name will event_widgetappear in UI
            __('Event Widget', 'my_event_widget'), 

            // Widget description
            array( 'description' => __( 'Event Widget', 'my_event_widget' ), )

    public function widget( $args, $instance ) {
        $title = apply_filters( 'widget_title', $instance['title'] );

        echo $args['before_widget'];

        if ( ! empty( $title ) ) {
            echo $args['before_title'] . $title . $args['after_title'];

        echo __( 'Hello, World!', 'my_event_widget' );
        echo $args['after_widget'];

    public function form( $instance ) {    
        if ( isset( $instance[ 'title' ] ) ) {
            $title = $instance[ 'title' ];
        else {
            $title = __( 'New title', 'my_event_widget' );
            <label for="<?php echo $this->get_field_id( 'title' ); ?>">
                <?php _e( 'Title:' ); ?>
            <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name(     'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" />


    public function update( $new_instance, $old_instance ) {
        $instance = array();
        $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';

        return $instance;


function wpb_load_event_widget() {
    register_widget( 'event_widget' );
add_action( 'widgets_init', 'wpb_load_event_widget' );
  • Have you already created a settings screen for your widget and are you just looking for a way to list posts of a custom post type in a dropdown?
    – engelen
    Mar 27, 2016 at 16:54
  • Yes that's what i'm looking for
    – Mathilde
    Mar 27, 2016 at 17:27
  • Please answer my question. Have you already created a settings screen for your widget?
    – engelen
    Mar 27, 2016 at 18:00
  • 1
    Sorry, Yes i have already done it, i have all my code i just don't know how to display the list of custom post in the dropdown
    – Mathilde
    Mar 27, 2016 at 18:35
  • Two more questions: Could you post your code in your original question? Do you want to display a dropdown with posts from both custom post types?
    – engelen
    Mar 27, 2016 at 18:42

1 Answer 1


First off, try to work on your code formatting. As it is, it's rather unreadable and this makes it not only more difficult for us to understand how to help you, but also less scalable and suited for future use. Always try to adhere to the WordPress PHP Coding Standards.

Now, on to the beef of the problem...

To add a new setting to a widget, you have to implement functionality in two class method of the class you already have: form() and update(). In form(), we're going to display the post dropdown, and in update(), we're going to save the selected post.

Displaying the dropdown

To display the dropdown, we utilize WP_Query, which creates a query for fetching all posts. We place this code in the form function before actually displaying anything. The code below fetches all (posts_per_page=1) posts from post types post and page (post_type=post,page), ordering them by title (orderby=post_title) ascendingly (order=ASC). The resulting posts are stored in the property $posts_query->posts.

$posts_query = new WP_Query( array(
    'post_type' => array( 'post', 'page' ), // Replace by your posts types for event type 1 and 2
    'posts_per_page' => -1,
    'orderby' => 'post_title',
    'order' => 'ASC'
) );

Next, we display the dropdown in the form() method as well, by simply looping over the posts found.

    <label for="<?php echo $this->get_field_id( 'post' ); ?>"><?php _e( 'Post' ); ?></label>
    <select name="<?php echo $this->get_field_name( 'post' ); ?>" id="<?php echo $this->get_field_id( 'post' ); ?>" class="widefat">
        <?php foreach ( $posts_query->posts as $post ) : ?>
            <option value="<?php echo $post->ID; ?>" <?php selected( $post->ID, $instance['post'] ); ?>>
                <?php echo $post->post_title; ?>
        <?php endforeach; ?>

Try to understand the code above, as you will need it for creating more widget options in the future!

Saving the post selected in the form

Now, we use the update() method to save the selected post when somebody saves the widget. To do so, just one more line is required right before $instance is returned.

$instance['post'] = $new_instance['post'];

This adds the new post to the instance array that will be used to update the instance.

This should be enough..

..to help you on your way. Good luck with displaying the post in the widget!

  • Yeah sorry for the code formatting, i haven't use PHP since a long time and never Wordpress, i'm a little bit confuse with the syntax and all the sample code i find. Thanks for your answer, that was the one i got in mind but i was hoping for something shorter from wordpress ^^ If there isn't i will implement it this way, thanks again for the sample code and the explanation. That was all i needed to end that website.
    – Mathilde
    Mar 29, 2016 at 20:04
  • Well, you could use wp_dropdown_pages for the dropdown itself, but I'd advise against it as it presets several arguments and is therefore, in my opinion, less transparent. Either way, if the answer answers your question, please accept it as the answer so that it won't show up as unanswered anymore :-).
    – engelen
    Mar 30, 2016 at 8:46

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.