apply_filters() y the_excerpt están dando resultados inesperados
Siento que debo estar pasando por alto algo bastante obvio, pero no puedo hacer que WordPress coopere.
Estoy generando etiquetas OG de Facebook con una función. Todo funciona bien, excepto el extracto.
Desde la obsolescencia de get_the_excerpt($post->ID)
, ¿hay otra manera de crear un extracto sin tener que crear un bucle completamente nuevo? Me parece excesivo.
Mi primer instinto fue usar apply_filters()
:
$description = apply_filters('the_excerpt', get_post($post->ID)->post_content);
Eso me da la entrada completa, con contenido formateado en HTML. Bien, debe estar mal. Entonces probé la siguiente idea lógica:
$description = apply_filters('get_the_excerpt', get_post($post->ID)->post_content);
No funciona. Ahora no hay HTML, pero sigue siendo la entrada completa (lo cual es realmente confuso).
Bien, no hay problema. Saltémonos todas las cosas elegantes y vayamos directamente al extracto recortado:
$description = wp_trim_excerpt(get_post($post->ID)->post_content);
Sin cambios.
Entonces, mi pregunta es: ¿qué diablos está pasando? ¿Hay algo que me esté perdiendo aquí?
Me metí en el núcleo de WP para ver cómo funciona the_excerpt()
, y parece ser idéntico a mi llamada:
/**
* Muestra el extracto de la entrada.
*
* @since 0.71
* @uses apply_filters() Llama al gancho 'the_excerpt' en el extracto de la entrada.
*/
function the_excerpt() {
echo apply_filters('the_excerpt', get_the_excerpt());
}
Tengo algunas preguntas basadas en mis hallazgos:
- ¿Por qué el filtro no se está aplicando como se espera?
- ¿Hay una manera de obtener el extracto fuera del bucle sin crear un nuevo bucle?
- ¿Estoy loco?
Gracias de antemano por echar un vistazo. Estoy bastante confundido aquí.
Resulta que la respuesta estaba en wp_trim_excerpt()
.
Está definido en wp-includes/functions.php:1879
:
/**
* Genera un extracto del contenido, si es necesario.
*
* La cantidad de palabras del extracto será de 55 palabras y si la cantidad es mayor
* que eso, se añadirá la cadena ' [...]' al extracto. Si la cadena
* tiene menos de 55 palabras, se devolverá el contenido tal cual.
*
* El límite de 55 palabras puede ser modificado por plugins/temas usando el filtro excerpt_length
* La cadena ' [...]' puede ser modificada por plugins/temas usando el filtro excerpt_more
*
* @since 1.5.0
*
* @param string $text Opcional. El extracto. Si está vacío, se genera un extracto.
* @return string El extracto.
*/
function wp_trim_excerpt($text = '') {
$raw_excerpt = $text;
if ( '' == $text ) {
$text = get_the_content('');
$text = strip_shortcodes( $text );
$text = apply_filters('the_content', $text);
$text = str_replace(']]>', ']]>', $text);
$excerpt_length = apply_filters('excerpt_length', 55);
$excerpt_more = apply_filters('excerpt_more', ' ' . '[...]');
$text = wp_trim_words( $text, $excerpt_length, $excerpt_more );
}
return apply_filters('wp_trim_excerpt', $text, $raw_excerpt);
}
Así que cualquier texto que se pase no se procesa; solo funciona si se llama con un parámetro vacío.
Para solucionar esto, añadí un filtro rápido a mi tema que resuelve el problema:
/**
* Permite la generación de extractos fuera del bucle.
*
* @param string $text El texto a recortar
* @return string El texto recortado
*/
function rw_trim_excerpt( $text='' )
{
$text = strip_shortcodes( $text );
$text = apply_filters('the_content', $text);
$text = str_replace(']]>', ']]>', $text);
$excerpt_length = apply_filters('excerpt_length', 55);
$excerpt_more = apply_filters('excerpt_more', ' ' . '[...]');
return wp_trim_words( $text, $excerpt_length, $excerpt_more );
}
add_filter('wp_trim_excerpt', 'rw_trim_excerpt');
Es algo redundante, pero me gusta más que abrir nuevos bucles cada vez que quiero generar un extracto.

Ah, no me quedó claro que estabas buscando solo la operación de texto (sin recuperar de la base de datos).

No hay problema. Siempre temo no tener sentido cuando hago preguntas. Sí estaba extrayendo de la base de datos, pero no quería abrir otro ciclo ya que tengo cosas como get_the_title($post->ID)
disponibles. La línea final de código fue $description = wp_trim_excerpt(get_post($post->ID)->post_content);

Me siento muy tonto preguntando esto, pero ¿cómo se llama a este nuevo filtro? Intenté usarlo como $content = apply_filters( 'rw_trim_excerpt', $content );
y $content = rw_trim_excerpt($content);
, pero ninguno funcionó (el primero no recortó la salida y el segundo produjo un error).

@QuantumDynamix Esto está diseñado para modificar el manejo de get_the_excerpt
para imitar the_excerpt
, por lo que puedes llamar: apply_filters('get_the_excerpt', $content);
.

Prueba:
get_post($post->ID)->post_excerpt
^^^^^^^^^^^^
Consulta: get_post
Codex para ver todos los miembros disponibles en el retorno.

Eso devuelve en blanco si no se ingresó un extracto para la publicación. Necesito imitar las acciones de get_the_excerpt() (creando un extracto si no existe ninguno).

Aplicar el filtro no hará eso, así que estás haciendo la pregunta incorrecta. No tengo idea de por qué estás buscando un extracto si no hay ninguno. get_the_excerpt()
no imita eso, revisa el código fuente, solo está accediendo a la variable miembro de $post
que es post_excerpt
. Consulta también el enlace del codex en la respuesta.

De la entrada del Codex sobre the_excerpt
: "mostrará un extracto automático que se refiere a las primeras 55 palabras del contenido de la publicación."
Estoy buscando imitar ese comportamiento fuera del loop.

Bueno, crea un segundo bucle temporalmente y consulta ese archivo por su ID para una solución rápida. Consulta Bucles Secundarios - http://codex.wordpress.org/Function_Reference/query_posts#Secondary_Loops

Puedes usar mi función personalizada para filtrar el contenido (es del NARGA Framework)
- Si la entrada tiene un extracto personalizado, mostrarlo en lugar del contenido
- Generar automáticamente un extracto del contenido si la entrada no tiene extracto personalizado
Recortar automáticamente shortcodes, código HTML, eliminar [...], añadir texto "Leer más" (traducible)
/** * Genera automáticamente un extracto del contenido si la entrada no tiene extracto personalizado * @from NARGA Framework - http://www.narga.net/narga-core * @param $excerpt_lenght El número máximo de palabras del extracto generado del contenido * @coder: Nguyễn Đình Quân a.k.a Narga - http://www.narga.net **/ function narga_excerpts($content = false) { # Si es la página de inicio, un archivo o resultados de búsqueda if(is_front_page() || is_archive() || is_search()) : global $post; $content = $post->post_excerpt; $content = strip_shortcodes($content); $content = str_replace(']]>', ']]>', $content); $content = strip_tags($content); # Si hay un extracto definido en la caja de Extracto Opcional if($content) : $content = apply_filters('the_excerpt', $content); # Si no hay extracto definido else : $content = $post->post_content; $excerpt_length = 50; $words = explode(' ', $content, $excerpt_length + 1); if(count($words) > $excerpt_length) : array_pop($words); array_push($words, '...<p><a class="more-link" href="' . get_permalink() . '" title="' . the_title_attribute('echo=0') . '"> ' . __( 'Leer más »', 'narga' ) . ' </a></p>'); $content = implode(' ', $words); endif; $content = '<p>' . $content . '</p>'; endif; endif; # Asegurarse de devolver el contenido return $content; } // Añadir filtro al contenido add_filter('the_content', 'narga_excerpts');
