As first introduced in the Image Widget Merge Proposal, WordPress 4.8 includes media widgets (#32417) for not only images (#39993) but also video (#39994) and audio (#39995), on top of an extensible This is the ability to add additional functionality to the code. Plugins extend the WordPress core software. base for introducing additional media widgets in the future, such as for galleries and playlists. To quote [40640]:
The last time a new 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. was introduced, Vuvuzelas were a thing, Angry Birds started taking over phones, and WordPress stopped shipping with Kubrick. Seven years and 17 releases without new widgets have been enough, time to spice up your sidebar A sidebar in WordPress is referred to a widget-ready area used by WordPress themes to display information that is not a part of the main content. It is not always a vertical column on the side. It can be a horizontal rectangle below or above the content area, footer, header, or any where in the theme.!
Since widgets are a very old part of WordPress (since 2.2), widgets in core Core is the set of software required to run WordPress. The Core Development Team builds WordPress. have been very much entirely built using PHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 7.4 or higher with some Ajax sprinkled on top. In the time since WP_Widget
was introduced in 2.8, WordPress has made dramatic shifts toward developing interfaces in JavaScript JavaScript or JS is an object-oriented computer programming language commonly used to create interactive effects within web browsers. WordPress makes extensive use of JS for a better user experience. While PHP is executed on the server, JS executes within a user’s browser. https://www.javascript.com/., including with the Customizer Tool built into WordPress core that hooks into most modern themes. You can use it to preview and modify many of your site’s appearance settings. in 3.4 and the Media Library in 3.5, and more recently with the focus on the REST API The REST API is an acronym for the RESTful Application Program Interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application (think “phone app” or “website”) can communicate with the data store (think “database” or “file system”) https://developer.wordpress.org/rest-api/. and the editor (Gutenberg).
Given that the media widgets are naturally interfacing with the media library JS JavaScript, a web scripting language typically executed in the browser. Often used for advanced user interfaces and behaviors., it is necessary that the media widgets make use of JavaScript to construct their UI User interface instead of relying on PHP. The media widgets fully reuse the existing media modal frames for not only selecting the media to display but also to edit all of its properties: attachments can be selected from the media library, while external media can be inserted by URL A specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org.
Initial groundwork for shimming JavaScript into widgets was added in 3.9 via the widget-added
and widget-updated
events, which are also being utilized in 4.8 with the Addition of TinyMCE to the Text Widget. A more recent proposal for making JavaScript more of a first class citizen can be found in #33507 and the media widgets incorporate some of its patterns that were also prototyped in the JS Widgets 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. The media widgets make use of a Backbone View to manage the widget control’s UI and a Backbone Model for reading and manipulating the widget instance data.
Base Media Widget
PHP: wp-includes/widgets/class-wp-widget-media.php
JS: wp-admin/js/widgets/media-widgets.js
The three widgets all extend a WP_Widget_Media
PHP abstract class; in JS the Backbone view wp.mediaWidgets.MediaWidgetControl
and wp.mediaWidgets.MediaWidgetModel
are extended. A unique aspect of how the media widgets work is how instance data is validated and sanitized. Normally widgets utilize procedural code to sanitize instances via a subclassed WP_Widget::update()
method. The media widgets, however, make use of a REST API schema returned from WP_Widget_Media::get_instance_schema()
to sanitize instances declaratively. The WP_Widget_Media::update()
method iterates over the schema and uses it to sanitize and validate the instance properties. (Adding schemas to the base WP_Widget
class is also proposed in #35574.) The JSON JSON, or JavaScript Object Notation, is a minimal, readable format for structuring data. It is used primarily to transmit data between a server and web application, as an alternative to XML. schema is extended to include a couple custom properties: media_prop
provides the media JS property name that the widget instance maps, and the should_preview_update
flag indicates whether a change to that prop should cause the control preview to re-render (this would be retired with a React React is a JavaScript library that makes it easy to reason about, construct, and maintain stateless and stateful user interfaces. https://reactjs.org/. rewrite and/or leveraging of corresponding blocks in Gutenberg The Gutenberg project is the new Editor Interface for WordPress. The editor improves the process and experience of creating new content, making writing rich content much simpler. It uses ‘blocks’ to add richness rather than shortcodes, custom HTML etc. https://wordpress.org/gutenberg/).
The WP_Widget_Media
abstract class has one abstract method which subclasses must implement: WP_Widget_Media::render_media()
. This is the method that WP_Widget_Media::widget()
calls with the $instance
props to render the media for a given widget media type. Before the props are passed to the method, the $instance
is applied through widget_{$id_base}_instance
filters.
A media widget subclass should output additional JS templates as the control needs by extending WP_Widget_Media::render_control_template_scripts()
. Scripts that the widget control requires can be enqueued by extending WP_Widget_Media::enqueue_admin_scripts()
; this is also where the PHP exports can be done with calls to wp_add_inline_script()
.
The REST API schema is exported from PHP to JS on the subclassed MediaWidgetModel
prototypes. Other properties on the prototypes which should be extended include l10n
and mime_type
. The model subclasses are registered by assigning them to the wp.mediaWidgets.modelConstructors
object, keyed by the widget ID base (e.g. media_image
, media_video
, etc). In the same way, the Backbone View wp.mediaWidgets.MediaWidgetControl
is subclassed and registered by adding to the wp.mediaWidgets.controlConstructors
object, also keyed by widget ID base. This is similar to how control types are registered in the Customizer.
The MediaWidgetControl
and MediaWidgetModel
will be instantiated once a widget control is expanded. Their instances will be then added to the wp.mediaWidgets.widgetControls
object and wp.mediaWidgets.modelCollection
respectively.
There is a subclass of a media controller and a couple media views in the wp.mediaWidgets
namespace. These extensions to media classes are needed due to current limitations in media extensibility. They may be removed/reduced with improvements in #40427.
As with the incorporation of TinyMCE into the Text widget, the incorporation of the media library into the media widget has necessitated constructing the widget’s form fields differently than how they are normally done. Widgets in core have historically utilized static HTML HyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers. for their control form fields. Every time a user hits “Save” the form fields get sent in an Ajax request which passes them to the WP_Widget::update()
method and then the Ajax response sends back the output of WP_Widget::form()
which then replaces the entire form. (Note widgets in the Customizer behave differently since there is no Save button in the widget, as updates are synced and previewed as changes are made; read more about Live Widget Previews.) This worked for static HTML forms in the past, but in the case of the media widgets the UI built with JavaScript instead of server-side PHP.
To avoid having to rebuild the media preview every time the user hits Save on the admin (and super admin) screen, the media widget puts its UI elements outside of the container that is “managed” by the server which gets replaced with each save. (A similar approach has also been employed by the new TinyMCE-extended Text widget in 4.8.) Since core does not yet represent a widget’s state in a JavaScript model (again see #33507), the media widget syncs its MediaWidgetModel
props with hidden inputs that get rendered by WP_Media_Widget::form()
in order to be sent to the server for preview and saving. The container for the media widget’s fields is .media-widget-control
and the traditional container for a widget’s input fields as rendered by WP_Widget::form()
is .widget-content
:
For examples of how to implement media widgets, see the three implementations included in 4.8 as follows.
Image Widget
PHP: wp-includes/widgets/class-wp-widget-media-image.php
JS: wp-admin/js/widgets/media-image-widget.js
Field |
Type |
Default |
Description |
attachment_id |
integer |
0 |
Attachment post ID |
url |
string |
"" |
URL to the media file |
title |
string |
"" |
Title for the widget |
size |
string |
"medium" |
Size |
width |
integer |
0 |
Width |
height |
integer |
0 |
Height |
caption |
string |
"" |
Caption |
alt |
string |
"" |
Alternative Text |
link_type |
string |
"none" |
Link To |
link_url |
string |
"" |
URL |
image_classes |
string |
"" |
Image CSS Cascading Style Sheets. Class |
link_classes |
string |
"" |
Link CSS Class |
link_rel |
string |
"" |
Link Rel |
link_target_blank |
boolean |
false |
Open link in a new tab |
image_title |
string |
"" |
Image Title Attribute |
Video Widget
PHP: wp-includes/widgets/class-wp-widget-media-video.php
JS: wp-admin/js/widgets/media-video-widget.js
The video widget allows for embeddable video formats to be selected from the media library or linked to externally by URL. In addition, URLs to YouTube or Vimeo may also be provided since the video
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. logic supports rendering them via MediaElement.js. It is possible for plugins to add support for additional oEmbed providers via extending the video widget control’s isHostedVideo
method; for more, see the Jetpack PR for adding VideoPress support.
Field |
Type |
Default |
Description |
attachment_id |
integer |
0 |
Attachment post ID |
url |
string |
"" |
URL to the media file |
title |
string |
"" |
Title for the widget |
preload |
string |
"metadata" |
Preload |
loop |
boolean |
false |
Loop The Loop is PHP code used by WordPress to display posts. Using The Loop, WordPress processes each post to be displayed on the current page, and formats it according to how it matches specified criteria within The Loop tags. Any HTML or PHP code in the Loop will be processed on each post. https://codex.wordpress.org/The_Loop. |
content |
string |
"" |
Tracks (subtitles, captions, descriptions, chapters, or metadata) |
mp4 |
string |
"" |
URL to the mp4 video source file |
m4v |
string |
"" |
URL to the m4v video source file |
webm |
string |
"" |
URL to the webm video source file |
ogv |
string |
"" |
URL to the ogv video source file |
flv |
string |
"" |
URL to the flv video source file |
Note that the presence of format-specific fields is dependent on what is returned by wp_get_video_extensions()
.
Audio Widget
PHP: wp-includes/widgets/class-wp-widget-media-audio.php
JS: wp-admin/js/widgets/media-audio-widget.js
The audio widget allows for embeddable audio formats to be selected from the media library or linked to externally by URL. Note that there are no oEmbed audio formats supported since the audio
shortcode logic only supports rendering players for actual audio files.
Field |
Type |
Default |
Description |
attachment_id |
integer |
0 |
Attachment post ID |
url |
string |
"" |
URL to the media file |
title |
string |
"" |
Title for the widget |
preload |
string |
"none" |
Preload |
loop |
boolean |
false |
Loop |
mp3 |
string |
"" |
URL to the mp3 audio source file |
ogg |
string |
"" |
URL to the ogg audio source file |
m4a |
string |
"" |
URL to the m4a audio source file |
wav |
string |
"" |
URL to the wav audio source file |
Note that the presence of format-specific fields is dependent on what is returned by wp_get_audio_extensions()
.
Default Themes Updates
Themes that add custom styles to the MediaElement.js player (namely Twenty Thirteen and Twenty Fourteen) were updated from just styling it within syndicated content, to also include instances within widgets. Most themes don’t restrict styles for captioned images or media players to just post content, that is, limit CSS selectors to classes output by post_class()
. If your theme does, make sure to either remove that constraint or include a .widget
selector.
Conclusion
The work on the new media widgets in core was conducted in the Core Media Widgets plugin and on its corresponding wp-core-media-widgets GitHub GitHub is a website that offers online implementation of git repositories that can easily be shared, copied and modified by other developers. Public repositories are free to host, private repositories require a paid subscription. GitHub introduced the concept of the ‘pull request’ where code changes done in branches by contributors can be reviewed and discussed before being merged be the repository owner. https://github.com/ repo. Many of the decisions that were made in the architecture of the feature can be found there in the GitHub issues and pull requests.
Keep in mind that the media widgets will likely undergo many more changes with the incorporation of the Gutenberg editor, and that widgets themselves will likely see many changes to align with Gutenberg’s editor blocks which are now being prototyped. Essentially if you can insert a given type of block Block is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. into the editor, there should also be a widget available for representing the same content.
#4-8, #dev-notes, #media-widgets
You must be logged in to post a comment.