I'd already come across a case where Wordpress added <p> tags. However now I'm dealing with the opposite situation. When I add [] shortcodes inside <p> tags WordPress automatically removes <p> tags.

<p>[anyshortcode]Hello World[/anyshortcode]</p>


Hello World

Adding dir="ltr" to <p> tags seems to fix the issue, maybe there is a way to add it programatically to all <p> tags?

Any ideas on how to fix this?

  • 2
    You can use a Advaced tinymce plugin that is more powerfull and make also p tags worked.
    – Foxsk8
    Commented Mar 14, 2014 at 21:21
  • use 'wpautop'. Ex: '<?php echo wpautop('[anyshortcode]'); ?>' Commented Mar 23, 2016 at 6:17

5 Answers 5


This is pretty much what Foxsk8 mentioned in a comment, so credit should go to him, but these additional instructions will be useful. The WordPress plugin called TinyMCE Advanced will solve your problem.

This plugin comes with an option inside Settings > TinyMCE Advanced that will fix your disappearing <p> tags. Mark the checkbox labeled Stop removing the <p> and <br /> tags when saving and show them in the Text editor and your <p> tags will be preserved.


TinyMCE is programmed to make editing easy (which for us HTML savvy is often not the case). By default is should not accept <p> tagging around [BLOCKS]. That is because "[]" are used for shortcode not only in WP but a ton of PHP based CMSs. The shortcodes should have the appropriate content wrapper.

Meaning the solution is to add the <p> tags in your shortcode code so that your content is wrapped the way you want.


As an additional to Foxsk8 and E. Serrano. If post contains <p> around shortcodes, WP will still remove it. It does it in shortcode_unautop filter that is added in '\wp-includes\default-filters.php'. It ensures that shortcodes are not wrapped in <p>...</p>.

So, we need to remove them:

remove_filter( 'the_content', 'shortcode_unautop' );

You can add this below code in your function.php file

function content_formatter($content){

    $new_content = '';
    $pattern_full = '{(\[raw\].*?\[/raw\])}is';
    $pattern_contents = '{\[raw\](.*?)\[/raw\]}is';
    $pieces = preg_split($pattern_full, $content, -1, PREG_SPLIT_DELIM_CAPTURE);

    foreach ($pieces as $piece) {
            if (preg_match($pattern_contents, $piece, $matches)) {
                    $new_content .= $matches[1];
            } else {
                    $new_content .= wptexturize(wpautop($piece));

    $array = array(
            '<p>[' => '[',
            ']</p>' => ']',
            ']<br />' => ']'

    $new_content = strtr($new_content, $array);

    return $new_content;


Now call this function whereever required like;

<?php echo content_formatter( get_field('field_name') ); ?>
  • A little bit of would be good instead of just posting code.
    – bravokeyl
    Commented May 23, 2016 at 7:06

Append this to your functions.php file within your theme's folder.

remove_filter( 'the_content', 'wpautop' );
  • See this also in other places. Does not work for me.
    – Garavani
    Commented Oct 18, 2023 at 15:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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