Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

After trouble parsing wrapping and non-wrapping shortcodes on the same page, I came across this trac ticket from 3 years ago: http://core.trac.wordpress.org/ticket/9264

The trouble is WP cannot properly parse

[myshortcode att="bla"] and 
[myshortcode]Enclosed content[/myshortcode] 

on the same page. The above gives you one shortcode with $att "bla" and $content "and [myshortcode]Enclosed content."

Adding a closing [/myshortcode] tag does not help:

[myshortcode att="bla"][/myshortcode] and
[myshortcode]Enclosed content[/myshortcode] 

Wordpress fails to parse it, and you end up with this a shortcode with $att "bla" and $content "[/myshortcode] and [myshortcode]Enclosed content."

As the ticket author points out (6 months ago),

With both [test/][test]content[/test] and [test][/test][test]content[/test] broken it seems impossible to enter a shortcode with null content before another instance of the same shortcode tag.

The diff in the trac ticket doesn't seem to work*, so I'm wondering if anyone has dealt with this or can suggest a fix in wp-includes/shortcodes.php.


*Perhaps related to the comment just before the changed line in wp-includes/shortcodes.php:

// WARNING! Do not change this regex without changing do_shortcode_tag() and strip_shortcodes()
share|improve this question

2 Answers 2

As far as I know, you need to leave a single space between multiple shortcodes.

I believe you can do this without too much trouble

[myshortcode attr="test1" content="test1" ...etc]
[myshortcode attr="test2" content="test2" ...etc]
[myshortcode attr="test3" content="test3" ...etc]

This SHOULD also work:

[myshortcode]Enclosed content[/myshortcode] [myshortcode]Enclosed content[/myshortcode] [myshortcode]Enclosed content[/myshortcode] [myshortcode]Enclosed content[/myshortcode] [myshortcode]Enclosed content[/myshortcode]

Also:

http://codex.wordpress.org/Shortcode_API

The parser does not handle mixing of enclosing and non-enclosing forms of the same shortcode as you would want it to. For example, if you have:

[myshortcode example='non-enclosing' /] non-enclosed content [myshortcode] enclosed content [/myshortcode]

Instead of being treated as two shortcodes separated by the text " non-enclosed content ", the parser treats this as a single shortcode enclosing " non-enclosed content [myshortcode] enclosed content".

So, this appears to not be a bug. This appears to be documented behavior.

Self closing shortcodes do work well together.


Also I may not be understanding the problem, but I tried this:

[svg src="test" width="300" height="300" style="display:block; margin:auto;" type="embed"]1111[/svg] [svg src="test" width="300" height="300" style="display:block; margin:auto;" type="embed"]1111[/svg] [svg src="test" width="300" height="300" style="display:block; margin:auto;" type="embed"]1111[/svg] [svg src="test" width="300" height="300" style="display:block; margin:auto;" type="embed"]1111[/svg]

That worked perfectly.

The code ended up looking like this:

function process_shortcode( $atts , $input ) { 
    $valid_attributes = array( 'src' , 'style' , 'type' , 'width' , 'height' );

    $content = NULL;

    foreach( $atts as $attribute => $value ) { 
        if( ! in_array( $attribute , $valid_attributes ) ) { 
            $content .= "\n" . '<!-- Invalid attribute ignored: ' . $attribute . ' -->' . "\n";
        }   
    }   

    switch( $atts[ 'type' ] ) { 
        case 'iframe':
            $content .= '<iframe src="' . $atts[ 'src' ] . '" width="' . $atts[ 'width' ] . '" height="' . $atts[ 'height' ] . '" style="' . $atts[ 'style' ] . '">';
            $content .= '</iframe>';
        break;
        case 'embed':
        default:
            $content .= '<div>';
            $content .= $input;
            $content .= '<embed src="' . $atts[ 'src' ] . '" width="' . $atts[ 'width' ] . '" height="' . $atts[ 'height' ] . '" ';
            $content .= 'type="image/svg+xml" pluginspage="http://www.adobe.com/svg/viewer/install/" style="' . $atts[ 'style' ] . '" /> ';
            $content .= '</div>';
        break;
    }

    return $content;
}
share|improve this answer
1  
My shortcodes aren't used next to each other—the issue is just multiple of the same shortcodes anywhere in the same post, when some wrap content do not. –  supertrue Nov 8 '11 at 0:11
    
So, this appears to not be a bug. This appears to be documented behavior. —it's documented, but that doesn't make it not a bug :) The workaround I'm using at the moment adds my shortcode under two aliases. I use one for instances that are enclosing, and the other for non-enclosing. It's not ideal but seems to work. –  supertrue Nov 9 '11 at 16:37
    
I've been there before, I too have to do a few things like that. But glad you got it figured out. I was unable to really reproduce the issue as I posted above. Best of luck! –  Sterling Hamilton Nov 9 '11 at 17:13
    
To reproduce the problem you have to use a non-enclosing (or empty) instance of a shortcode followed by an enclosing instance of the same shortcode. For example: [myshortcode att="bla"] [myshortcode]Enclosed text.[/myshortcode] or [myshortcode att="bla"][/myshortcode] [myshortcode]Enclosed text.[/myshortcode] –  supertrue Nov 10 '11 at 17:15
    
Is the attribute part needed for the [myshortcode att="bla"][/myshortcode] [myshortcode]Enclosed text.[/myshortcode] example? –  Sterling Hamilton Nov 10 '11 at 18:43
up vote 1 down vote accepted

According to a new post by mdawaffe on the trac ticket referenced in this question:

[test id="1"/] first self closed, now [test id="2"]with content[/test]
[foo attr/]bar[foo attr/]bar[/foo]
[test/]
[test]foobar[/test]
[test id="1"][/test]

All these cases now work. Apart from unit tests, this ticket can be closed.

I am assuming this means it will not be an issue in 3.3.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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