If you are reading this, then probably you are having issues like added line breaks or weird looking code on the output of some shortcodes. While, at first you may think from the title of the article, that it has nothing to do with the behavior, but trust me, this is exactly what is breaking the output of the shortcode from our plugin (and probably some other plugins as well, most of them if not all of them).
Understanding the problem
So, what is the problem really? To be honest the problem is not WordPress’ own. It is smart enough to do things in the right way. The problem arrives because of the necessity of two things that some (and we are not accusing anyone) theme developers and plugin developers find confusing and hard to solve.
- Providing a
[raw]
shortcode to print things as it is (without line breaks and texturize). - Preventing WordPress from adding paragraphs to multiline contents inside a shortcode. Say for example
[text][div]
My paragraph.
[/div][/text]will be converted to
[text][div]
<p>My paragraph.</p>
[/div][/text]before the shortcode parsing happens.
To prevent this “self-proclaimed anomaly“, what some people do is tell WordPress to first parse the shortcode and then add paragraphs. The code for this essentially looks like this.
[php]remove_filter( ‘the_content’, ‘wpautop’ );
add_filter( ‘the_content’, ‘wpautop’ , 99 );[/php]
Also, to add the [raw] shortcode functionality,
[php]
function my_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));
}
}
return $new_content;
}
remove_filter(‘the_content’, ‘wpautop’);
remove_filter(‘the_content’, ‘wptexturize’);
add_filter(‘the_content’, ‘my_formatter’, 99);
[/php]
While the codes above seems to get the job done for the developer, it has many unnecessary side-effects. For example, this will not add line breaks to anything inside [raw] shortcode true, but will essentially break other shortcodes by adding line breaks among their HTML content.
Due to this, the output of our very own plugin eForm
[html]
<input type="radio" class="ipt_uif_radio check_me validate[required]"
value="1"
name="ipt_fsqm_form_63[mcq][0][rows][1][]" id="ipt_fsqm_form_63_mcq_0_rows_1__1"
/>
<label for="ipt_fsqm_form_63_mcq_0_rows_1__1"></label>
[/html]
becomes
[html]
<input type="radio" class="ipt_uif_radio check_me validate[required]"<br />
value=”1″<br />
name=”ipt_fsqm_form_63[mcq][0][rows][1][]” id=”ipt_fsqm_form_63_mcq_0_rows_1__1″<br />
/><br />
<label for="ipt_fsqm_form_63_mcq_0_rows_1__1"></label>
[/html]
which ultimately results in this…
Quite messy right? While the simplest fix to this kind of problem is to wrap our shortcode inside [raw], like
[text][raw][ipt_fsqm_form id="1"][/raw][/text]
but that still is _doing_it_wrong
. If you develop theme, then please read on to know why, or if you are just another victim of it, then skip to the fix.
Why is it Wrong?
To understand, we have to discuss how WordPress’ Shortcode API works. WordPress has two nice APIs to texturize and add paragraphs to contents.
If we look into wp-includes/default-filters.php
then it becomes clear.
[php]
add_filter( ‘the_content’, ‘wptexturize’ );
add_filter( ‘the_content’, ‘convert_smilies’ );
add_filter( ‘the_content’, ‘convert_chars’ );
add_filter( ‘the_content’, ‘wpautop’ );
add_filter( ‘the_content’, ‘shortcode_unautop’ );
add_filter( ‘the_content’, ‘prepend_attachment’ );
[/php]
It tells us essentially two things:
- Paragraphs are added to content after “texturizing” it.
- Then standalone shortcodes are stripped from any enclosing paragraphs.
Which in return tells us, WordPress is smart enough to not to convert, say
[text][my_shortcode][/text]
to
[text]<p>[my_shortcode]</p>[/text]
Which seemed to be the very concern about re-prioritizing wpautop anyway. So why bother doing it? Well, we didn’t do it, neither did you. Your theme developer or other plugin developer did it and they have their reasons. But still, it is breaking stuff, so it is time to fix it.
PS: If you are thinking about the [raw] code, then there are many plugins which do it in correct way. Say for example, SyntaxHighlighter Evolved. Personally I always prefer using this plugin when in the need for printing some raw code.
Possible Solutions
Due to unknown varieties of implementations, we can not provide exact solutions, but at least we can try. If you are an end user not a developer, then probably you’d stick to solution 1 and 3, but if you know your way around codes and all, then try solution 2 as well.
Solution 1: Using the raw shortcode
Although wrong, but still it would solve your problems temporarily. If your theme is breaking shortcode output, then probably it is providing a [raw] or [noformat] shortcode to prevent it as well. Consult your theme documentation to know about it, and wrap the shortcode which is breaking inside the raw one. For eg,
[text][raw][ipt_fsqm_form id="2"][/raw][/text]
Solution 2: Removing the code yourself
Inside the functions.php file of your active theme, you might be able to find code similar to this:
[php]
remove_filter( ‘the_content’, ‘wpautop’ );
add_filter( ‘the_content’, ‘wpautop’ , 99 );
// This line might not be present
add_filter( ‘the_content’, ‘shortcode_unautop’, 100 );
[/php]
Or this
[php]
function my_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));
}
}
return $new_content;
}
remove_filter(‘the_content’, ‘wpautop’);
remove_filter(‘the_content’, ‘wptexturize’);
add_filter(‘the_content’, ‘my_formatter’, 99);
[/php]
Remove the one you find. If you can not find it inside functions.php, then you might still be able to find it inside some file called shortcode.php or filters.php or something similar. Best is to do a search for wpautop
inside the theme directory.
Solution 3: Consult your theme developer
If everything fails, then contact the developers of your theme. They should have the solution for you. Also show them this page as a reference so that they can understand the problem right away and solve it.
Solution 4: Consult the forum
If everything else fails, then contact us through our support forum. The link is given on right. We will help you with this.
Hi Swashata,
I was facing this issue with my WP theme that I purchased. The raw tag definitely helped however, the one in this post didn’t work. [raw][[ipt_fsqm_form id=”2″]][/raw]
I guess, the code should be:
[raw][ipt_fsqm_form id=”2″][/raw] – This one worked. This could be specific to my theme though. I am using “Karma” by TrueThemes.
Link to their post for this issue: https://support.truethemes.net/?knowledgebase=using-third-party-shortcode-or-javascript-in-post-editor
Please correct it, if that’s how it should be. I am no developer so, you’ll be the best judge of it. 🙂
Thanks for the post, it saved me much of trouble.
Cheers,
Joydeep
Hello,
Thank you for pointing out the mistake. I accidentally escaped it while writing the post. It has now been fixed.