I would like to use the titles within a select element in a form I am echoing to the client side. What would be the best way to do this?

  • The question is not very clear. Are you trying to return all post titles for all posts under specific post type? Is that right? Sep 21, 2016 at 10:11
  • Sorry! Yes exactly, I have made a custom post type, created a few posts of this type, and I want to echo a form with a select element which allows a user to select one of the titles (They represent projects) to donate to. Sep 21, 2016 at 10:12

4 Answers 4


Query all post titles of a specific post type

// Function that returns post titles from specific post type as form select element
// returns null if found no results.

function output_projects_list() {
    global $wpdb;

    $custom_post_type = 'page'; // define your custom post type slug here

    // A sql query to return all post titles
    $results = $wpdb->get_results( $wpdb->prepare( "SELECT ID, post_title FROM {$wpdb->posts} WHERE post_type = %s and post_status = 'publish'", $custom_post_type ), ARRAY_A );

    // Return null if we found no results
    if ( ! $results )

    // HTML for our select printing post titles as loop
    $output = '<select name="project" id="project">';

    foreach( $results as $index => $post ) {
        $output .= '<option value="' . $post['ID'] . '">' . $post['post_title'] . '</option>';

    $output .= '</select>'; // end of select element

    // get the html
    return $output;

// Then in your project just call the function
// Where you want the select form to appear
echo output_projects_list();
  • 3
    This is an overly complex function for something that can easily be done using the API that WordPress provides in the WP_Query class. The answer provided by @ialocin is far better. You shouldnt need $wpdb for this. Sep 22, 2016 at 19:07
  • Yes and what is the point of the comment? :) Sep 22, 2016 at 20:19
  • 1
    @Brian What is far better about the other answer? This is technically faster as you are grabbing only the data that you need from mysql. The other answer (easier answer) grabs all the data into memory then modifies it afterwards in PHP. Thats more work for PHP. Both are acceptable but each have their strengths. If you know mysql then this isn't overly complex at all. Its pretty simple.
    – JoeMoe1984
    Jan 5, 2018 at 20:21
  • I agree with @JoeMoe1984, This function isn't as simple as the other answer... BUT it is MUCH more efficient from a memory perspective. SQL is a FAR better place (than wp_list_pluck(...)) to reduce/extract the valuable information from. Yes, it is slightly more complex, but your system will thank you for that...
    – mawalker
    Mar 15, 2018 at 9:31

You could - and in my mind, should - use API functions to get the data.

// query for your post type
$post_type_query  = new WP_Query(  
    array (  
        'post_type'      => 'your-post-type',  
        'posts_per_page' => -1  
// we need the array of posts
$posts_array      = $post_type_query->posts;   
// create a list with needed information
// the key equals the ID, the value is the post_title
$post_title_array = wp_list_pluck( $posts_array, 'post_title', 'ID' );
  • 3
    +1 for wp_list_pluck(). I always forget about that one...
    – FaCE
    Sep 21, 2016 at 10:58
  • +1 for introducing me to the pluck! How had I not seen this before??
    – Chizzle
    Sep 8, 2017 at 1:36
  • +1 for the one-liner.... One-liners always rock! Sep 18, 2021 at 15:23
  • 1
    Beware this will easily overload sites with lots of posts. Running WP_Query with 'posts_per_page' => -1 without sufficiently restrictive filters is an easy way to crash a site or run out of server resources. Aug 22, 2022 at 9:55
  • You're not wrong @sbnc.eu but the question was how to get all the titles. Aug 26, 2022 at 12:10

For an hierarchical post type, we have the built-in:

        'post_type' => 'page',
        'echo'      => 1, 
        'name'      => 'wpse_titles', 
        'id'        => 'wpse-titles' 

that will generate a select element with post titles and the post ID as the option value.


<select name='wpse_titles' id='wpse-titles'>
    <option class="level-0" value="1">AAA</option>
    <option class="level-0" value="2">BBB</option>
    <option class="level-1" value="3">&nbsp;&nbsp;&nbsp;CCC</option>

It's not clear from the documentation for wp_dropdown_pages(), but it's a wrapper for get_pages() and also support it's input arguments.


The way I have always done things like this is using get_posts and foreach like something below:

// Create our arguments for getting our post
$args = [

// we get an array of posts objects
$posts = get_posts($args);

// start our string
$str = '<select>';
// then we create an option for each post
foreach($posts as $key=>$post){
  $str .= '<option>'.$post->post_title.'</option>';
$str .= '</select>';
echo $str;
  • This is working well, thank you. I am attempting to add 'selected' to the option currently saved, I've tried a lot of different bits of code and finally have come to this, which is allowing me to update the option but the 'selected' isn't being added to the correct one. Any pointers on what I'm doing wrong? ` $str .= '<option '. ($post == $value2 ? 'selected=selected' : '') .'>'. $post->post_title .'</option>';` Many thanks for any suggestions p.s. Sorry I don't seem to be adding code correctly, tried backticks
    – Jo_pinkish
    Aug 26, 2017 at 12:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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