Permitir HTML en el extracto

13 abr 2014, 00:11:46
Vistas: 136K
Votos: 66

Aquí está mi código de extracto.

// Generar longitud personalizada del extracto
function wpbx_excerpt_length($length) {
    return 300;
}
add_filter('excerpt_length', 'wpbx_excerpt_length');

¿Cómo permito HTML como <a> <b> <i> <br>

0
Todas las respuestas a la pregunta 3
23
144

GUÍA COMPLETA SOBRE EXTRACTOS

Recientemente he respondido algunas preguntas sobre extractos, así que voy a dar una explicación detallada cubriendo todo lo que pueda.

PREFACIO

Parece que hay un par de preguntas surgiendo de esta respuesta sobre dónde debería ir el código, y la respuesta es, realmente depende de ti y cómo lo veas conveniente. Hay un par de opciones donde puedes colocar el código (si no se indica explícitamente):

  • En el functions.php de tu tema o cualquier archivo usado como archivo de funciones. Solo recuerda que cuando hagas esto, si el tema no es tuyo, todos los cambios se perderán cuando actualices tu tema.

  • Una mejor manera sería usar el código en un tema hijo. Como arriba, en el functions.php o un archivo relacionado con funciones.

  • Usar el código en un plugin. Esta es la forma preferida ya que hace que el código esté disponible en todos los temas. Si cambias de tema, no tienes que preocuparte por reescribir el mismo código.

Espero que esto aclare un poco las cosas :-)

ETIQUETAS HTML/FORMATEO

the_excerpt() antes que nada no acepta ningún parámetro, así que no se le puede pasar nada. Es un hecho que the_excerpt() recorta el contenido a 55 palabras, y todas las etiquetas HTML son eliminadas antes de devolver el texto. the_excerpt() se encuentra en wp-includes/post-template.php. Para permitir ciertas o todas las etiquetas HTML en el extracto, se debe crear un nuevo extracto.

Primero, la función original debe ser eliminada, y luego la nueva función debe ser enganchada a get_the_excerpt. Por favor ten en cuenta, este nuevo extracto seguirá siendo invocable como the_excerpt() en los archivos de plantilla, no hay necesidad de cambiar eso. get_the_excerpt() se encuentra en wp-includes/post-template.php.

El extracto usa wp_trim_excerpt para devolver el texto recortado, así que necesitamos eliminar wp_trim_excerpt primero del filtro del extracto. wp_trim_excerpt() se encuentra en wp-includes/formatting.php, línea 2355. Así es cómo:

remove_filter('get_the_excerpt', 'wp_trim_excerpt');

Ahora puedes añadir tu nuevo extracto a get_the_excerpt

add_filter('get_the_excerpt', 'wpse_custom_wp_trim_excerpt');

Para permitir etiquetas HTML/formateo, necesitaremos especificar qué etiquetas necesitas permitir. Puedes usar la siguiente declaración strip_tags para lograrlo

$wpse_excerpt = strip_tags($wpse_excerpt, wpse_allowedtags());

El segundo argumento wpse_allowedtags() es una pequeña función que se usa para añadir las etiquetas que the_excerpt() permitirá. Para una lista completa de etiquetas HTML 5 válidas, ve y échale un vistazo aquí. Aquí está la función, añade cualquier etiqueta HTML que necesites permitir/mantener

function wpse_allowedtags() {
// Añade etiquetas personalizadas a esta cadena
    return '<script>,<style>,<br>,<em>,<i>,<ul>,<ol>,<li>,<a>,<p>,<img>,<video>,<audio>'; 
}

Si necesitas permitir todas las etiquetas HTML, es decir, no eliminar ninguna etiqueta, la función strips_tags() puede ser omitida/eliminada completamente.

Un punto a tener en cuenta, sin embargo, cuando se permiten etiquetas HTML, estas etiquetas se cuentan como palabras, así que tu conteo de palabras para extractos con etiquetas y sin etiquetas no será el mismo. Para corregir eso, necesitarás eliminar estas etiquetas del conteo real de palabras primero para que solo se cuenten las palabras.

He escrito un extracto que permitirá todas las etiquetas, contará solo palabras como palabras, y completará una oración después de la cantidad establecida de palabras (para que el texto no se recorte a mitad de oración) y añadirá un texto de leer más después de la última palabra.

Aquí está el código completo

function wpse_allowedtags()
{
  // Añade etiquetas personalizadas a esta cadena
  return '<script>,<style>,<br>,<em>,<i>,<ul>,<ol>,<li>,<a>,<p>,<img>,<video>,<audio>';
}

if (!function_exists('wpse_custom_wp_trim_excerpt')) :

  function wpse_custom_wp_trim_excerpt($wpse_excerpt)
  {
    $raw_excerpt = $wpse_excerpt;
    if ('' == $wpse_excerpt) {

      $wpse_excerpt = get_the_content('');
      $wpse_excerpt = strip_shortcodes($wpse_excerpt);
      $wpse_excerpt = apply_filters('the_content', $wpse_excerpt);
      $wpse_excerpt = str_replace(']]>', ']]&gt;', $wpse_excerpt);
      $wpse_excerpt = strip_tags($wpse_excerpt, wpse_allowedtags()); /*SI necesitas permitir solo ciertas etiquetas. Elimina si todas las etiquetas están permitidas */

      //Establece el conteo de palabras del extracto y solo corta después de que la oración esté completa.
      $excerpt_word_count = 75;
      $excerpt_length = apply_filters('excerpt_length', $excerpt_word_count);
      $tokens = array();
      $excerptOutput = '';
      $count = 0;

      // Divide la cadena en tokens; etiquetas HTML, o palabras, seguidas por cualquier espacio en blanco
      preg_match_all('/(<[^>]+>|[^<>\s]+)\s*/u', $wpse_excerpt, $tokens);

      foreach ($tokens[0] as $token) {

        if ($count >= $excerpt_length && preg_match('/[\,\;\?\.\!]\s*$/uS', $token)) {
          // Límite alcanzado, continúa hasta que , ; ? . o ! ocurran al final
          $excerptOutput .= trim($token);
          break;
        }

        // Añade palabras para completar la oración
        $count++;

        // Añade lo que queda del token
        $excerptOutput .= $token;
      }

      $wpse_excerpt = trim(force_balance_tags($excerptOutput));

      $excerpt_end = ' <a href="' . esc_url(get_permalink()) . '">' . '&nbsp;&raquo;&nbsp;' . sprintf(__('Leer más sobre: %s &nbsp;&raquo;', 'wpse'), get_the_title()) . '</a>';
      $excerpt_more = apply_filters('excerpt_more', ' ' . $excerpt_end);

      //$pos = strrpos($wpse_excerpt, '</');
      //if ($pos !== false)
      // Dentro de la última etiqueta HTML
      //$wpse_excerpt = substr_replace($wpse_excerpt, $excerpt_end, $pos, 0); /* Añade leer más junto a la última palabra */
      //else
      // Después del contenido
      $wpse_excerpt .= $excerpt_more; /*Añade leer más en un nuevo párrafo */

      return $wpse_excerpt;

    }
    return apply_filters('wpse_custom_wp_trim_excerpt', $wpse_excerpt, $raw_excerpt);
  }

endif;

remove_filter('get_the_excerpt', 'wp_trim_excerpt');
add_filter('get_the_excerpt', 'wpse_custom_wp_trim_excerpt');

Puedes simplemente eliminar las '//' de las funciones que necesites adicionalmente.

LONGITUDES PERSONALIZADAS DE EXTRACTOS

A veces necesitas mostrar extractos simples de diferentes longitudes y no es viable escribir un extracto para cada post/función/página. Aquí hay una pequeña y bonita función usando wp_trim_words

function wpse_custom_excerpts($limit) {
    return wp_trim_words(get_the_excerpt(), $limit, '<a href="'. esc_url( get_permalink() ) . '">' . '&nbsp;&hellip;' . __( 'Leer más &nbsp;&raquo;', 'wpse' ) . '</a>');
}

Lo que hace esta pequeña función es tomar get_the_excerpt, recortarlo al $limit establecido por el usuario, y devolver el texto con un enlace de leer más al final.

Puedes invocar este extracto así en tu plantilla

echo wpse_custom_excerpts($limit);

donde $limit será tu conteo de palabras, así que un extracto de 30 palabras sería

echo wpse_custom_excerpts(30);

Solo una cosa para recordar aquí, si estableces tu límite a más de 55 palabras, solo se devolverán 55 palabras ya que el extracto solo tiene 55 palabras de longitud. Si se necesitan extractos más largos, usa get_the_content en su lugar.

LONGITUD PERSONALIZADA DE EXTRACTO

Si solo necesitas alterar la longitud de the_excerpt(), puedes usar la siguiente función

function wpse_excerpt_length( $length ) {
    return 20;
}
add_filter( 'excerpt_length', 'wpse_excerpt_length', 999 );

Recuerda, necesitarás establecer una prioridad mayor que 10 para que tu función personalizada se ejecute después de la predeterminada.

AÑADIR ENLACE LEER MÁS

Todos los textos devueltos por el extracto tienen el odiado [...] al final que no es clickeable. Para añadir un texto de leer más en lugar de los puntos suspensivos, usa esta función

 function wpse_excerpt_more( $more ) {
    return ' <a class="read-more" href="'. get_permalink( get_the_ID() ) . '">' . __('Leer Más', 'your-text-domain') . '</a>';
}
add_filter( 'excerpt_more', 'wpse_excerpt_more' );

EDITAR

Extracto del primer párrafo

Quiero mantener esto completo, así que aquí está el extracto que recorta después del primer párrafo.

Aquí hay una función que mantiene las etiquetas HTML intactas, añade un enlace "Leer más" al final del extracto y recorta el extracto después del primer párrafo.

if ( ! function_exists( 'wpse0001_custom_wp_trim_excerpt' ) ) : 
    
    function wpse0001_custom_wp_trim_excerpt($wpse0001_excerpt) {
        global $post;
        $raw_excerpt = $wpse0001_excerpt;
        if ( '' == $wpse0001_excerpt ) {
    
            $wpse0001_excerpt = get_the_content('');
            $wpse0001_excerpt = strip_shortcodes( $wpse0001_excerpt );
            $wpse0001_excerpt = apply_filters('the_content', $wpse0001_excerpt);
            $wpse0001_excerpt = substr( $wpse0001_excerpt, 0, strpos( $wpse0001_excerpt, '</p>' ) + 4 );
            $wpse0001_excerpt = str_replace(']]>', ']]&gt;', $wpse0001_excerpt);
    
            $excerpt_end = ' <a href="'. esc_url( get_permalink() ) . '">' . '&nbsp;&raquo;&nbsp;' . sprintf(__( 'Leer más sobre: %s &nbsp;&raquo;', 'pietergoosen' ), get_the_title()) . '</a>'; 
            $excerpt_more = apply_filters('excerpt_more', ' ' . $excerpt_end); 
    
            //$pos = strrpos($wpse0001_excerpt, '</');
            //if ($pos !== false)
            // Dentro de la última etiqueta HTML
            //$wpse0001_excerpt = substr_replace($wpse0001_excerpt, $excerpt_end, $pos, 0);
            //else
            // Después del contenido
            $wpse0001_excerpt .= $excerpt_more;
    
            return $wpse0001_excerpt;
    
        }
        return apply_filters('wpse0001_custom_wp_trim_excerpt', $wpse0001_excerpt, $raw_excerpt);
    }
    
endif; 
    
remove_filter('get_the_excerpt', 'wp_trim_excerpt');
add_filter('get_the_excerpt', 'wpse0001_custom_wp_trim_excerpt');

EDITAR 29-10-2015

Para cualquiera que necesite una solución para no mostrar el enlace de leer más después del extracto cuando el extracto es más corto que la cantidad de palabras establecida, por favor ve la siguiente pregunta y respuesta

13 abr 2014 08:30:46
Comentarios

¿dónde exactamente coloco esta parte? function wpse_allowedtags() { // Agrega etiquetas personalizadas a esta cadena return '<script>,<style>,<br>,<em>,<i>,<ul>,<ol>,<li>,<a>,<p>,<img>,<video>,<audio>'; } estoy confundido

user32447 user32447
13 abr 2014 12:13:38

Todo este código va en functions.php. Puedes agregarlo justo encima de if ( ! function_exists( 'wpse_custom_wp_trim_excerpt' ) ) : en tu archivo functions.php

Pieter Goosen Pieter Goosen
13 abr 2014 12:16:16

@user32447 ver edición

Pieter Goosen Pieter Goosen
13 abr 2014 12:19:14

Lo sé, pero hay ciertas etiquetas que quiero permitir y no sé cómo lograrlo. Coloqué el código en mi functions.php, pero ¿qué debo cambiar para permitir ciertas etiquetas @pieter goosen

user32447 user32447
13 abr 2014 12:21:02

¿Debería borrar esta línea y reemplazarla? $wpse_excerpt = strip_tags($wpse_excerpt, wpse_allowedtags());

user32447 user32447
13 abr 2014 12:21:58

No importa, me faltó ver la parte superior del código

user32447 user32447
13 abr 2014 12:25:12

No, mantén $wpse_excerpt = strip_tags($wpse_excerpt, wpse_allowedtags());. Debes agregar tus etiquetas a estos return '<script>,<style>,<br>,<em>,<i>,<ul>,<ol>,<li>,<a>,<p>,<img>,<video>,<audio>'; También puedes eliminar todas estas etiquetas y solo agregar las tuyas

Pieter Goosen Pieter Goosen
13 abr 2014 12:25:27

si esto va al archivo functions.php, ¿no se sobrescribirá cuando llegue una actualización?

mcgrailm mcgrailm
24 jul 2014 04:51:56

@mcgrailm sí, así sería. Por eso es importante agregar esto al functions.php de tu tema hijo. Incluso puedes agregarlo como un plugin must-use

Pieter Goosen Pieter Goosen
24 jul 2014 06:55:16

¿Quizás también agregar ":" como un token?

timocouckuyt timocouckuyt
28 mar 2015 15:49:13

@PieterGoosen ¡Guau, esta es una gran explicación! Solo hay un detalle: la función va a agregar palabras hasta el siguiente . o ! (por ejemplo), pero ¿qué pasa si no hay más palabras después del último . o !? El enlace "Leer más" igual se mostrará... Sé que la función de extracto no se supone que muestre el contenido completo, pero eso puede ser difícil de controlar si un editor escribe un artículo pequeño. ¿Qué opinas de esta situación?

Pipo Pipo
12 jun 2015 18:34:15

@Pipo Tienes razón. Revisaré este problema después del fin de semana, voy a estar un poco ocupado. Te mantendré informado. Gracias por tu respuesta

Pieter Goosen Pieter Goosen
13 jun 2015 06:12:00

@PieterGoosen No hay problema, no hay prisa, solo estoy intentando aprender de tu código. Que tengas un buen domingo

Pipo Pipo
14 jun 2015 21:13:09

¿Esto asegura que no queden etiquetas abiertas? Lo pregunto por esta pregunta.

Nicolai Grossherr Nicolai Grossherr
30 jul 2015 14:47:32

Hay un problema con las etiquetas ul y li que conozco, pero en general, esto debería eliminarse de un extracto. @ialocin

Pieter Goosen Pieter Goosen
30 jul 2015 14:51:08

¡Genial! Entonces, si tengo, digamos, 100 palabras y hay una etiqueta de apertura sin una de cierre, será eliminada.

Nicolai Grossherr Nicolai Grossherr
30 jul 2015 14:53:32

@ialocin no, no lo hará. Puedes implementar algo como esto para eliminar etiquetas que quedan abiertas. Lo que quise decir es que, en realidad, se deberían eliminar etiquetas como ul y li del extracto. En una de las funciones anteriores puedes hacerlo.

Pieter Goosen Pieter Goosen
30 jul 2015 14:58:22

Lástima, entonces te malentendí, obviamente. Esto era más sobre, por ejemplo, la etiqueta <b>.

Nicolai Grossherr Nicolai Grossherr
30 jul 2015 15:05:16

Creo que esto necesita pruebas :-). Cuando construí esto, estaba más pensado para etiquetas "a", que en esa etapa era mi principal problema. Solo más tarde noté que las etiquetas "ul" y "li" se eliminaban a medias, por lo que te quedabas con la etiqueta de apertura pero no con la de cierre. Para ser honesto, este código tiene sus fallos :-)

Pieter Goosen Pieter Goosen
30 jul 2015 15:16:00

@PieterGoosen Solo mencionar que enganchar la función excerpt_more no funcionará a menos que le des una prioridad más baja, ya que template-tags.php se carga después del functions.php del tema actual.

Cu7l4ss Cu7l4ss
16 dic 2015 03:05:11

@PieterGoosen gracias por el post tan informativo - pregunta rápida: ¿sería posible modificar el extracto de esta manera solo para un tipo de entrada específico?

nickpish nickpish
8 sept 2017 01:52:04

¿Puedes simplemente escribir una solución rápida que pueda copiar y pegar en mi código? Es verano y no quiero leer un libro.

Daniel Muñoz Parsapoormoghadam Daniel Muñoz Parsapoormoghadam
9 jun 2018 17:54:59

Para los que se preguntan qué copiar, hay una sección "Aquí está el código completo" en la respuesta.

m4n0 m4n0
31 dic 2020 10:36:51
Mostrar los 18 comentarios restantes
0

Añade más etiquetas si lo necesitas en $allowed_tags = ...

function _20170529_excerpt($text) {
$raw_excerpt = $text;
if ( '' == $text ) {
    // Obtener el contenido del post
    $text = get_the_content('');

    // Eliminar todos los shortcodes del contenido
    $text = strip_shortcodes( $text );

    $text = apply_filters('the_content', $text);
    $text = str_replace(']]>', ']]&gt;', $text);

    $allowed_tags = '<a>,<b>,<br><i>'; 
    $text = strip_tags($text, $allowed_tags);

    $excerpt_word_count = 55; /*** MODIFICA ESTO. Cambia el número de palabras del extracto al entero que prefieras.***/
    $excerpt_length = apply_filters('excerpt_length', $excerpt_word_count); 

    $excerpt_end = '[...]'; /*** MODIFICA ESTO. Cambia el final del extracto por otra cosa.***/
    $excerpt_more = apply_filters('excerpt_more', ' ' . $excerpt_end);

    $words = preg_split("/[\n\r\t ]+/", $text, $excerpt_length + 1, PREG_SPLIT_NO_EMPTY);
    if ( count($words) > $excerpt_length ) {
        array_pop($words);
        $text = implode(' ', $words);
        $text = $text . $excerpt_more;
    } else {
        $text = implode(' ', $words);
    }
}
return apply_filters('wp_trim_excerpt', $text, $raw_excerpt);
}

De: http://bacsoftwareconsulting.com/blog/index.php/wordpress-cat/how-to-preserve-html-tags-in-wordpress-excerpt-without-a-plugin/

29 may 2017 11:21:49
1

Puedes añadir un editor de texto enriquecido para los extractos también, agrega el siguiente código en el archivo de plugin o en el functions.php de tu tema y podrás ver el editor HTML para extractos. Además, renderizará los extractos en formato HTML también. #saludos

Copié esto de algún lugar pero no recuerdo la fuente. Lo uso en todos mis proyectos y funciona.

Edición: Esto fue copiado de Agregar un editor de texto enriquecido al extracto respuesta del 2012 por fuxia

Editor de texto enriquecido para extractos

/**
  * Reemplaza el editor de extracto predeterminado con TinyMCE.
*/
add_action( 'add_meta_boxes', array ( 'T5_Richtext_Excerpt', 'switch_boxes' ) );
class T5_Richtext_Excerpt
{
    /**
     * Reemplaza las meta cajas.
     *
     * @return void
     */
    public static function switch_boxes()
    {
        if ( ! post_type_supports( $GLOBALS['post']->post_type, 'excerpt' ) )
        {
            return;
        }

        remove_meta_box(
            'postexcerpt', // ID
            '',            // Pantalla, vacío para soportar todos los tipos de post
            'normal'      // Contexto
        );

        add_meta_box(
            'postexcerpt2',     // Reutilizar solo 'postexcerpt' no funciona.
            __( 'Extracto' ),    // Título
            array ( __CLASS__, 'show' ), // Función de visualización
            null,              // Pantalla, usamos todas las pantallas con meta cajas.
            'normal',          // Contexto
            'core',            // Prioridad
        );
    }

    /**
     * Salida para la meta caja.
     *
     * @param  object $post
     * @return void
     */
    public static function show( $post )
    {
        ?>
        <label class="screen-reader-text" for="excerpt"><?php
        _e( 'Extracto' )
        ?></label>
        <?php
            // Usamos el nombre predeterminado, 'excerpt', así no tenemos que preocuparnos
            // por guardar, otros filtros, etc.
            wp_editor(
                self::unescape( $post->post_excerpt ),
                'excerpt',
                array (
                    'textarea_rows' => 15,
                    'media_buttons' => FALSE,
                    'teeny'         => TRUE,
                    'tinymce'       => TRUE
                )
            );
    }

    /**
     * El extracto usualmente está escapado. Esto rompe el editor HTML.
     *
     * @param  string $str
     * @return string
     */
    public static function unescape( $str )
    {
        return str_replace(
            array ( '&lt;', '&gt;', '&quot;', '&amp;', '&nbsp;', '&amp;nbsp;' ),
                array ( '<',    '>',    '"',      '&',     ' ', ' ' ),
                $str
        );
    }
}
7 abr 2019 03:18:36
Comentarios

Gracias, @peter-wooster por la edición.

Mayur Chauhan Mayur Chauhan
22 nov 2021 02:07:52