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.

I'm using Black Studio TinyMCE Widget as a rich text editor widget. In a sidebar I inserted the TinyMCE widget with a [testimonial] shortcode and some content after it.

For example:

[testimonial]

Read more client testimonials (as a link)

When I switch to the HTML tab of that widget I've got the following:

<p>[testimonial]</p>
<p><a title="Testimonials" href="http://mm.dev/testimonials/">Read more client testimonials</a></p>

The shorcode simply displaying a random Testimonial CPT post:

add_shortcode("testimonial", "dlma_testimonial_shortcode");
function dlma_testimonial_shortcode($atts, $content = null){
    $args = array(
        'post_type' => 'testimonial',
        'post_status' => 'publish',
        'posts_per_page' => '1',
        'orderby' => 'rand'
    );
    $testimonial = new WP_Query($args);

    if($testimonial){
        return apply_filters('the_content', $testimonial->posts[0]->post_content);
    }
    return "";
}

However, when I view a page, stray <p> elements are inserted:
Edited thanks to Tom J Nowell

<div class="textwidget">
  <p>
    <blockquote>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis vestibulum velit convallis sem pulvinar vitae lobortis metus varius.” <em>Person name, Person job</em></p>
    </blockquote>
  </p>
  <p>
    <a href="http://mysite.com/testimonials/" title="Testimonials">Read more client testimonials</a>
  </p>
</div>

The [testimonial] shortcode got expanded correctly, however, as it was originally wrapped into <p> element in the widget it still appears to be wrapped in it. I have tried deleting the <p> element from the widget HTML tab view, however, whenever the Save button is clicked the <p> element is inserted again.

I've tried to remove unwanted <p> element that wraps the shortcode with the the_content filter as following:

remove_filter( 'the_content', 'wpautop' );
add_filter( 'the_content', 'wpautop' , 12);

That didn't work. I'm guessing I've got the flow wrong of processing the content of a widget with a shortcode in it. I'm very confused now. How can I remove unwanted <p> elements that wrap shortcodes?

I would hugely appreciate any help!

Many thanks.

share|improve this question
1  
if you call apply_filters('the_content' you don't need to use do_shortcode since its one of the the_content filters. –  Bainternet Apr 15 '12 at 15:50
    
Thanks Bainternet, I find the_content filter a bit confusing...as you can see. –  dashaluna Apr 15 '12 at 16:45

2 Answers 2

There actually are several ways to handle the Wordpress editor wrapping shortcodes in <p> tags.

This code shows probably the simplest way to do it...just a simple and short function you need to drop into your functions.php file. Once you do, no more tags around your shortcodes that are on their own line!

function wpex_clean_shortcodes($content){   
$array = array (
    '<p>[' => '[', 
    ']</p>' => ']', 
    ']<br />' => ']'
);
$content = strtr($content, $array);
return $content;
}
add_filter('the_content', 'wpex_clean_shortcodes');

Source: http://www.wpexplorer.com/snippet/clean-wordpress-shortcodes

Hope that helps someone!

share|improve this answer

A blockquote is a block element, and shouldn't be put inside a <p> tag, what you're seeing is your browsers DOM trying to compensate for the invalid html markup. If you look at the raw source code itself generated, you will not find those stray paragraph tags

Remove your <p> wrapping tags, and make sure any content that needs wrapping in a <p> tag is done inside the shortcode.

http://stackoverflow.com/questions/3428828/p-tag-is-a-block-level-element-in-xhtml

The general rule is that a <p> element is a block element, but it should never contain block elements, only inline elements.

e.g.:

  • A p element can contain:
    • span
    • b
    • strong
    • etc
  • A p element cannot contain:
    • div
    • blockquote
    • ul
    • ol
    • h1
    • etc
share|improve this answer
    
Thanks for the answer. I've checked raw HTML page code and you're right, there isn't stray <p> elements..I will update the code in the question. However, I did try to delete wrapping <p> elements around the shortcode in the widget, however, after saving the widget content the <p> element is inserted again, so I do still need to somehow filter them out.. any ideas? –  dashaluna Apr 15 '12 at 15:39
    
It's the auto p stuff, you should reformat your content accordingly so that the shortcode doesnt not have a blank line immediatley after it –  Tom J Nowell Apr 15 '12 at 16:51
    
Tom, I've tried reformatting in the widget, it either wraps shortcode and link in a separate <p> element, or into a single one if there is no space between shortcode and link. But it still wraps the content... I don't think the formatting in the widget would help. I think I need to do it with filters, but can't figure out to do it correctly :( –  dashaluna Apr 15 '12 at 17:15
    
Well to begin with there is no need at all for there to be any <p> tags in the post content at all, Wordpress automatically puts those in, so you may be having the same identical issue with the second paragraph because WordPress generates <p><p>stuff</p></p> which is also invalid html and would probably generate this in the dom: <p></p><p>stuff<p><p></p> –  Tom J Nowell Apr 15 '12 at 18:25
    
Try this all on one line: "[testimonial]Read more client testimonials (as a link)" –  Tom J Nowell Apr 15 '12 at 18:26

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.