The 4.8 release caused issues for many sites that had custom HTML HyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers. in Text widgets, which until now had been common practice. So we’ve been working hard on fixes in the 4.8.1 release which aim to simultaneously serve the needs of novice users and advanced users alike: the rich Text widget A WordPress Widget is a small block that performs a specific function. You can add these widgets in sidebars also known as widget-ready areas on your web page. WordPress widgets were originally created to provide a simple and easy-to-use way of giving design and structure control of the WordPress theme to the user. (introduced in 4.8), a legacy mode for the Text widget, and a Custom HTML widget.
For more background on the changes in 4.8, see Addition of TinyMCE to the Text Widget. To review, the Text widget in 4.8 includes TinyMCE—the same visual editor used for writing post content—and it looks like:
Text Widget Legacy Mode
The issues with the introduction of TinyMCE to the Text widget revolve around the ways that TinyMCE attempts to clean up HTML code by deleting empty elements (such as those for dashicons) and dropping attributes it may not recognize (such as HTML5 Microdata attributes). Also with the 4.8’s removal of the “automatically add paragraphs” checkbox, there were also issues related to paragraphs and line breaks being added incorrectly.
Note that the Text widget was already designed to preserve the old behavior of the widget until it was modified and thus upgraded, so there are many instances of Text widgets in the wild today that could very well begin to break upon being modified. For this reason the issues were not reported right away and instead started to trickle in steadily after the release.
There were various solutions that were considered, but the one that had the consensus among contributors was:
[Check if the Text widget] was previously saved from an older version of WordPress before TinyMCE was added to the Text widget. If it is such a pre-existing Text widget instance, then use heuristics to detect if TinyMCE would negatively impact the contents of the widget, including the auto-p checkbox being unchecked, whether there are empty tags, and whether there are span, div, script, or style tags. When the Text widget is in this legacy mode, it can have a notice that informs users of the new HTML Code widget and that it should be used going forward. Likewise, in the new mode when TinyMCE is present, when the Text (HTML) tab is selected, there can be a note (perhaps an admin (and super admin) pointer) that encourages users to use the HTML Code widget instead. By implementing this, novice users with basic content in their widgets win, and advanced users with custom HTML content in their widgets will cease from being negatively impacted.
The Text widget in legacy mode looks the same as the Text widget before 4.8, but with the addition of a new notice:
The legacy mode will only be presented for widgets created prior to 4.8.0 that have instance data which match the logic in the
WP_Widget_Text::is_legacy_instance() method. The legacy mode will not be presented to newly created Text widgets. Once a Text widget is opened and saved in legacy mode, it will permanently stay in legacy mode. There is a new instance property called “
visual” which will be set to
false when a widget is saved in legacy mode. When a new Text widget is created, it is opened in the default visual mode and the new instance will get saved with
Text Widget Filters
There is a change in how the
filter instance property was used in 4.8.0: in that release, when a Text widget was modified, the fact that it had been upgraded was stored by overloading the
filter boolean property to also have the value of
"content", indicating that the widget gets content filters applied like a post does. Since this string is a truthy value, I reasoned it would normally work the same in filters that check
! empty( $instance['filter'] ), but it would fail in cases where a plugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party tried
true === $instance['filter']. So 4.8.1 reverts the overloading of the
filter property to again be a boolean, and this should improve compatibility for
widget_text filters. Whenever a Text widget is modified with the default visual mode (with TinyMCE) it will get both
filter=true saved in its instance. When a Text widget is modified in the legacy mode, it will always get
visual=false and its
filter property will reflect the checked state of the auto-paragraph checkbox.
Another note on filters: special consideration was made for shortcodes in the Text widget given the frequency of plugins and themes adding shortcode A shortcode is a placeholder used within a WordPress post, page, or widget to insert a form or function generated by a plugin in a specific location on your site. support (since the widget does not recognized them by default in core Core is the set of software required to run WordPress. The Core Development Team builds WordPress.). Plugins and themes have done
add_filter( 'widget_text', 'do_shortcode' ) to add support. Since the
widget_text filter Filters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output. applies before the new
widget_text_content filter (as of 4.8), it will apply before
wpautop will have applied, resulting in the possibility of extra line breaks being added undesirably if the shortcode output has new line characters. So to help prevent that from happening, the Text widget will temporarily move the
do_shortcode handler from
widget_text_content just in time while the filters are being applied. See the relevant logic.
For users who are accustomed to pasting HTML into the Text widget, when an attempt is made to paste markup into the visual editor a pointer will be displayed informing them that they should paste it into the Text tab instead, or to alternatively use the new Custom HTML widget (see section below):
Likewise, when a user opens the Text tab, it will also open a pointer to inform them of the Custom HTML widget:
While pointers are normally displayed on upgrades, these pointers will be displayed even on new installs since they reflect changes to long-standing behavior for the Text widget that users have become accustomed to. Any tutorials that instruct users to use the Text widget for pasting in arbitrary HTML should be updated to instruct the users to select the Custom HTML widget instead.
Custom HTML Widget
Since users are prompted (per the pointers above) to try using the Custom HTML widget instead of the Text widget for some use cases, it is important that the widget content be able to be freely copied between the Text widget and the Custom HTML widget. For this reason, the Custom HTML widget retains the application of the
widget_text filters like the Text widget does. The type of widget for which the filter is applying can be determined by looking at the type of the
WP_Widget instance being passed as the last filter argument. When the
widget_text filter is applied, it will pass the second
$instance parameter in the same format as the Text widget, with
text (instead of
visual properties that are always both set to
false (as if the instance was in legacy non-visual mode). In addition to re-applying the
widget_text filter, the Custom HTML widget has a dedicated
widget_custom_html_content filter whereas the the Text widget has a dedicated
In addition to filter compatibility, the Custom HTML widget also tries to retain theme styling compatibility by using the same
widget_text CSS Cascading Style Sheets. class name on the outer widget wrapper and
textwidget on the inner wrapper around the content itself. For any themes that wish to style the Custom HTML widget alone, there are the
custom-html-widget class names used on the outer and inner wrapper elements respectively. For themes that wish to style the Text widget alone and exclude the Custom HTML widget, the
:not() pseudo selector can be used, for example
.textwidget:not(.custom-html-widget) for the outer and inner wrappers, respectively.
The markup generated by a Custom HTML widget on the frontend will look like:
<section id="custom_html-6" class="widget_text widget widget_custom_html">
<h2 class="widget-title">My Title</h2>
<div class="textwidget custom-html-widget">My Content</div>
This same Custom HTML widget’s instance data will look like:
"title": "My Title",
"content": "My Content"
For more specifics on the Custom HTML widget, refer to the subclass:
Here is a list of tickets related to the Text widget and Custom HTML widget which are closed in the 4.8.1 release:
- #40907: Introduce widget dedicated for HTML code
- #40951: New Text Widget – Switching Between Visual/Text Editor Strips Out Code
- #40960: Set `’filter’ => ‘content’` on starter content “business info” widget
- #40960: Widgets: The Text widget should respect the “Disable the visual editor when writing” setting
- #40972: TinyMCE editor in Text widget does not have RTL contents
- #40974: Updated text widget do not save text (when using paste)
- #40986: Widgets: text widget and media widgets cannot be edited in accessibility Accessibility (commonly shortened to a11y) refers to the design of products, devices, services, or environments for people with disabilities. The concept of accessible design ensures both “direct access” (i.e. unassisted) and “indirect access” meaning compatibility with a person’s assistive technology (for example, computer screen readers). (https://en.wikipedia.org/wiki/Accessibility) mode
- #41021: Text widget does not show Title field or TinyMCE editor
- #41158: Increase tinymce panel z-index
- #41386: Text Widget – Wording – Legacy Mode 4.8.1 beta A pre-release of software that is given out to a large group of users to trial under real conditions. Beta versions have gone through alpha testing in-house and are generally fairly close in look, feel and function to the final product; however, design changes often occur as part of the process.
- #41392: Theme styles for Text widget do not apply to Custom HTML widget
- #41394: Text widget: Rename legacy mode to visual mode and improve back-compat for widget_text filters
#4-8-1, #dev-notes, #tinymce, #widgets