Obtener lista de tipos de contenido personalizados registrados
¿Cómo puedo obtener una lista de todos los tipos de contenido personalizados registrados y mostrarlos en cualquier página de plantilla?
Tengo un código como este.
<?php
/**
* Nombre de la Plantilla: Lista de Tipos de Contenido Personalizados
*/
get_header();
$args=array(
'public' => true,
'exclude_from_search' => false,
'_builtin' => false
);
$output = 'names'; // names u objects, ten en cuenta que names es el valor predeterminado
$operator = 'and'; // 'and' u 'or'
$post_types = get_post_types($args,$output,$operator);
$posttypes_array = array();
foreach ($post_types as $post_type ) {
$posttypes_array[] = $post_type;
}
echo "<pre>";
print_r($posttypes_array);
echo "</pre>";
get_footer();
?>

Tu código se ve bien. Sin embargo, puedes probar los siguientes códigos para obtener todas las publicaciones personalizadas:
$args = array(
'public' => true,
'_builtin' => false,
);
$output = 'names'; // nombres u objetos, nota que names es el valor por defecto
$operator = 'and'; // 'and' (y) u 'or' (o)
$post_types = get_post_types( $args, $output, $operator );
foreach ( $post_types as $post_type ) {
echo '<p>' . $post_type . '</p>';
}
?>
También puedes usar varios argumentos para filtrar más tu resultado. Para ver una lista detallada de argumentos puedes consultar la página oficial del Codex de WordPress: https://codex.wordpress.org/Function_Reference/get_post_types

Si deseas obtener todos los tipos de entradas como una lista, necesitas usar la función get_post_types y recorrer los resultados con un bucle foreach
.
<?php
// Obtener todos los tipos de entradas como lista
foreach ( get_post_types( '', 'names' ) as $post_type ) {
echo '<p>'.$post_type.'</p>';
}
?>
Estas 2 líneas de código pueden listar todos tus tipos de entradas registrados. Si quieres saber más sobre esta función get_post_types, visita la página oficial del codex de WordPress: https://codex.wordpress.org/Function_Reference/get_post_types

global $wp_post_types;
$posttypes = array_keys( $wp_post_types );
// Eliminar _builtins u otros tipos de post no deseados
$pt_remove = array("attachment","nav_menu_item","customize_changeset","revision");
foreach ( $posttypes as $posttype ):
if ( in_array($posttype, $pt_remove) ) continue;
$posttype_names[ $posttype ] = $posttype;
endforeach;
echo "<pre>";
print_r($posttype_names);
echo "</pre>";

<?php
$args = array(
'post_type' => 'clients', // Tipo de post: clientes
'post_status' => 'publish', // Estado: publicado
'tax_query' => array( // Consulta de taxonomía
array(
'taxonomy' => 'clients_service', // Taxonomía: servicio de clientes
'field' => 'slug', // Campo: slug
'terms' => 'therapy' // Término: terapia
)
)
);
$testimonials = new WP_Query( $args ); // Nueva consulta WP_Query
if( $testimonials->have_posts() ) : // Si hay posts
?>
<ul>
<?php
while( $testimonials->have_posts() ) : // Mientras haya posts
$testimonials->the_post();
?>
<li><?php printf( '%1$s - %2$s', get_the_title(), get_the_content() ); ?></li> // Mostrar título y contenido
<?php
endwhile;
wp_reset_postdata(); // Restablecer datos del post
?>
</ul>
<?php
else :
esc_html_e( '¡No hay clientes en la taxonomía de terapia!', 'text-domain' ); // Mensaje si no hay posts
endif;
?>
Cuando se llama a new WP_Query, se recuperan los clientes relevantes y podemos iterar a través de ellos. En el bucle simplemente mostramos el título y el contenido del cliente en una lista simple.

Tu código es correcto. El problema está en el momento de ejecución de ambos:
- Registrar el CPT (Tipo de contenido personalizado)
- Llamar a la función de tipo de post que escribiste.
Tienes una de 2 soluciones:
Solución 1:
Asegúrate de que tu CPT se registre con mayor prioridad antes de llamar a la función get_post_types
.
Solución 2:
Reduce la prioridad de get_post_types
para que se ejecute después de que el CPT esté registrado.
add_action('init', 'tu_nombre_de_funcion', 10);
Espero que esto ayude.
Gracias
