¿Es compatible Wordpress con un shortcode llamándose a sí mismo desde dentro de una llamada de shortcode?

2

He creado un marco de Wordpress súper loco que tiene un millón y un código corto, uno de ellos es un código corto de columnas que admite un parámetro de conteo que le permite definir una columna y se agregará la clase apropiada.

Mi código breve es el siguiente:

add_shortcode('column', 'column_shortcode');
function column_shortcode($atts, $content = '')
{
    extract(shortcode_atts(array(
       'count' => 12
    ), $atts));

    if (stripos($count, '_') === FALSE)
    {
        if ((int) $count > 12)
        {
            $count = 12;
        }
    }

    $html = '<div class="column-'.$count.' column">';
    $html .= do_shortcode($content);
    $html .= '</div>';

    return $html;
}

Parece que hay un problema, sin embargo, cuando el código corto de la columna se usa dentro de una columna, ¿se trata de un problema conocido o Wordpress no admite códigos cortos del mismo nombre que se anidan entre sí?

Lo que sucede esencialmente es que la columna interior se cierra prematuramente en el HTML generado y veo [/ column] envuelto en etiquetas de párrafos que se muestran en la parte frontal. Sin embargo, si creo otro código abreviado y lo llamo hijo, usando exactamente el mismo código que el anterior, solo el código del niño es solo [hijo] en lugar de [columna] todo funciona como se espera.

Aquí está el código del editor WYSIWYG en mi instalación de Wordpress. La Prueba A es el escenario ideal, no quiero tener que usar dos códigos cortos diferentes que hacen lo mismo. El Anexo B es lo que funciona simplemente duplicando el código abreviado.

Anexo A: no funciona

[column count="9"]

[column count="8_9"]

Welcome to the site.

Who's brave enough to fly into something we all keep calling a death sphere? Well, then good news! It's a suppository. A true inspiration for the children. Ah, computer dating. It's like pimping, but you rarely have to use the phrase "upside your head."

[/column]

[/column]

Anexo B: funciona

[column count="9"]

[child count="8_9"]

Welcome to the site.

Who's brave enough to fly into something we all keep calling a death sphere? Well, then good news! It's a suppository. A true inspiration for the children. Ah, computer dating. It's like pimping, but you rarely have to use the phrase "upside your head."

[/child]

[/column]
    
pregunta Dwayne Charrington 24.10.2012 - 07:59

3 respuestas

2

Este es un problema conocido. Si tiene un código abreviado dentro de otro que tiene el mismo nombre, el analizador de wordpress no podrá manejarlos correctamente. Esto también se menciona en la página de códice para API de código corto bajo limitaciones.

Desde la página enlazada However the parser will fail if a shortcode macro is used to enclose another macro of the same name

La solución que sugiero es agregar parámetros adicionales a la llamada de shortcode principal & en su función de código abreviado, llame de forma recursiva en función de si esos parámetros adicionales están presentes

EJEMPLO

[column count="9" child="8_9" 8_9_text="

Welcome to the site.

Who's brave enough to fly into something we all keep calling a death sphere? Well, then good news! It's a suppository. A true inspiration for the children. Ah, computer dating. It's like pimping, but you rarely have to use the phrase "upside your head."
" /]

Luego en el código

function shortcode_handler($atts, $content, $tag) {
    if(isset($atts['child']))
        $output = shortcode_handler(array('count'=>$atts['child']), $atts[$atts['child'].'_text'])

    // Do something else with the output

}

Sé que no se ve bien, pero quizás puedas resolver algo en el contexto de tu aplicación.

    
respondido por el Mridul Aggarwal 24.10.2012 - 12:45
2

Escribí una pequeña función que habilitará códigos cortos dentro de ellos mismos. Debería funcionar perfectamente para su problema. Ha sido muy útil para mí.

Abra el archivo 'wp-includes / shortcodes.php' y cambie la función do_shortcode () (en la línea 201) a la siguiente

function do_shortcode($content) {
    global $shortcode_tags;

    if (empty($shortcode_tags) || !is_array($shortcode_tags))
        return $content;

    $content = enable_recursive_shortcodes($content);

    $pattern = get_shortcode_regex();
    return preg_replace_callback( "/$pattern/s", 'do_shortcode_tag', $content );
}

Todo lo que se modificó es la adición de * $ content = enable_recursive_shortcodes ($ content); *

Esa función recorre el $ contenido que se le pasa y agrega un sufijo a los nombres de código abreviado de los códigos cortos dentro de ellos. Entonces solo se procesan los códigos cortos externos, y cuando se procesa su contenido, el sufijo se elimina permitiendo que se procesen. No hay límite de cuántos niveles de profundidad puede alcanzar. (ejemplo: [cuadro] [cuadro] [cuadro] [cuadro] Contenido [/ cuadro] [/ cuadro] [/ cuadro] [/ cuadro])

Agregue la siguiente función sobre la función do_shortcode ()

/**
 * Add shortcode suffix enabling recursive shortchodes.
 *
 * This function goes inside the set of $recursive_tags and adds a suffix to
 * the shortcode name so it will allow a shortcode to call itself in its content
 *
 * @since 2.5
 * @return string Content with recursive shortcodes modified out.
 */
function enable_recursive_shortcodes($content) {

    $recursive_tags = array( 'column', 'div', 'span', 'table' ); // define recursive shortcodes, these must have closing tags 
    $suffix = '__recursive'; // suffix is added to the tag of recursive shortcodes

    $content = str_replace( $suffix, '', $content ); // remove old suffix on shortcodes to start process over

    foreach( $recursive_tags as $recursive_tag ) {

        $open_tag = '[' . $recursive_tag . ' ';
        $close_tag = '[/'. $recursive_tag . ']';

        $open_tags = 0;

        $open_pos = stripos( $content, $open_tag ); // find first opening tag

        $offset = $open_pos + strlen( $open_tag ); // set offset for first closing tag

        while( $open_pos !== false ) {

            $close_pos = stripos( $content, $close_tag, $offset ); // find first closing tag

            if(++$open_tags > 1) { // if we are inside an open tag

                // modify open tag from original shortcode name
                $content = substr( $content, 0, $open_pos ) . 
                            '[' .$recursive_tag . $suffix . ' ' . 
                              substr( $content, $offset ); 
                // modify closing tag from original shortcode name
                $content = substr( $content, 0, $close_pos + strlen($suffix) ) . 
                            '[/'.$recursive_tag.'__recursive]' . 
                            substr( $content, $close_pos + strlen( $close_tag ) + strlen($suffix) ); 
                $open_tags--;
            }

            $open_pos = stripos( $content, $open_tag, $offset ); // find next opening tag

            if( $close_pos < $open_pos ) $open_tags--; // if closing tag comes before next opening tag, lower open tag count

            $offset = $open_pos + strlen($open_tag); // set new offset for next open tag search

        }

    }

    return $content;

}

Asegúrese de actualizar la variable $ recursive_tags según sea necesario. Solo esas etiquetas serán revisadas para niños del mismo nombre. Esas etiquetas deben tener etiquetas de cierre [columna] [/ columna] porque [columna /] no funcionará. También deben tener un espacio después del nombre del shortcode en la etiqueta de apertura y no espacios en la etiqueta de cierre debido a cómo la función busca a través de las etiquetas. Si alguien actualiza el código para permitir que funcionen los códigos cortos de estilo de [columna] o [columna /], por favor, comparta.

    
respondido por el Trey Welstad 26.01.2013 - 04:18
0

La solución más simple, aunque quizás no sea la mejor, que he encontrado para esto es agregar la etiqueta varias veces con ligeras variaciones. Por ejemplo, en el caso del interrogador, podría ser:

function render_column( $atts, $content ) {
    // etc.

    return apply_filters( 'the_content', $content );
}

add_shortcode( 'column', 'render_column' );
add_shortcode( 'column-level-2', 'render_column' );
add_shortcode( 'column-level-3', 'render_column' );

Esto requiere un poco de documentación adicional y es posible que algunos usuarios no lo entiendan de inmediato, pero creo que es un poco más intuitivo que pedir a los usuarios que incluyan el contenido del shortcode en un atributo. Y, por supuesto, esa solución introduce el problema separado de manejar las comillas en un atributo de código corto.

    
respondido por el John Watkins 06.12.2017 - 23:03

Lea otras preguntas en las etiquetas