I have made my own theme with shortcodes to WordPress.
In my filters I have:
remove_filter('the_content', 'wpautop');
add_filter('the_content', 'wpautop', 99);
add_filter('the_content', 'shortcode_unautop', 100);
This should remove paragraph tags around and in my shortcodes.
My shortcode output (partial of the entire code):
$output .= '
<div ' . implode(' ', $html_attributes) . '>
<a href="' . get_permalink() . '">
<div ' . implode(' ', $html_attributes_inner) . '>
' . $logo . '
<div class="button hidden-xs hidden-sm">Læs case</div>
<div class="content">
<div class="row">
<div class="col-md-8">
<h4 class="title">' . get_the_title() . '</h4>
<div class="spacer small"></div>
<div class="excerpt">' . get_post()->post_excerpt . '</div>
</div>
</div>
</div>
</div>
</a>
</div>
';
// Script newlines whitespace, tabs etc.
return str_replace(["\r", "\n", "\t"], '', '<div class="row cases">' . $output . '</div>');
This produces:
<div class="row cases">
<div class="col-xs-12"><a href="">
<div class="case" style="background-image: url(.jpg)">
<div class="button hidden-xs hidden-sm">Læs case</div>
<div class="content">
<div class="row">
<div class="col-md-8">
<h4 class="title">Nori</h4>
<div class="spacer small"></div>
<div class="excerpt"></div>
</div>
</div>
</div>
</div>
<p></a></div>
<div class="col-xs-12 col-md-6"><a href="">
<div class="case" style="background-image: url(.jpg)"><img src=".png" alt="">
<div class="button hidden-xs hidden-sm">Læs case</div>
<div class="content">
<div class="row">
<div class="col-md-8">
<h4 class="title">AN-IVY. Nyt gentleman brand med stor passion for fashion, og klassisk herretøj</h4>
<div class="spacer small"></div>
<div class="excerpt">AN-IVY er et brand startet i 2013. De designer herrekollektioner der er inspireret af Ivy Leagues tradioner og moderne fashion. De har en stor passion for mode og klassisk herretøj.</div>
</div>
</div>
</div>
</div>
<p></a></div>
<div class="col-xs-12 col-md-6"><a href="">
<div class="case" style="background-image: url(.jpg)">
<div class="button hidden-xs hidden-sm">Læs case</div>
<div class="content">
<div class="row">
<div class="col-md-8">
<h4 class="title">Powderstore</h4>
<div class="spacer small"></div>
<div class="excerpt"></div>
</div>
</div>
</div>
</div>
<p></a></div>
</div>
</div>
Note the additional <p>
tags at line 15, 29 and 43.
The paragraph tags disappear if I remove the anchor tag in my shortcode, but that's not a solution I can use.
I have made my own theme with shortcodes to WordPress.
In my filters I have:
remove_filter('the_content', 'wpautop');
add_filter('the_content', 'wpautop', 99);
add_filter('the_content', 'shortcode_unautop', 100);
This should remove paragraph tags around and in my shortcodes.
My shortcode output (partial of the entire code):
$output .= '
<div ' . implode(' ', $html_attributes) . '>
<a href="' . get_permalink() . '">
<div ' . implode(' ', $html_attributes_inner) . '>
' . $logo . '
<div class="button hidden-xs hidden-sm">Læs case</div>
<div class="content">
<div class="row">
<div class="col-md-8">
<h4 class="title">' . get_the_title() . '</h4>
<div class="spacer small"></div>
<div class="excerpt">' . get_post()->post_excerpt . '</div>
</div>
</div>
</div>
</div>
</a>
</div>
';
// Script newlines whitespace, tabs etc.
return str_replace(["\r", "\n", "\t"], '', '<div class="row cases">' . $output . '</div>');
This produces:
<div class="row cases">
<div class="col-xs-12"><a href="http://dev.youfront-hosting.dk/case/nori">
<div class="case" style="background-image: url(http://dev.youfront-hosting.dk/content/uploads/nori-restaurant-1120x500.jpg)">
<div class="button hidden-xs hidden-sm">Læs case</div>
<div class="content">
<div class="row">
<div class="col-md-8">
<h4 class="title">Nori</h4>
<div class="spacer small"></div>
<div class="excerpt"></div>
</div>
</div>
</div>
</div>
<p></a></div>
<div class="col-xs-12 col-md-6"><a href="http://dev.youfront-hosting.dk/case/an-ivy">
<div class="case" style="background-image: url(http://dev.youfront-hosting.dk/content/uploads/anivy-founders-545x500.jpg)"><img src="http://dev.youfront-hosting.dk/content/uploads/anivy-logo.png" alt="">
<div class="button hidden-xs hidden-sm">Læs case</div>
<div class="content">
<div class="row">
<div class="col-md-8">
<h4 class="title">AN-IVY. Nyt gentleman brand med stor passion for fashion, og klassisk herretøj</h4>
<div class="spacer small"></div>
<div class="excerpt">AN-IVY er et brand startet i 2013. De designer herrekollektioner der er inspireret af Ivy Leagues tradioner og moderne fashion. De har en stor passion for mode og klassisk herretøj.</div>
</div>
</div>
</div>
</div>
<p></a></div>
<div class="col-xs-12 col-md-6"><a href="http://dev.youfront-hosting.dk/case/powderstore">
<div class="case" style="background-image: url(http://dev.youfront-hosting.dk/content/uploads/team-youfront-545x500.jpg)">
<div class="button hidden-xs hidden-sm">Læs case</div>
<div class="content">
<div class="row">
<div class="col-md-8">
<h4 class="title">Powderstore</h4>
<div class="spacer small"></div>
<div class="excerpt"></div>
</div>
</div>
</div>
</div>
<p></a></div>
</div>
</div>
Note the additional <p>
tags at line 15, 29 and 43.
The paragraph tags disappear if I remove the anchor tag in my shortcode, but that's not a solution I can use.
- Can't you run your shortcode processing filter after the autop processing and not before? Seems like it would save some hassle. – majick Commented Feb 10, 2016 at 4:01
- @majick The theory should work. But shortcode_unautop doesn't seem to function if do_shortcode hasn't been run. (I neither want my shortcodes wrapped in paragraph tags) – andershagbard Commented Feb 10, 2016 at 15:42
3 Answers
Reset to default 2The above solution doesn't work if you're using Advanced Custom Fields. When using ACF, the following code does work:
remove_filter( 'the_content', 'wpautop' );
remove_filter( 'acf_the_content', 'wpautop' );
add_filter( 'the_content', 'wpautop' , 99);
add_filter( 'acf_the_content', 'wpautop' , 100);
add_filter( 'the_content', 'shortcode_unautop',110 );
add_filter( 'acf_the_content', 'shortcode_unautop',111 );
This is the solution:
function wpex_fix_shortcodes($content) {
return strtr($content, [
'<p>[' => '[',
']</p>' => ']',
']<br />' => ']'
]);
}
remove_filter('the_content', 'wpautop');
remove_filter('the_content', 'do_shortcode', 11);
add_filter('the_content', 'wpautop', 100);
add_filter('the_content', 'wpex_fix_shortcodes', 105);
add_filter('the_content' , 'do_shortcode', 110);
This runs wpautop before do_shortcode, but removes the paragraph tags before and after the unformatted shortcodes, then runs do_shortcode.
EDIT
The solution above can also cause some HTML errors. Best practice would be to remove wpautop filter, and then add a shortcode which calls wpautop around content. Like this:
add_shortcode('text', function($attributes, $content = null)
{
// Output
return do_shortcode(wpautop($content));
});
Maybe try removing all the newlines from the output itself, since this is what is ultimately being messed with...
$output .= '<div ' . implode(' ', $html_attributes) . '>';
$output .= '<a href="' . get_permalink() . '">';
$output .= '<div ' . implode(' ', $html_attributes_inner) . '>';
$output .= $logo;
...and so forth. If the newlines are gone maybe wpautop will leave the shortcode output alone.
otherwise, since it is a very specific and misformatted string output, you could always fix for it after the fact:
add_filter('the_content','shortcode_fix',110);
function shortcode_fix($content) {
return str_replace('<p></a></div>','</a></div>',$content);
}
....