¿Cómo incluir saltos de línea en the_excerpt?
¿Cómo puedo incluir un salto de línea dentro de the_excerpt? He modificado la longitud y el botón "leer más" a través de mi functions.php. Estoy usando extractos para cada entrada del blog y a veces se ve un poco feo que no haya saltos de línea incluidos.

Al igual que la solución de Johannes Pille, la siguiente solución debería ser más adaptable.
En detalle:
- sobreescribir la función wp_trim_excerpt
- eliminar el filtro antiguo y agregar un nuevo filtro personalizado
Aquí está el código completo:
// agregar a themes/{tu_tema}/functions.php
define('EXCERPT_RARELY', '{[}]');
define('EXCERPT_BR', nl2br(PHP_EOL));
function so306588_trim_excerpt_custom($text = '')
{
add_filter('the_content', 'so306588_trim_excerpt_custom_mark', 6);
// pasar por el filtro original
$text = wp_trim_excerpt($text);
remove_filter('the_content', 'so306588_trim_excerpt_custom_mark', 6);
return so306588_trim_excerpt_custom_restore($text);
}
function so306588_trim_excerpt_custom_mark($text)
{
$text = nl2br($text);
return str_replace(EXCERPT_BR, EXCERPT_RARELY, $text);
}
function so306588_trim_excerpt_custom_restore($text)
{
return str_replace(EXCERPT_RARELY, EXCERPT_BR, $text);
}
// eliminar filtro por defecto
remove_filter('get_the_excerpt', 'wp_trim_excerpt');
// agregar filtro personalizado
add_filter('get_the_excerpt', 'so306588_trim_excerpt_custom');

Me gusta. +1. Si el autor original hubiera aceptado el mío alguna vez, comentaría "Esta debería ser la respuesta aceptada (ahora)".

No existe un filtro que permita establecer etiquetas permitidas para que no sean eliminadas por the_excerpt()
. Podría considerarse una deficiencia del núcleo de WordPress.
De cualquier manera, la generación real del extracto no ocurre en esa etiqueta de plantilla, sino completamente en otro lugar:
Los extractos son generados por la función wp_trim_excerpt()
, dentro de la cual se aplican los filtros de extracto que ya estás utilizando (excerpt_length
y excerpt_more
) y que llama a wp_trim_words()
, que a su vez llama a wp_strip_all_tags()
. Las tres funciones se encuentran en wp-includes/formatting.php.
Por lo tanto, ante la ausencia de un filtro para este caso y la inevitabilidad de que tu extracto pase por wp_strip_all_tags()
, la única posibilidad de preservar algunas etiquetas es agregar una función de reemplazo personalizada para wp_trim_excerpt()
:
function wpse67498_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', ' ' . '[...]' );
$allowable = '<br>';
$text = preg_replace( '@<(script|style)[^>]*?>.*?</\\1>@si', '', $text );
$text = trim( strip_tags( $text, $allowable ) );
if ( 'characters' == _x( 'words', 'word count: words or characters?' )
&& preg_match( '/^utf\-?8$/i', get_option( 'blog_charset' ) ) )
{
$text = trim( preg_replace( "/[\n\r\t ]+/", ' ', $text ), ' ' );
preg_match_all( '/./u', $text, $words_array );
$words_array = array_slice( $words_array[0], 0, $num_words + 1 );
$sep = '';
} else {
$words_array = preg_split( "/[\n\r\t ]+/", $text, $num_words + 1, PREG_SPLIT_NO_EMPTY );
$sep = ' ';
}
if ( count( $words_array ) > $excerpt_length ) {
array_pop( $words_array );
$text = implode( $sep, $words_array );
$text = $text . $excerpt_more;
} else {
$text = implode( $sep, $words_array );
}
}
return apply_filters( 'wp_trim_excerpt', $text, $raw_excerpt );
}
remove_filter( 'get_the_excerpt', 'wp_trim_excerpt');
add_filter( 'get_the_excerpt', 'wpse67498_wp_trim_excerpt' );

Actualmente, es posible utilizar la función the_excerpt()
para mostrar el extracto con saltos de línea. Pero si prefieres retornar el resultado, puedes usar una función como esta:
function get_the_excerpt_theme() {
$excerpt = get_the_excerpt();
$excerpt = apply_filters( 'the_excerpt', $excerpt );
return $excerpt;
}
Esta función aplica los filtros al extracto usando apply_filters('the_excerpt', $excerpt )
como en la función de WordPress the_excerpt()
, pero retorna la cadena sin mostrarla.
Además, si deseas permitir solo saltos de línea en el extracto, puedes agregar $excerpt = strip_tags($excerpt,'<br>')
debajo de la línea apply_filters
.
¡Espero que te sea útil!

Una solución simple es reemplazar los saltos de línea antes de que WordPress los reemplace. Utilicé un carácter seleccionado arbitrariamente del área privada de Unicode ya que no se espera que aparezca en ningún contenido, además si aparece está destinado a uso privado para indicar que el manejo no está estandarizado.
add_filter('wp_trim_words', function($text, $num_words, $more, $original_text) {
static $filtering;
if ( $filtering ) {
return $text;
}
$filtering = true;
// Carácter aleatorio de un área de uso privado de Unicode
$private_use_char = "\u{101425}";
$text = str_replace( ["\n\r", "\n", "\r"], $private_use_char, $original_text);
$text = wp_trim_words($text, $num_words, $more);
$text = str_replace($private_use_char, "\n", $text); // o str_replace($private_use_char, "<br>", $text)
$filtering = false;
return $text;
}, 10, 4);
Ten en cuenta que esto resultará en caracteres "\n"
en la salida de the_excerpt()
y get_the_excerpt()
, por lo que probablemente quieras llamar a wpautop()
antes de usarlo en HTML. Alternativamente, puedes simplemente reemplazar $private_use_char
con <br>
en lugar de \n
como se indica en el comentario.

Bueno, la última versión de WordPress parece tratar el campo de extracto como un campo de contenido normal de publicación... Lo acabo de probar en SandboxWordpress.com y los saltos de línea ahora se convierten en etiquetas de párrafo separadas. Dicho esto, estoy seguro de que esto funcionaba en el pasado, de lo contrario no lo habría compartido. No estoy seguro de que fuera necesario un voto negativo, pero me alegra que hayan llamado mi atención sobre esto.

Bueno, puedo eliminar el voto negativo, aunque no estoy seguro de cuál es la forma correcta, porque a pesar de que creo que esto podría haber funcionado en el pasado, lo he probado y ya no funciona, por lo que sentí que perdí mi tiempo. Pero por otro lado, es cierto que ninguna respuesta puede permanecer válida para siempre cuando el sistema para el que está hecha cambia. Entonces, ¿cuál sería la forma adecuada de indicar que una respuesta ya no es útil, incluso si podría haberlo sido en el pasado? Estoy abierto a sugerencias. Por favor, agrega una nota en la respuesta indicando que ya no funciona con la última versión de WP, y eliminaré el voto negativo. ¿Trato hecho?
