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
```