¿Cómo obtener todos los títulos de las entradas de un tipo de publicación específico?
Me gustaría usar los títulos dentro de un elemento select en un formulario que estoy mostrando en el lado del cliente. ¿Cuál sería la mejor manera de hacer esto?

Podrías - y en mi opinión, deberías - utilizar funciones de la API para obtener los datos.
// consulta para tu tipo de post personalizado
$post_type_query = new WP_Query(
array (
'post_type' => 'tu-tipo-de-post',
'posts_per_page' => -1
)
);
// necesitamos el array de posts
$posts_array = $post_type_query->posts;
// creamos una lista con la información necesaria
// la clave equivale al ID, el valor es el título del post
$post_title_array = wp_list_pluck( $posts_array, 'post_title', 'ID' );

Ten cuidado, esto puede sobrecargar fácilmente sitios con muchas publicaciones. Ejecutar WP_Query con 'posts_per_page' => -1
sin filtros suficientemente restrictivos es una manera fácil de colapsar un sitio o agotar los recursos del servidor.

No estás equivocado @sbnc.eu pero la pregunta era cómo obtener todos los títulos.

Correcto, y lo que estoy diciendo es que este método solo es viable para sitios pequeños. Si hay muchas publicaciones, una consulta personalizada es obligatoria. La diferencia en rendimiento y consumo de memoria puede ser demasiado grande para ignorarla.

Consultar todos los títulos de publicaciones de un tipo de publicación específico
// Función que devuelve los títulos de publicaciones de un tipo de publicación específico como elemento select de formulario
// devuelve null si no encuentra resultados.
function output_projects_list() {
global $wpdb;
$custom_post_type = 'page'; // define aquí el slug de tu tipo de publicación personalizado
// Una consulta SQL para devolver todos los títulos de publicaciones
$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 );
// Devuelve null si no encontramos resultados
if ( ! $results )
return;
// HTML para nuestro select que imprime los títulos de publicaciones como bucle
$output = '<select name="project" id="project">';
foreach( $results as $index => $post ) {
$output .= '<option value="' . $post['ID'] . '">' . $post['post_title'] . '</option>';
}
$output .= '</select>'; // fin del elemento select
// obtener el html
return $output;
}
// Luego en tu proyecto simplemente llama a la función
// Donde quieras que aparezca el formulario select
echo output_projects_list();

Esta es una función demasiado compleja para algo que se puede hacer fácilmente usando la API que WordPress proporciona en la clase WP_Query. La respuesta proporcionada por @ialocin es mucho mejor. No deberías necesitar $wpdb para esto.

@Brian ¿Qué tiene de mucho mejor
la otra respuesta? Técnicamente esta es más rápida ya que solo obtienes los datos que necesitas directamente de MySQL. La otra respuesta (la más fácil) obtiene todos los datos en memoria y luego los modifica después en PHP. Eso es más trabajo para PHP. Ambas son aceptables pero cada una tiene sus fortalezas. Si conoces MySQL, esto no es demasiado complejo. Es bastante simple.

Estoy de acuerdo con @JoeMoe1984, esta función no es tan simple como la otra respuesta... PERO es MUCHO más eficiente desde la perspectiva de memoria. SQL es un lugar MUCHO mejor (que wp_list_pluck(...)) para reducir/extraer la información valiosa. Sí, es un poco más complejo, pero tu sistema te lo agradecerá...

Para un tipo de publicación jerárquico, tenemos la función incorporada:
wp_dropdown_pages(
[
'post_type' => 'page',
'echo' => 1,
'name' => 'wpse_titles',
'id' => 'wpse-titles'
]
);
que generará un elemento select con los títulos de las publicaciones y el ID de la publicación como valor de la opción.
Ejemplo:
<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"> CCC</option>
</select>
No está claro en la documentación de wp_dropdown_pages()
, pero es un envoltorio para get_pages()
y también admite sus argumentos de entrada.

La forma en que siempre he hecho cosas como esta es usando get_posts
y foreach
como algo similar a lo siguiente:
// Creamos nuestros argumentos para obtener nuestro post
$args = [
'post_type'=>'custom-slug'
];
// obtenemos un array de objetos post
$posts = get_posts($args);
// iniciamos nuestra cadena
$str = '<select>';
// luego creamos una opción para cada post
foreach($posts as $key=>$post){
$str .= '<option>'.$post->post_title.'</option>';
}
$str .= '</select>';
echo $str;

Esto está funcionando bien, gracias. Estoy intentando añadir 'selected' a la opción actualmente guardada, he probado muchos fragmentos de código diferentes y finalmente llegué a esto, lo cual me permite actualizar la opción pero el 'selected' no se está añadiendo al correcto. ¿Alguna sugerencia sobre lo que estoy haciendo mal?
$str .= '<option '. ($post == $value2 ? 'selected=selected' : '') .'>'. $post->post_title .'</option>';
Muchas gracias por cualquier sugerencia
P.D. Disculpa, parece que no estoy añadiendo el código correctamente, he probado con backticks
