2

i'm trying to wrap each shortcode in div with special data attributes, but when i'm using nested shortcode they don't wrapped, where i'm wrong? thanks

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 );

this code works fine with shortcodes like this:

[shortcode][/shortcode]

and return:

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

but when i used nested shortcode my code wrap only first shortcode, inner shortcode not wraped:

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

but must return this:

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

where i'm wrong? thanks!

1

You need to recurse into the shortcode content ($m[5] as returned by get_shortcode_regex()), the standard way being to use 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>';
    }
|improve this answer|||||
  • something went wrong with your code, my dom tree now looks like this: take.ms/tHyMo – 20yco Feb 1 '16 at 10:23
  • Yes you're right, the reassembly was wrong - will update answer... – bonger Feb 1 '16 at 10:43
  • looks awesome! huge thanks to you! but now a have another problem, im trying to display shortcode in data-shortcode attr like this: take.ms/IaYod i'm trying to use '$scCont' on "data-shortcode", but this doesn't work for me – 20yco Feb 1 '16 at 10:54
  • My guess is you're running into WP parsing issues - you could try encoding the data into eg base64 ($data_sc = base64_encode( $scCont ); and then decoding it on the javascript side via btoa()... – bonger Feb 1 '16 at 11:10
  • Any chance I could get a full working code example for this? I'm having trouble figuring out how to include it in my theme. – JacobTheDev Aug 23 '18 at 14:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.