Skip Navigation

[Resolved] Urgent 2.6.4.2: `WPV_template::remove_wpautop`,`::restore_wpautop` need patch

This support ticket is created 6 years, 1 month ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

Sun Mon Tue Wed Thu Fri Sat
- - 14:00 – 20:00 14:00 – 20:00 14:00 – 20:00 14:00 – 20:00 14:00 – 20:00
- - - - - - -

Supporter timezone: Asia/Ho_Chi_Minh (GMT+07:00)

Tagged: 

This topic contains 1 reply, has 2 voices.

Last updated by Beda 6 years, 1 month ago.

Assisted by: Beda.

Author
Posts
#1134357

PROBLEM: `WPV_Template::restore_wpautop()` incorrectly restores `wpautop` in Gutenberg context.

hidden link specifically and unconditionally removes `wpautop` filter from `the_content`, so this must not be restored. Otherwise rendering will have broken HTML related all the well known problems of `wpautop()` in general (broken `<p>` tags, etc).

This affects Gutenberg 4.1.0+ compatibility, please see hidden link for context.

SOLUTION: there are many things to consider.

1. `gutenberg_wpautop` filter priority has changed. This alone requires a stronger approach than just hardcoding `remove_filter gutenberg_wpautop 8`. What if it is changed again in the future? Need a tracker variable, see patch below.

2. every `remove_filter()` needs to track whether it was successful at all, regardless of `wpautop()`. If no, do NOT restore filters by blind assumption. For example `shortcode_unautop` is a very problematic tool, see https://core.trac.wordpress.org/ticket/14050 for details, and it may be removed on some systems *on purpose* to override with a better processor.

PATCH: hidden link for proper diff syntax highlighting

I'm introducing a new tracker variable and recording every `remove_filter()` call result.
Every restore attempt goes through `if` checks. Helper functions for reducing repeat string literals would be nice, but I'll leave that up to you.
There should be no back-compatibility issues. If anything, rendering should become more consistent all around.

```diff
diff --git a/embedded/inc/views-templates/wpv-template.class.php b/embedded/inc/views-templates/wpv-template.class.php
index 62586ce..52c2ea4 100644
--- a/embedded/inc/views-templates/wpv-template.class.php
+++ b/embedded/inc/views-templates/wpv-template.class.php
@@ -8,6 +8,11 @@ class WPV_template{
^M
$this->wpautop_removed = false;^M
^M
+ /**^M
+ * Tracks which `remove_filter()` call succeeded, and should be restored later.^M
+ */^M
+ $this->remove_filter = [];^M
+^M
$this->view_template_used_ids = array();^M
}^M
^M
@@ -914,34 +919,48 @@ class WPV_template{
}^M
^M
function remove_wpautop() {^M
- remove_filter('the_content', 'wpautop');^M
- remove_filter('the_content', 'shortcode_unautop');^M
+ $this->remove_filter['the_content']['wpautop'] = remove_filter('the_content', 'wpautop');^M
+ $this->remove_filter['the_content']['shortcode_unautop'] = remove_filter('the_content', 'shortcode_unautop');^M
// Remove the autop behavior introduced by Gutenberg when the content does not contain blocks.^M
// The relevant filter is documented in gutenberg/lib/compat.php^M
- if ( function_exists( 'gutenberg_wpautop' ) ) {^M
- remove_filter( 'the_content', 'gutenberg_wpautop', 8 );^M
+ if ( function_exists( 'gutenberg_wpautop' ) ) {^M
+ $this->remove_filter['the_content']['gutenberg_wpautop'][5] = remove_filter( 'the_content', 'gutenberg_wpautop', 5 );^M
}^M
- remove_filter( 'wpv_filter_wpv_the_content_suppressed', 'wpautop' );^M
- remove_filter( 'wpv_filter_wpv_the_content_suppressed', 'shortcode_unautop' );^M
- remove_filter('the_excerpt', 'wpautop');^M
- remove_filter('the_excerpt', 'shortcode_unautop');^M
+ $this->remove_filter['wpv_filter_wpv_the_content_suppressed']['wpautop'] = remove_filter( 'wpv_filter_wpv_the_content_suppressed', 'wpautop' );^M
+ $this->remove_filter['wpv_filter_wpv_the_content_suppressed']['shortcode_unautop'] = remove_filter( 'wpv_filter_wpv_the_content_suppressed', 'shortcode_unautop' );^M
+ $this->remove_filter['the_excerpt']['wpautop'] = remove_filter( 'the_excerpt', 'wpautop' );^M
+ $this->remove_filter['the_excerpt']['shortcode_unautop'] = remove_filter( 'the_excerpt', 'shortcode_unautop' );^M
^M
$this->wpautop_removed = true;^M
}^M
^M
function restore_wpautop( $content ) {^M
- if ( $this->wpautop_removed ) {^M
- add_filter('the_content', 'wpautop');^M
- add_filter('the_content', 'shortcode_unautop');^M
+ if ( $this->wpautop_removed && ! empty( $this->remove_filter ) ) {^M
+ if ( isset( $this->remove_filter['the_content']['wpautop'] ) && $this->remove_filter['the_content']['wpautop'] ) {^M
+ add_filter('the_content', 'wpautop');^M
+ }^M
+ if ( isset( $this->remove_filter['the_content']['shortcode_unautop'] ) && $this->remove_filter['the_content']['shortcode_unautop'] ) {^M
+ add_filter('the_content', 'shortcode_unautop');^M
+ }^M
// Restore the autop behavior introduced by Gutenberg when the content does not contain blocks.^M
// The relevant filter is documented in gutenberg/lib/compat.php^M
if ( function_exists( 'gutenberg_wpautop' ) ) {^M
- add_filter( 'the_content', 'gutenberg_wpautop', 8 );^M
+ if ( isset( $this->remove_filter['the_content']['gutenberg_wpautop'][5] ) && $this->remove_filter['the_content']['gutenberg_wpautop'][5] ) {^M
+ add_filter('the_content', 'gutenberg_wpautop', 5);^M
+ }^M
+ }^M
+ if ( isset( $this->remove_filter['wpv_filter_wpv_the_content_suppressed']['wpautop'] ) && $this->remove_filter['wpv_filter_wpv_the_content_suppressed']['wpautop'] ) {^M
+ add_filter('wpv_filter_wpv_the_content_suppressed', 'wpautop');^M
+ }^M
+ if ( isset( $this->remove_filter['wpv_filter_wpv_the_content_suppressed']['shortcode_unautop'] ) && $this->remove_filter['wpv_filter_wpv_the_content_suppressed']['shortcode_unautop'] ) {^M
+ add_filter('wpv_filter_wpv_the_content_suppressed', 'shortcode_unautop');^M
+ }^M
+ if ( isset( $this->remove_filter['the_excerpt']['wpautop'] ) && $this->remove_filter['the_excerpt']['wpautop'] ) {^M
+ add_filter('the_excerpt', 'wpautop');^M
+ }^M
+ if ( isset( $this->remove_filter['the_excerpt']['shortcode_unautop'] ) && $this->remove_filter['the_excerpt']['shortcode_unautop'] ) {^M
+ add_filter('the_excerpt', 'shortcode_unautop');^M
}^M
- add_filter( 'wpv_filter_wpv_the_content_suppressed', 'wpautop' );^M
- add_filter( 'wpv_filter_wpv_the_content_suppressed', 'shortcode_unautop' );^M
- add_filter('the_excerpt', 'wpautop');^M
- add_filter('the_excerpt', 'shortcode_unautop');^M
$this->wpautop_removed = false;^M
}^M
^M
```

#1134874

Our Developers have been working on Gutenberg compatibility and will continue to work on it, as well to grant compatibility once Gutenberg is part of WordPress.
I have forwarded your information and suggestions to them, so they can evaluate and consider it.

I thank you in name of Toolset for your commitment and for informing us of the findings.

I suggest that we close the ticket here, as I will not be able to update you imminently with changes, however, you could follow the blog post and changelogs for eventual updates made.
If our Developers would have followup questions, I'd inform you here.

Thank you!