web-dev-qa-db-fra.com

Enveloppez chaque shortcode dans un tableau pour div

j'essaie d'envelopper chaque shortcode dans div avec des attributs de données spéciaux, mais lorsque j'utilise un shortcode imbriqué, ils ne sont pas encapsulés. Merci

public function wrapShortcode( $content )
{
    preg_match_all( '/' . get_shortcode_regex() . '/', trim( $content ), $found , PREG_SET_ORDER | PREG_OFFSET_CAPTURE );

    if ( ! empty( $found  ) ) {
        for ( $i = count( $found  ) - 1; $i >= 0; $i-- ) {
            $id = md5( time() . '-' . $this->tag_index ++ );
            $match = $found[ $i ];

            $scCont = substr( $content, $match[0][1], strlen( $match[0][0] ) );
            $shortcode = array(
                'tag'   => $match[2][0]
            );

            $modifiedShortcode = '<div class="shortcode" data-name="'.$shortcode['tag'].'">'.$scCont.'</div>';
            $content = substr( $content, 0, $match[0][1] ) . $modifiedShortcode . substr( $content, $match[0][1] + strlen( $match[0][0] ) );
        }
    }

    remove_action( 'the_content', array( $this, 'wrapShortcode' ), 1 );

    // Stray spaces can create lost paragraph tags.
    $content = preg_replace( '/(\/\w+>)\s+(<\/\w+)/', '$1$2', $content );
    return apply_filters( 'bq_wrapShortcode', $content );
}
add_filter( 'the_content', array( $this, 'wrapShortcode' ), -9999999 );

ce code fonctionne bien avec des codes courts comme ceci:

[shortcode][/shortcode]

et retour:

<div class="shortcode" data-name="shortcode">[shortcode][/shortcode]</div>

mais quand j'ai utilisé un shortcode imbriqué, mon code enveloppe uniquement le premier shortcode, shortcode interne non enveloppé:

<div class="shortcode" data-name="shortcode">[shortcode][inner_shortcode][/inner_shortcode][/shortcode]</div>

mais doit retourner ceci:

<div class="shortcode" data-name="shortcode">
     [shortcode]
     <div class="shortcode" data-name="inner_shortcode">
        [inner_shortcode][/inner_shortcode]                 
     </div>
     [/shortcode]
</div>

où je me trompe? Merci!

2
20yco

Vous devez entrer dans le contenu du code abrégé ($m[5] comme renvoyé par get_shortcode_regex()), la méthode standard étant d'utiliser preg_replace_callback():

    public function wrapShortcode( $content )
    {
        $content = preg_replace_callback( '/' . get_shortcode_regex() . '/s', array( $this, 'wrapShortcodeCallback' ), $content );

        remove_filter( 'the_content', array( $this, 'wrapShortcode' ), -9999999 );

        // Stray spaces can create lost paragraph tags.
        $content = preg_replace( '/(\/\w+>)\s+(<\/\w+)/', '$1$2', $content );
        return apply_filters( 'bq_wrapShortcode', $content );
    }
    public function wrapShortcodeCallback( $m )
    {
        $id = md5( time() . '-' . $this->tag_index ++ );
        if ( $m[5] !== '' ) {
            // Recurse into content.
            $m[5] = preg_replace_callback( '/' . get_shortcode_regex() . '/s', array( $this, 'wrapShortcodeCallback' ), $m[5] );
            $scCont = '[' . $m[1] . $m[2] . $m[3] . ']' . $m[5] . '[/' . $m[2] . ']' . $m[6];
        } else {
            $scCont = '[' . $m[1] . $m[2] . $m[3] . $m[4] . ']' . $m[6];
        }
        return '<div class="shortcode" data-name="'.$m[2].'">'.$scCont.'</div>';
    }
1
bonger