1

I notice that theres invalid markup in my shortcode. Its ok if I disable wpautop tho

function shortcode_banner($attrs, $content = '') {
    echo ' --- ' . $content . ' --- ';
    $html = '<section id="banner"><div class="wrap">' . do_shortcode($content) . '</div></section>';
    die($html);
}

When autop is enabled I get (notice the closing </p> at the start?)

--- </p>
<h1>The title</h1>
xxx ... xxx ...
--- 
<section id="banner"><div class="wrap"></p>
<h1>The title</h1>
xxx ... xxx ...
</div></section>

When disabled I get

 --- 
<h1>The header</h1>
xxx ... xxx ...
 --- 
<section id="banner"><div class="wrap">
<h1>The header</h1>
xxx ... xxx ...    
</div></section>

UPDATE: I notice this happens only when I have a tag (e.g. <h1>) after my shortcode. Like:

[banner]
<h1>Test</h1>

If I have

[banner]
xxx ...

it's ok, except Wordpress adds a <br />

1

Try this:

// replaces [banner ...] .. [/banner] with <!--banner ID--> before the_content filters run
add_filter('the_content', 'protect_my_shortcode', -100);
function protect_my_shortcode($content){
  return preg_replace_callback('/\[(banner)\b(.*?)(?:(\/))?\](.+?)\[\/\1\]/s', 'protect_my_shortcode_callback', $content);
}

function protect_my_shortcode_callback($matches){
  global $__banners;
  $id = '<!--banner '.count($__banners).'-->';

  $__banners[$id] = do_shortcode($matches[0]);
  // or '['.$matches[1].' '.$matches[2].']'.$matches[4].'[/'.$matches[1].']'
  // if you need to run any filters on the shortcode content ($matches[4])

  return $id;
}

// replaces <!--banner ID--> with the processed shortcode after all the filters run
add_filter('the_content', 'unprotect_my_shortcode', 100);
function unprotect_my_shortcode($content){
  global $__banners;
  return str_replace(array_keys($__banners), array_values($__banners), $content);
}
| improve this answer | |
  • An improvement, but now a <p> is wrapping my banner <p><section id="banner"></section></p>. Whats wrong with i.imgur.com/kEthX.png (whats in my TinyMCE) – JM at Work Jun 30 '11 at 9:47
  • try to replace above '<!--banner '.count($__banners).'-->'; with '<div class="banner-'.count($__banners).'"></div>'; WP shouldn't wrap DIVs within <p>... – onetrickpony Jun 30 '11 at 11:59
0

I don't know what causes this issue, but you can use the force_balance_tags() function to clean up the markup after the fact.

Note that there are some caveats to using force_balance_tags() in practice.

| improve this answer | |

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.