Editor changes in 4.8

There are couple of noteworthy changes to the editor in WordPress 4.8.

A much better experience when trying to place the cursor around links. Try inserting a link, then move the cursor with the left and right arrow keys. You can clearly see when it is inside the link element and when it is before or after it.

Following the earlier announcement, support for Internet Explorer 8, 9, and 10 has been removed from the editor.

As always there have been a lot of improvements and bug fixes, upstream in TinyMCE, and in core.

#4-8, #editor

Addition of TinyMCE to the Text Widget

In its first couple years, WordPress lacked rich/visual text editing. Before TinyMCE was incorporated in WordPress 2.0, users had to edit post content as raw HTML with some support from the Quicktags buttons. When widgets were introduced in WordPress 2.2, the Text widget was included which allowed a user to add content to their sidebar. Nevertheless, unlike the post editor, the Text widget did not incorporate TinyMCE, nor did it include Quicktags. For twelve years, since TinyMCE was added to core in 2005, users have had to hack around with HTML in their Text widgets to do things as simple as make text bold or add links. This has been featured even as recently as the 4.7 release video. Well, as of WordPress 4.8, the Text widget is finally getting the same treatment as the post editor with the introduction of TinyMCE for visual text editing, while still supporting raw HTML editing via a Text tab but now with the additional help of Quicktags:

Text widget: visual tab Text widget: text (HTML) tab

A primary reason for the long delay in incorporating TinyMCE into the Text widget was the difficulty of cleanly instantiating another copy of the WordPress visual editor dynamically after the page has loaded. Since WordPress 3.3 there has been the wp_editor() PHP function for instantiating an editor for the initial page load, but there was no facility for instantiating editors afterward, such as when adding a new Text widget to a sidebar. So in #35760 a new JS API was introduced for dynamically instantiating WP editors on the page: wp.editor.initialize(). This JS API is used for the new TinyMCE-powered Text widget; for more, please see Editor API changes in 4.8.

Note that by default the Text widget only features buttons for bold, italic, unordered list, ordered list, and link. If you want to add additional buttons to the toolbar, you may use a plugin to enqueue the following JS to add the blockquote button, for example:

jQuery( document ).on( 'tinymce-editor-setup', function( event, editor ) {
	if ( editor.settings.toolbar1 && -1 === editor.settings.toolbar1.indexOf( 'blockquote' ) ) {
		editor.settings.toolbar1 += ',blockquote';
	}
});

Likewise, a custom button can be added via code like:

jQuery( document ).on( 'tinymce-editor-setup', function( event, editor ) {
	editor.settings.toolbar1 += ',mybutton';
	editor.addButton( 'mybutton', {
		text: 'My button',
		icon: false,
		onclick: function () {
			editor.insertContent( 'Text from my button' );
		}
	});
});

A reason for why there is no “Add Media” button for the editor in the Text widget is that WordPress 4.8 also includes dedicated media widgets for adding images, video, and audio to sidebars. Another reason is a current technical limitation whereby arbitrary media embeds (oEmbeds) fail to work properly outside the context of post content (see #34115). For this reason if you try to embed a video or something else by pasting in a URL it will not currently expand into the embedded content. The same is true for shortcodes: they are not processed by default since many shortcodes presuppose a global $post as the context within which they expect to be running. Plugins may opt-in selectively to support individual shortcodes by filtering widget_text as they have had to do for many years now.

While not supporting shortcodes, the updated Text widget does have some of the same filters applying to it as the_content, in particular:

  • wpautop
  • wptexturize
  • capital_P_dangit
  • convert_smilies

The Text widget has supported a “filter” instance property which was reflected in the UI via a checkbox for whether or not to automatically add paragraphs and line break tags (wpautop). For the updated Text widget, this checkbox is removed entirely in favor of aligning its behavior with the post editor where this behavior is always enabled. These filters only apply on Text widgets that have been updated/touched after the 4.8 upgrade. When a Text widget is modified in 4.8, the filter instance prop gets set to a static string “content” and then it will apply a new widget_text_content filter which then apply the above functions to the widget text.

The incorporation of TinyMCE into the Text widget has necessitated constructing the widget’s form fields differently than how they are normally done. Widgets in core have historically utilized static HTML 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 TinyMCE is a JavaScript component. To avoid having to rebuild TinyMCE every time the user hits Save on the admin screen, the Text widget puts the title field and TinyMCE text field 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 media widgets in 4.8.) The fields in the Text widget’s UI sync with hidden inputs which get synchronized with the server; in the Customizer, changes to the TinyMCE field will be previewed after 1 second with denouncing. The container for the Text widget’s fields is .text-widget-fields and the traditional container for a widget’s input fields as rendered by WP_Widget::form() is .widget-content:

Themes should already account for the most common HTML elements within the text widgets and provide appropriate styles for them—the addition of the editor toolbar increases the likelihood its elements will be used in the future. Most default themes needed additional styles for ordered and unordered lists within widgets, so theme authors are encouraged to double-check their themes and test them with content in the text widget that includes markup provided by the editor toolbar.

Initial groundwork for shimming JavaScript into widgets was added in 3.9 via the widget-added and widget-updated events. A more recent proposal for making JavaScript more of a first class citizen in widgets can be found in #33507 and the media widgets incorporate some of its patterns that were also prototyped in the JS Widgets plugin. The synchronization of a widget’s state (instance properties) via hidden text fields can be eliminated once a widget’s state can be fully represented in a JavaScript model.

The Text widget is implemented as a Backbone.js view which is available at wp.textWidgets.TextWidgetControl. Instances of this view are then stored in the wp.textWidgets.widgetControls object. The widget’s control JS will only instantiate for a given widget once it is first expanded, when the widget-added event fires. What’s more is that the widget will only first initialize once the container is fully expanded since TinyMCE is not able to initialize properly inside of a container that is animating. In order to capture when TinyMCE inside the Text widget is initialized, you should use a TinyMCE event like tinymce-editor-setup. Note also that due the Document Object Model, when a widget is moved to a new location in a sidebar and this the TinyMCE iframe is moved in the DOM, this dynamically-created iframe is reloaded and thus emptied out. For this reason, every time a Text widget is moved to a new location the TinyMCE editor in the widget will be removed and then re-initialized. Keep this in mind when extending.

Keep also in mind that the Text widget 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.

#4-8, #dev-notes, #editor, #widgets

What’s New in Gutenberg? (May 22nd)

We’ll start making weekly posts here in the name of making the ongoing editor updates more visible outside of the Slack channel and the GitHub development stream. At the moment there are 13 blocks implemented in the project, and a few more being worked on by the team and contributors.


In Progress

We welcome all your feedback and contributions on the project repository, or ping us in #core-editor.

#core-editor, #editor, #gutenberg

Editor API changes in 4.8

A new editor API was added in #35760. It makes it possible to dynamically instantiate the editor from JS. There are two parts to it:

  • All editor related scripts and stylesheets have to be enqueued from PHP by using wp_enqueue_editor().
  • Initialization is left for the script that is adding the editor instance. It requires the textarea that will become the Text editor tab to be already created and not hidden in the DOM. Filtering of the settings is done on adding the editor instance from JS.

There are three new methods added to the wp.editor namespace:

  • wp.editor.initialize()
  • wp.editor.remove()
  • wp.editor.getContent()

(See wp-admin/js/editor.js for more info.)

The default WordPress settings are passed to the initialize() method automatically, and can be overridden by passing a settings object on initialization, similarly to using wp_editor() in PHP.

In addition there are several custom jQuery events that are fired at different stages during initialization:

  • wp-before-tinymce-init is fired before initialization and can be used to set or change any editor setting. It passes the settings object.
  • tinymce-editor-setup is fired after initialization has started but before the UI is constructed. It passes the editor instance object.
  • tinymce-editor-init is fired when the TinyMCE instance is ready (same as the init event in TinyMCE).

Here’s an example of how to add few of the default TinyMCE buttons to the toolbar:

jQuery( document ).on( 'tinymce-editor-setup', function( event, editor ) {
	editor.settings.toolbar1 += ',alignleft,aligncenter,alignright';
});

Here is another example of how to add a custom button:

jQuery( document ).on( 'tinymce-editor-setup', function( event, editor ) {
	editor.settings.toolbar1 += ',mybutton';

	editor.addButton( 'mybutton', {
		text: 'My button2',
		icon: false,
		onclick: function () {
			editor.insertContent("It's my button!");
		}
	});
});

For more information please see the TinyMCE documentation.

#4-8, #editor, #tinymce

Editor: How Little Blocks Work

The editor focus is progressing at a steady pace, with some of the major elements taking shape, so it’s a good time to provide an update. This is a complicated flow so a diagram helps explain things a bit better:

The logic flow for the editor is the following:

  • ① inferring a block representation of the post content (parsing);
  • ② describing the post as an ordered list of blocks (state tree);
  • ③ representing the post in the DOM (rendering);
  • ④ attaching controls to manipulate the content a.k.a blocks (editing UI).

Generally speaking, in a declarative paradigm, the state of the application is structured in an easy machine readable format so that what is rendered is a reflection of the state of the application, and where manipulations are represented as a unidirectional flow. However, the reality is we don’t start in WordPress with a representation of the state of the post that has such structure—there’s no knowledge of “blocks” because content is stored serialized in a single flat field.

So our first step is to infer the structure we need from implicit cues. This is a crucial step that makes the double loop in the above diagram work. It is handled by the grammar and parsing mechanism which takes the flat content of the post and infers a tree of ordered block data using, preferably, syntax hints present in HTML comments. The editor is then initialized with a state representation of the block nodes (the middle yellow rectangle in the diagram) generated by the parsing of the raw post content.

We are basically augmenting the structured representation of the post to aid us in building a robust editing tool that can be expressive and limit side effects. The visual editor is then a view that contains and renders the list of block nodes from the internal state into the page, using the shape of markup defined by all registered blocks involved. This removes the need for imperative handling in both finding a block and manipulating its attributes. Blocks provide functions that describe how they want to be represented for both the editing context and the final markup to be saved. The internal representation of the post content is updated as blocks are updated, so during the editing session we can remain in the right side of the diagram above. Finally, when it is time to save the post, the data is serialized back into post_content with HTML comment delimiters to reset the cycle.

The foundation is a bit complicated, but the goal is that creating individual blocks is easier and protected from the technicalities of the process. The rendering of blocks for editing is handled by a VisualBlock component, which attaches event handlers and renders the edit function of a block definition to the document with the corresponding attributes and local state. The edit function is the markup shape of a component while in editing mode, which can be augmented to provide very rich interactions for users. You can take a glance at some of the existing blocks we have so far to get an idea for how the API works and what it takes to build a block. Keep in mind the API is not finalized and tweaks are happening frequently.

If you want to help with this project, head over to #core-editor in Slack or follow the activity in the GitHub repository.

#core-editor, #editor

Continued Discussion on Browser Support

There will be an additional dev chat this week to further discuss the fallback strategy to be used if support is dropped for older browsers. This chat will take place on March 15, 2017 at 12:00 EDT.

While only a small percentage of WordPress users still utilize older, obsolete browsers, it amounts to hundred of thousands, if not millions of people when applied to the WordPress userbase. With the new editor being worked on, there will come a time where a decision must be made whether or not to drop support for these older browsers to allow more modern functionality to be developed. More details can be found in my previous post outlining the discussion so far.

If a decision to drop support for these browsers is reached, there must be a fallback approach determined so that these users do not lose the ability to edit their WordPress site. After continuing the discussion from my previous post outlining proposed fallbacks in the most recent dev chat, here is a modified list of discussed fallbacks with some new, and some improved ideas.

Gradual Approach

@jbpaul17 suggested using a blend of the previously proposed fallbacks. Start by including two versions of TinyMCE in core, and record data to measure exactly how much the old editor is utilized over the course of X number of months, or X number of release cycles. Then, use a simple textarea similar to the one in core now for users with JavaScript disabled. Moving from one step to the next would only happen when an agreed upon benchmark is reached.

This approach hinges on actually having the ability to collect this data (see #38418). As learned with the REST API though, setting benchmarks for future decisions can be very difficult.

Plugin Approach with Auto Install/Install Suggestion

As suggested by @samuelsidler, if the plugin approach is taken and the old version of TinyMCE is not included in WordPress core when the new editor lands, there could be an auto-install approach. After much discussion, it was agreed that auto-installing a plugin would not work because there are too many points of failure. However, a large message encouraging a user to upgrade their browser or install the plugin could be a feasible option.

Plugin Route First, Adding Back If Necessary

@jnylen0 suggested that the plugin route could be taken first, adding the old version of TinyMCE back into core only if a benchmark is reached to indicate sufficient demand. This too would need some way to measure demand for the old editor.

Simple Text Editor with Some Enhancements

@afercia noted that a simple textarea or the current “text mode” will very likely still be required for accessibility reasons. I suggested using this option while making a list of features that would need to be added to that field in order to make this an acceptable fallback for older browsers.

If you have thoughts on any of these, please share them below. Otherwise, hope to see you in Slack!

#browser-support, #editor

The New Editor and Browser Support

If you have not already, I encourage you to read through the Editor Technical Overview and check out the great work so far in the initial Gutenberg prototype. Progress on the new editor can also be followed on the GitHub project.

While the technical overview focuses on what obstacles are faced before forming opinions on the correct way to solve them, it does not focus on the actual technology requirements of the deliverables. As contributors start to create a new and improved editor experience, these technical requirements should be clearly defined and agreed upon so that decisions and progress can be made.

Accessibility, for example, is one technical requirement. All new features must pass WCAG 2.0 AA.

Browser support is another technical requirement. A few lengthy discussions have occurred within #core on Slack and within an issue on Gutenberg’s GitHub. The discussions weigh the pros and cons of dropping support for older browsers in order to use features only supported in newer browsers to improve the editor. It is a tough decision to make because the editing experience will become less useful for a small percentage of users.

This post will attempt to summarize the discussions that have taken place so far and provide some data in an effort to elicit more discussion so a stance on this requirement can be determined.

Who Uses Older Browsers and Why?

Many users are still unable to choose which browser they use. Many companies and institutions have specific browser and version restrictions based on their own unique software, technical, and security requirements.

Here are some factors that contribute to older browser versions still existing:

  • IE8 is the highest version a Windows XP user can install.
  • IE9 is the highest version a Windows Vista user can install.
  • Windows 7 users are forced to update to IE11.

To determine how many people are still using these browsers, 3 data sources were considered. The following numbers are from StatCounter’s GlobalStats:

  • IE8: 0.41%
  • IE9: 0.26%
  • IE10: 0.26%
  • IE11: 3.79%

WordPress.com numbers are nearly identical to these. W3Counter also shows similar numbers with IE8, IE9, & IE10 slightly higher (but with less precision as no numbers are available).

While these percentages are negligible in some contexts, it is important to remember how many people use WordPress. When these statistics are considered in the context of WordPress, they represent tens (if not hundreds) of thousands of people that could potentially be left behind if support for any of these browser versions is dropped.

Current Established Core Browser Support Policies

According to the design handbook, the current stance in Core for browsers is as follows:

  • Full support back to IE11, partial back to IE8.
  • Firefox, Chrome, Safari: Current – 1.
  • iOS Safari: Current – 1.
  • Android browser: Current major.
  • Chrome/Android: Current.
  • Everything else: Bugs fixed as reported.

Older browsers must continue to be functional, even if the experience does not match that of newer browsers.

Calypso only supports IE11 & Edge, dropping support for older versions.

Microsoft has even dropped support for IE8, 9, and 10 very early in 2016. This means that no bug patches or security updates will be released for any of those versions. Because of this, users should be encouraged to upgrade their browsers whenever possible.

Dropping support

In order to drop support for a browser, there needs to be a specific substantial benefit. Not dropping support for anyone, if possible, is desired.

The argument has been made that since this is an overhaul of a core feature essential to WordPress, it could be the perfect time to raise the minimum browser requirements.

Proposed Fallbacks

If a decision is reached to remove support for any of the browser versions mentioned, a proper fallback must be provided so users being forced to use an outdated browser can continue to enjoy using WordPress.

All potential options will be evaluated with the WordPress project’s core philosophies in mind. Please review them and consider them while brainstorming and discussing.

The following are some potential fallbacks that have been suggested in discussions.

Include two versions of TinyMCE in Core

This approach would be seamless for the user. It would, however, magnify the burden on Core’s editor component by requiring two versions of the library to be maintained. It would also ship code that a large percentage of the user base may not use. Every extra file shipped in core also has potential to reduce auto update reliability.

Move the current implementation of TinyMCE into a plugin.

This approach would allow site administrators to enable the current editor experience if their user base contains a large number of people using older browser versions. From a user perspective, this would be a very poor and frustrating experience, especially if the user is not allowed to install plugins, or does not have enough technical knowledge.

Use a simple textarea.

This is the current approach in the editor for users with JavaScript disabled. However, this may alienate some non-technical users who, for example, may not know that <em> is used for italics. A basic HTML knowledge would be required to effectively use this fallback.

Further Discussion

Do you have additional suggestions for an approach or fallback? Feelings on where the line should be drawn in the sand? Thoughts on why we should continue to maintain support for older browsers? Please mention them below.

#browser-support, #editor

Editor Technical Overview

As we start looking at the editor from a technical perspective it’s important we identify the main obstacles and requirements we face before we start conjecturing solutions. As @matt wrote before, the editor focus aims to make writing rich posts effortless. This has taken the path of treating a post as being composed of distinct pieces of content called blocks. These pieces should be easy to insert and manipulate, providing rich and contextual interfaces to interact with as you craft a post.

So how do we go about turning this into a reality? Content in WordPress is, fundamentally, HTML-augmented text; that is to say, it has no inherent data structure. This has been a very important aspect of WordPress and a force for the open web—it speaks to the sense of ownership and freedom WordPress gives you, since it’s always easy to get the full content of your publications—yet the lack of structure gets in the way of the goal to treat content as composed from individual pieces. (This reality also became an issue for the development of post formats a few years ago, but I digress.)

It’s relatively easy to add structure, but it’s not trivial to do so in a way that doesn’t harm data integrity, portability, and the cohesiveness of the post_content. So let’s lay out a first requirement:

① Shape of the Data: Portable Text

To ensure we keep a key component of WordPress’ strength intact, the source of truth for the content should remain in post_content, where the bulk of the post data needs to be present in a way that is accessible and portable, while still providing additional structure on top of HTML semantics for our editing tools. Data needs to be praised and respected. This additional structure would hopefully be invisible to the document’s display context, as it ensures the rendered content is viewable in situations that may not be aware of blocks at all. (Think of email clients, RSS, older editor versions, mobile editors, database dumps, etc.)

Storing things separately means post_content becomes either a pointer or duplicated data, which fragments the source of truth since they can get out of sync easily. (A few content block plugins do this by storing structured data in postmeta and pure data in post_content.) On the other hand, storing things together means structure can become gibberish if it’s not formatted properly before display.

How can we then offer users a great experience when creating or manipulating content without sacrificing the spirit of integrity and data reliability that is expected from WordPress? Good representations of the data would also make it easier to develop robust collaboration tools in the future by allowing us to lock things in a more fine grained way. I believe this is important to figure out soon to allow us to prototype quickly, so I’ll follow up with an initial proposal by the end.

Honouring HTML leads to a second requirement:

② Simplicity and Semantics of Representation

Unless we are improving the semantics of the document we should minimize what markup we add to identify a block; for example, avoid adding extra DOM elements or attributes, both for simplicity and standards sake. WordPress has been a champion of web standards, and we should not venture away from this quality. How can we add structure in a way that remains invisible to the output (as meaningful content as possible) but gives the necessary hooks to infer a structured view for editing purposes?

While we discuss how to structure the content to include invisible demarcation of blocks, the aspect of their nature leads to a third requirement:

③ Static & Dynamic Blocks

Blocks can be either static or dynamic. That is to say, some blocks can be stored with all the necessary aspects needed for their display, while others need to be processed before generating their final output (shortcodes, embeds, widgets, etc). This distinction is important because the most common two blocks people will naturally use are text and images. We should not break their clarity as we treat them as blocks.


 # Static
Here’s some text.

# Dynamic
[text id=123] // Pulls "Here's some text" from somewhere.

This conceptual separation of blocks is useful for designing our project, yet they generate abstract complexity which users should not be exposed to, leading to a fourth requirement:

④ Consistent Experience

One of the biggest benefits of blocks is that composing a post becomes more intuitive and reliable. Everything is inserted under the same assumptions; discovering what can be inserted is a natural part of inserting content. To the user all blocks behave in a consistent and familiar way, even if they provide tailored UIs for their controls.

The user should also be able to edit a post in a different system (mobile, REST, older version of core, apps like Mars Edit, etc), even if they lose the advantages of block editing. That’s another reason why post_content as source of truth matters, compared to storing a JSON structure in postmeta. Having things in two places means they can get out of sync depending on what tool you used to edit.

These nuances of data, UI, and display lead to a final and more general requirement, which is understanding the system we’ll be crafting:

⑤ The System

The editor experience has three fundamental aspects to its system: the UI used to manipulate a block; the demarcation of the block; the rendered output of the block. These are all separate concerns, from the tools we craft to edit a post, to the document syntax that holds the data structure, to the way the final output is generated to be displayed as HTML. (With static blocks that last aspect may be of no significant concern since the document doesn’t care about the presence of static blocks, it just displays them.)

Picturing these concerns as connected but fundamentally separate would help us figure out the best design and technical solutions for each stage, while avoiding us taking aggressive moves by coupling expectations. For instance, JavaScript is a natural technology to look at when it comes to the ability to manipulate and interact with content blocks, yet it may not be the best at all when it comes to rendering the final post to a viewer. Avoiding painting the whole flow under the same light should allow us to focus efforts, because we don’t have to change everything.

❶ Coda

As a final coda, and following @joen‘s design exploration, let’s keep in mind that our first goal should be to set up a reliable foundation to allow us to iterate quickly and test assumptions. I propose we focus initially on a few static blocks (text, image with and without caption, quote) to limit scope of the project.

In which ways can we fulfil ① and ② from the above requirements?

Shortcodes fall short in that they are not invisible, they are opaque, not standing to the scrutiny of semantics, and are also painful to parse. Alternatives could be data-* attributes in the HTML elements or custom elements (paving the way for web components, perhaps), yet we need to be careful with adding cruft.

One other possibility is to look at HTML comments as a way to provide explicit demarcation to post_content without affecting the node structure of the document for something that is inherently spurious to the HTML semantics. WordPress already uses comments for the more tag (<!--more-->) and splitting content into pages in a way that has proven to be quite robust.

It could look something like this:

<!-- wp:image -->
<figure>
  <img src="/">
  <figcaption>A picture is worth a thousand words</figcaption>
</figure>
<!-- /wp -->

There are drawbacks, benefits, and implications with each that we should discuss separately. Are there any other possible solutions?

Please, join us in #core-editor if you are interested. We’re holding weekly meetings in Slack, Wednesdays at 19:00 CET.

#editor

Focus Tech and Design Leads

There are three main focuses this year: the REST API, the editor, and the customizer.

For the REST API we’re going to work on getting first party wp-admin usage of the new endpoints, and hopefully replace all of the core places where we still use admin-ajax.

The editor will endeavour to create a new page and post building experience that makes writing rich posts effortless, and has “blocks” to make it easy what today might take shortcodes, custom HTML, or “mystery meat” embed discovery.

The customizer will help out the editor at first, then shift to bring those fundamental building blocks into something that could allow customization “outside of the box” of post_content, including sidebars and possibly even an entire theme.

Each focus will have a tech lead, and a design lead, and I’ll be working closely with each to make sure we’re aligned and moving diligently in the right direction even though we don’t have the normal release hooks. These starting leads will be:

REST API: Ryan McCue and KAdam White.

Editor: Matias Ventura and Joen Asmussen.

Customizer: Weston Ruter and Mel Choyce.

Given there is no set timeline for releases that would normally set a term, these leads are free to bow out at any time they feel they can’t contribute fully and we’ll find a replacement.

You might be wondering what each lead is responsible for. The REST team gave some thought to this for their focus, and this is the list they came up with:

Tech Lead responsibilities:

  • identify and ensure implementation of first-class REST API usage within WP-Admin,
  • replacing/refactoring admin-ajax use.
  • overall REST API architecture
  • infrastructure and endpoint performance
  • security at an infrastructure and endpoint (data-exposure) level
  • improving authentication options and documentation
  • working with the Design Lead to build new, or expand on existing, endpoints
  • working with the Design Lead to address usability feedback for the infrastructure and endpoints

Design Lead responsibilities:

  • usability of endpoints for internal or external clients
  • usability of the infrastructure from the perspective of a API client
  • working with the Editor and Customizer focus teams to collect requirements and gather feedback
  • identifying ways to improve the overall experience for folks building clients or consuming endpoints (like documentation)

#customizer, #editor, #rest-api

Idea: Uniform Resource Identifiers as an Alternative to Shortcodes

The idea is that any objects embedded in a post’s content have their own home and should be seen as separate resources. Data would be stored elsewhere.

Examples

  • https://example.com/resources/contact-forms/email-ella/
  • https://example.com/resources/charts/php-versions-wordpress/
  • https://example.com/author/iseulde/
  • https://example.com/galleries/yummy-chocolates/
  • https://example.com/surveys/wordpress-editor-2016/
  • https://external.com/some-map-or-form/

Object Types

This approach could be good for:

  • Forms such as contact forms, surveys and polls.
  • Visualised data such as diagrams, charts, graphs and tables.
  • Lists of items such as a galleries, playlists and lists of posts.
  • Albums or manually composed collections of items where the presentation is uniquely different from a normal list.
  • Any content that needs to be reused or organised separately. Anything that can be re-sourced. 😉
  • Any external resources.

This is not good for:

  • Layout.
  • Text conversions.

Inspiration

  • External embeds work similarly in WordPress through oEmbed.
  • Images, audio and video are embedded by their URL in HTML.
  • Media have their own “attachment” post type in WordPress.
  • Many plugins already have a separate post type to store their data.
  • I’ve seen some news media do this already for things for like graphs (post, resource).

Benefits

  • A URL (or “link”) is a concept that is already familiar to many users.
  • URIs are designed for these sort of things. Think about images — it would follow the same paradigm.
  • The content is treated as a separate resource, and can be reused, just like shortcodes, but it forces separation.
  • WordPress allows you to create “pretty” semantic URIs, so the resource can be described for a better experience.
  • A cool side effect is that others could embed these easily on their site through oEmbed. WordPress already supports this.
  • If there’s a problem, the URL will act as a fallback.

Implementation

A quick way to implement this for WordPress 4.4 and higher is registering a new post type. This will handle most things, you just need to provide a custom embed template with the template_include filter. An external resource can be filtered with the Embed API and TinyMCE View API, even if it doesn’t support oEmbed.

Challenge: Variants and Settings

Either each variant of an resource needs its own ID, or settings could be passed with a query string. I think the use of settings should be minimised — for example, columns for a gallery object may be better set per ID. Settings can certainly be useful for things like autoplay, for example YouTube allows you to set the start time.

Challenge: Alignment

This is great if the URL is added on a separate line, but aligning the object is not evident. This is a challenge for shortcodes too. At the moment the core galery shortcode does not allow you to allign it, and the caption shortcode has an attribute for it. Similarly the URl could have a query parameter for alignment, but that doesn’t sound ideal. Alternatively the paragraph could be floated, or it needs to be wrapped in a `div` element to float mid-text. Another approach is to always wrap the URLs in a (custom) tag that can have display information. Again, think about how images are embedded in HTML.

Possible solution:

<figure class="alignright">
 https://example.com/galleries/yummy-chocolates/
 <figcaption>Chocolates.</figcaption>
</figure>

Challenge: Namespace

Shortcodes would have a similar problem, though slug clashes are probably more likely. Ideally plugins should use their own prefix, but this may be seen as ugly. Another way to avoid clashes with other post types is a sub type for “attachments” or “resources”.

Challenge: Extra Queries

I don’t see this exactly as a challenge, as it’s the nature of the concept, but it may be used as an argument against it. Many shortcodes already make use of custom post types to store data and embedding media (or anything else) also requires extra queries. If and how this should be cached is another problem.


I would love to hear your thoughts on this alternative, especially from those who use shortcodes for this type of objects in the post content. If you already use a custom post type, why not take advantage of embedding instead of creating shortcodes? If you want to embed external resources, why wrap it in a shortcode?

If you have other alternatives, I’d love to hear about those too!

#editor, #media, #plugins, #shortcodes