• Resolved the_enn

    (@the_enn)


    So I’ve read several articles and posts on how to prevent WP from adding <p> in front of <img> tags. Yet, I’m unable to return shortcode content without the p tag being inserted.

    My shortcode function looks like this:

    function displayAllianceNews($atts, $content = null) {
    
      $thecontent.='<div>'.$content.'</div>';
    
      // Get rid of WP <p></p> tags before <img>
      $content_antip = remove_ptags_images($thecontent);
       return $content_antip;
    }

    The input $content variable doesn’t have any <p> tags to start. It looks like:

    <h2>News</h2><img src="/wp-content/uploads/2015/04/4.1.5.3-NCCRA-CBL-Cover-e1429193101216.jpg" class="wrapleftOutline" alt="photo">

    Here’s the filter function (just for the open p tag for testing):

    function remove_ptags_images( $string )
    {
        $patternOpen = array(
            '#<p>\s*<img>#'
        );
    
        return preg_replace($patternOpen, '<img>', $string);
    }

    If I echo $content_antip before the return statement, the content appears correctly with no p’s. However, WP seems to be filtering the content after the return statement and adding p’s around the img tag. I added these to my functions.php as well, but to no avail:

    remove_filter ('acf_the_content', 'wpautop');
    remove_filter( 'the_content', 'wpautop' );

    Any idea what I’m doing wrong?

Viewing 10 replies - 1 through 10 (of 10 total)
  • Moderator bcworkz

    (@bcworkz)

    You need to remove the ‘wpautop’ filter callback, but doing so when your theme is loaded is probably too early. Hook ‘init’ with a late (large) priority number and remove the filter from within the ‘init’ callback.

    This will remove the wpautop from applying to any content, not just shortcodes. Most people who remove wpautop() are fine with this.

    Thread Starter the_enn

    (@the_enn)

    Thanks, I tried that and am getting the same issue.

    I put this in my functions.php:

    add_action('init','remove_wpautop',201);
    
    function remove_wpautop() {
    	remove_filter ('acf_the_content', 'wpautop');
    	remove_filter( 'the_content', 'wpautop' );
    
    }

    Anything else I should try? Or, is there any WP utility or plugin that shows you how to track when something like wpautop gets called?

    Thread Starter the_enn

    (@the_enn)

    A-ha!

    I tried deactivating plugins one by one and sure enough, I found the culprit, the WordPress-D3 plugin. If I de-activate it, the wpautop formatting goes away.

    Now the issue is how keep the plugin active, but remove wpautop from it. I posted a support message in that plugin’s forum on how to do that, but if any ideas, all ears!

    Moderator bcworkz

    (@bcworkz)

    You don’t want to hack the plugin code because it’ll revert during an update. You can remove the wpautop filter added by this plugin by matching the priority they used:
    remove_filter( 'the_content', 'wpautop', 90 );
    Add this as a third line just in case the original filter needs to be removed.

    Thread Starter the_enn

    (@the_enn)

    Ok, so I got it to work–THANK YOU–and am a little confused because of the order of precedence when WP executes certain action hooks.

    This did not work(functions.php):

    add_action('init','remove_wpautop',90);
    
    function remove_wpautop() {
    	remove_filter ('acf_the_content', 'wpautop');
    	remove_filter( 'the_content', 'wpautop' );
    
    }

    But this did (I removed the init hook and function from above):

    remove_filter( 'the_content', 'wpautop', 90);

    I had thought that the ‘init’ hook was fired after the plugins were loaded. Is this not accurate?

    The WP-D3 plugin was the problem point, but the add_filter from the plugin is apparently executing after my ‘init’ hook from above. If my ‘init’ hook has the priority of 90, shouldn’t this run after the plugin? Obviously it isn’t, but I’m trying to wrap my head around why…

    Moderator bcworkz

    (@bcworkz)

    You are correct about execution order, it’s just that the first code that didn’t work was done incorrectly. No matter, the working version is fine. I suggested the ‘init’ hook when I wasn’t sure when wpautop() was added. Since you discovered where it was being added, it makes removing it again much easier.

    Plugins always load before theme, so the filter is already in place, ready for removal when your theme loads. However, if the plugin adds a filter from the ‘init’ hook or similar, you need to do the same, but later to counteract this.

    Thread Starter the_enn

    (@the_enn)

    Thanks for explaining, bcworkz. So it sounds like if both the plugin and the theme are using ‘init’ as the hook to include a filter, they can still run in a different order based on the priority level.

    Looking at the plugin, the add_filter is in the main wp-d3.php file, and I’m not seeing it run based on an ‘init’ hook. It’s not inside a function, so I’m not sure what hook is driving it(if any?). So I’m still a bit confused in that respect, but I appreciate your help getting me in the right direction!

    Moderator bcworkz

    (@bcworkz)

    Right, that means the hook is added when the plugin loads, which is actually rather early. If you had another plugin trying to remove this hook, you cannot know what the load order is so you would then need a delay mechanism like waiting for ‘init’ to fire.

    Since you want to remove the hook from a theme, the code will run later no matter what, so there is no need for hooking ‘init’ to delay things, executing on load will work fine. The key is knowing what priority was used (90) in the first place. You cannot remove a hook unless the priorities match. I mean ‘the_content’ priority, not ‘init’. ‘init’ is not a factor, but if it were, the idea there would be to use a later priority, not match. The difference is the hook being removed vs. the delay tactic to do the removal.

    Thread Starter the_enn

    (@the_enn)

    I had to read that several times, but it has finally sunk in. ๐Ÿ™‚

    Thanks a lot for explaining this – it’s a big help for this issue, not to mention going forward.

    So when removing a hook that was already added in a plugin, it can be done in one of two ways:

    Theme:
    No init hook necessary because the theme is loaded after the plugins. However, the priority of the hook must match that of the hook from the plugin you are overriding.

    Plugin:
    Need to use the init hook as a delay mechanism to make sure it runs after the plugins are loaded since you have no idea what order the plugins are being loaded.

    Moderator bcworkz

    (@bcworkz)

    You got it! I wish I could have explained it more clearly. It’s hard to explain without writing a dissertation. But once someone truly grasps the concept, they see it’s not so complicated. Hooks are important to understand well because so much of hacking WP is based on hooks.

Viewing 10 replies - 1 through 10 (of 10 total)

The topic ‘Can't stop p tag insertion with shortcode’ is closed to new replies.