Obtener el extracto por ID
¿Por qué no se puede obtener el extracto por ID como con el título y la mayoría de los otros elementos?
Por ejemplo, get_the_excerpt(ID). Sé cómo usar la función $post->post_excerpt pero eso no devuelve parte del contenido si no se ingresó un extracto, simplemente no devuelve nada.
Entonces, lo que estoy tratando de hacer es obtener el extracto por ID si existe un extracto, y si no hay un extracto con ese ID pero hay algún contenido, obtener parte del contenido en su lugar.
¿Cómo se podría hacer eso?
¿Alguna idea?
Maravilloso...
EDICIÓN --
Código fuente del bucle según lo solicitado.
<?php $stories = get_posts('category_name=feedback&numberposts=4');
foreach ($stories as $post) :
$title = $post->post_title;
$excerpt = get_the_excerpt_id($post->ID);
$thumb = get_the_post_thumbnail($post->ID,array(60, 60, true));?>
<div class="textstandard_white" style="font-size:14px; line-height:22px; padding-top:10px;"><b><a href="<?php echo get_permalink($post->ID);?>"><?php echo $title;?></a></b></div><div align="left" style="height:18px; width:82px; background:url(http://www.divethegap.com/update/z-images/structure/icons/stars.png) left top no-repeat;"><div id="stars<?php echo $post->ID;?>" align="left" style="height:18px; background:url(http://www.divethegap.com/update/z-images/structure/icons/stars_glow.png) left top no-repeat;">
</div>
</div>
<script type="text/javascript">
var width<?php echo $post->ID;?> = ((<?php
$Rating = get_post_meta($post->ID, "Rating", true);
echo $Rating;
?> * 20) + '%')
$('#stars<?php echo $post->ID;?>').css('width', width<?php echo $post->ID;?>);
</script><div class="textstandard_white" style="padding-top:6px; font-size:10px; color:#BBB; padding-bottom:10px; border-bottom:1px dotted #BBB; min-height:70px;"><div style="float:left; padding-right:6px; padding-bottom:6px;"><div style="background:#FFF; border:1px solid #FFF;
border-radius: 4px; -moz-border-radius: 4px ; -webkit-border-radius: 4px; padding:4px;"><a href="<?php echo get_permalink($post->ID);?>"><?php echo $thumb;?></a></div></div>
<?php echo $excerpt;?></div>
<?php endforeach;?>

Hola @Robin I. Knight:
Considero que get_the_excerpt()
es una función con un diseño heredado. A medida que el uso de WordPress ha crecido, existen muchos casos de uso más nuevos donde no encaja, pero donde las funciones más recientes para obtener diferentes datos sí lo hacen. Un ejemplo es el uso frecuente ahora de un array $args
de opciones de función.
Pero es fácil solucionarlo para tus necesidades. Aquí tienes una función alternativa que puedes usar y que puedes colocar en cualquier parte del archivo functions.php
de tu tema:
function robins_get_the_excerpt($post_id) {
global $post;
$save_post = $post;
$post = get_post($post_id);
$output = get_the_excerpt();
$post = $save_post;
return $output;
}
No lo he probado, pero estoy bastante seguro de que está bien. Si esto no satisface tus necesidades, por favor amplía la información y tal vez pueda hacer otras sugerencias.

Funciona. Más o menos. Resultados muy extraños. Definitivamente está realizando su función pero los resultados son raros. Lo estoy usando junto con GET_Posts y por alguna razón los 2 primeros get posts son siempre los mismos. Aquí hay un enlace y verás a lo que me refiero. Mira los 4 posts en el lado derecho. http://www.divethegap.com/update/community/feedback/2010/06/steve-riches/

@Robin I Knight: Por favor publica el código fuente de tu loop como una actualización a tu pregunta; es muy difícil depurar código sin ver el código. También podría ser un plugin el que está causando el problema; prueba desactivándolos uno por uno.

Por cierto, cambié el nombre de la función a get_the_excerpt_id($post_id)

@Robin I Knight - No veo nada en tu loop, pero podrías intentar llamar a setup_postdata($post)
al inicio de tu loop, como sugiere @Rarst. Si eso no funciona, podría ser un plugin que necesitas desactivar; ¿lo has intentado? Y probablemente no quieras llamarla get_the_excerpt_id()
porque WordPress podría agregar esa función en el futuro y romper tu sitio. Y probablemente podrías prescindir de la función en tu loop usando foreach($stories as $story): global $post; $post = $story;
en su lugar.

La mecánica del extracto es extremadamente confusa. No es una respuesta precisa a tu pregunta, pero en general, si necesitas que las etiquetas de plantilla, específicas del Loop, funcionen con un array devuelto por get_posts()
, puedes emular el Loop de esta manera:
$stories = get_posts();
foreach ($stories as $post) {
setup_postdata($post);
// código personalizado
}
wp_reset_postdata();

@cwd si solo usas setup_postdata()
la consulta global no se ve afectada y solo los datos del post necesitan ser restablecidos.

Esta solución es mucho más limpia que almacenar el post en otra variable y requerir otro post solo para hacerlo global. +1

Desde la versión 3.3.0 existe una nueva función: wp_trim_words
La estoy utilizando fuera del bucle de la siguiente manera:
<?php if ( $post_id ) {
$post = get_post( $post_id );
if ( $post ) { ?>
<h2><?php echo $post->post_title; ?></h2>
<p><em><?php echo wp_trim_words( $post->post_content ); ?></em></p>
<p><strong>Este artículo solo puede ser leído por suscriptores.</strong></p>
<?php } } ?>
Esto no debe confundirse con wp_trim_excerpt que aparentemente solo funciona dentro del bucle, ya que internamente llama a the_content().

Solo para agregar a la respuesta de MikeSchinkel, que por alguna razón no funcionó para mí. Tuve que agregar la línea setup_postdata para que funcione.
function get_the_excerpt( $post_id ){
global $post;
$save_post = $post;
$post = get_post($post_id);
setup_postdata( $post ); // hola
$output = get_the_excerpt();
$post = $save_post;
return $output;
}
Supongo que si estás usando esto fuera del loop, no debería interferir con otros setup_postdata que estén ocurriendo.
Saludos

Si TODOS tus posts tienen la etiqueta <!--more-->
, entonces puedes usar lo siguiente con tu código anterior:
$sjc_excerpt = explode( '<!--more-->', $post->post_content);
echo wpautop( $sjc_excerpt[0] );
Por supuesto, si tienes algún post que no tenga la etiqueta <!--more-->
, se mostrará completo. Funciona en mi situación, pero no para todos...

Considero que get_the_excerpt()
es una función con un diseño heredado. A medida que el uso de WordPress ha crecido, existen muchos casos de uso más nuevos donde no encaja, pero donde las funciones más nuevas para obtener diferentes datos sí lo hacen. Un ejemplo es el uso ahora frecuente de un array $args
de opciones de función.
Pero es fácil adaptarla a tus necesidades. Aquí tienes una función alternativa que puedes usar y que puedes colocar en cualquier parte del archivo functions.php
de tu tema:
function robins_get_the_excerpt($post_id) {
global $post;
$save_post = $post;
$post = get_post($post_id);
$output = get_the_excerpt();
$post = $save_post;
return $output;
}
Para complementar la respuesta de MikeSchinkel, que por alguna razón no funcionó para mí. Tuve que agregar la línea setup_postdata para que funcionara.

Este es un pequeño código de dos líneas que uso mucho utilizando wp_trim_words. Constantemente me encuentro necesitando las funcionalidades de abreviación y "leer más" fuera del loop. Puede que a alguien más le resulte útil. Esto es lo que uso para:
- Obtener el extracto (excerpt) por ID de entrada (POST ID)
- Obtener el contenido de la entrada si no se ha establecido un extracto
- Establecer la longitud en palabras del extracto
- Elegir el contenido para el "Leer más" (enlace o texto)
Coloco esto directamente en línea, en la plantilla personalizada que estoy editando.
//Obtener el objeto de la entrada
$dapost = get_post(POST_ID);
//Obtener el extracto
$my_excerpt = wp_trim_words( apply_filters( "the_excerpt", get_the_excerpt($dapost) ? get_the_excerpt($dapost) : $dapost->post_content ), "20", "<a href='$dapost->guid'> ".__('Obtener más información', 'translation')."</a>" );
Desglose
1. El contenido del extracto
Obtener el extracto por ID de entrada, pero obtener el contenido de la entrada si no se ha establecido un extracto.
Estoy usando la forma abreviada de If/Else en PHP.
$dapost = get_post(POST_ID);
apply_filters( "the_excerpt", get_the_excerpt($dapost) ? get_the_excerpt($dapost) : $dapost->post_content
2. Longitud en palabras
Establecer la cantidad de palabras en el extracto a 20
"20"
3. Elegir contenido para "Leer más" (enlace/texto)
"<a href='$dapost->guid'> ".__('Obtener más información', 'translation')."</a>"
Usé $dapost->guid
para obtener la URL porque no necesitaba URLs amigables y quería evitar otra llamada a la base de datos. Siempre podrías usar get_the_permalink.
Consulta wp_trim_words en la documentación de WordPress.

A partir de WP 4.5.0 es posible usar el ID del post como parámetro
get_the_excerpt( $post->ID )
Fuente:https://developer.wordpress.org/reference/functions/get_the_excerpt/

Por muy molesto que pueda ser, en realidad es bastante sencillo de hacer
// Función para obtener el extracto de un post por su ID
function cameronjonesweb_get_excerpt_by_id( $post_id ) {
// Aplica los filtros y devuelve el extracto recortado
return apply_filters( 'get_the_excerpt', wp_trim_excerpt( '', $post_id ), $post_id );
}
