Make WordPress Core

Recent Updates Page 2 Toggle Comment Threads | Keyboard Shortcuts

  • Pascal Birchler 9:49 am on October 15, 2016 Permalink |
    Tags: ,   

    Shiny Updates v3 Kickoff Chat 

    While the biggest chunk of Shiny Updates v2 was merged into WordPress 4.6, there were still plenty of ideas that didn’t make it in time. I think it would be worthwhile to bring more shininess to WordPress 4.8 or 4.9. Regular chats have been dormant for a while, but I’d like to continue them starting Wednesday, 19 October 2016, 17:00 UTC in the #feature-shinyupdates Slack channel.

    Topics for the first chat will include a brief update on current shiny updates bugs in WordPress core and the planned goals for Shiny Updates v3 (e.g. update-core.php). Some of the ideas can be found on GitHub.

    Now is a great time to get involved and help making WordPress updates even more shiny. Please come join us next week and contribute to the continuing abolishment of The Bleak Screen of Sadness™.

    • Philip Ingram 3:30 pm on October 15, 2016 Permalink | Log in to Reply

      I won’t be able to make the chat but one thing that struck me again yesterday as a frustration (and not sure this actually falls under shiny updates) is why are we still not opening screenshot images for plugins in some type of light box modal vs forcing browsers to download the images. It’s not very convenient when one simply wants to view the image in larger form and I don’t think this would be that hard to pull off either.

      • Pascal Birchler 3:42 pm on October 15, 2016 Permalink | Log in to Reply

        Are you referring to the plugin directory? If so, the images should open in a new tab right now. If the images is being downloaded, it has the wrong mime type associated with it and the developer should fix this in Subversion (at least that’s required right now).

        For adding a light box, I’d suggest requesting that in #meta or https://make.wordpress.org/meta/. The new plugin directory is currently in the works and I’m sure the team will happily consider it.

  • K.Adam White 10:26 pm on October 14, 2016 Permalink |  

    REST API: Agenda for Oct 17, 2016 Meeting 

    The meeting to decide whether to merge the REST API Content Endpoints in WordPress 4.7 will occur at 2016-10-18 01:00 UTC in #core!

    Please comment on this feedback post with your arguments for or against.

    In preparation for that meeting, we will be holding bonus weekend office hours at 2016-10-15 17:00 UTC and 2016-10-16 17:00 UTC in #core-restapi.

    Our usual team meeting is also happening, on Monday at 2016-10-17 14:00 UTC. The agenda for this meeting:

  • David A. Kennedy 4:38 pm on October 14, 2016 Permalink |
    Tags: , ,   

    Twenty Seventeen: Agenda for Oct 14, 2016 Meeting 

    Here’s the agenda for today’s weekly meeting on Twenty Seventeen. It will last 30 minutes, and I’ll be around in the #core-themes channel for at least 30 minutes afterward to answer any questions.

    • General theme update.
    • Flexbox.
    • Open floor.

    Reminder: Meetings are every Friday at 18:00 UTC. Twenty Seventeen Features meeting every Tuesday at 17:00 UTC.

    • Joy 5:11 pm on October 14, 2016 Permalink | Log in to Reply

      I’m pretty new to Slack, so it took me awhile to find where the meeting actually is
      http s://wordpress.slack.com/messages/core-themes/
      and not
      http s://wordpress.slack.com/archives/core-themes

  • K.Adam White 11:15 pm on October 13, 2016 Permalink |
    Tags: ,   

    Merge Proposal Discussion: REST API Content Endpoints 

    There are discussion meetings and office hours in #core-restapi at 2016-10-14 14:00UTC and 2016-10-14 19:00UTC on Friday the 14th. Our next team meeting is on 2016-10-17 14:00UTC. Please attend some of all of these, because

    We are meeting at 2016-10-18 01:00 UTC to make a decision on this merge proposal!

    To that end, the below discussion points will be updated regularly, please leave comments on this post or join the conversation in #core-restapi.

    Yesterday at the dev chat the API Team proposed the Content API Endpoints for merge in WordPress 4.7. There was popular support for this feature but as @jorbin and @helen noted that the lack of dissent suggested additional review is needed, so the API Team is continuing to seek thorough review & constructive criticism of the content endpoints, including the open questions previously shared on the week 7 and week 8 API team updates.

    The merge proposal also engendered follow-up discussion in the #core-restapi channel about the benefit content endpoints bring to core, whether having such endpoints built in is quantifiably more beneficial than having them as a plugin, whether moving development from a plugin to core would slow development, and whether the endpoints as-proposed have been sufficiently reviewed for security and performance. We attempt to capture those questions & concerns (and the perspectives on them) below.


    Have the content API endpoints been thoroughly reviewed for security?

    • The REST API plugin has been on HackerOne for over a year with paid bounties for bugs
    • @barry has begun a security review


    How does the API measure up against alternatives? Are there concerns about how the API could impact the servers to which it is deployed?

    • DeliciousBrains did a performance comparison with Admin AJAX and found the REST API to have a performance improvement (These tests have not yet been independently verified)
    • @mikeschroder notes in the comments that using the REST API in place of Admin-Ajax will also bring speed benefits by permitting many previously-uncacheable requests to be cached.

    User Feedback

    Are the content endpoints sufficiently well-tested & vetted by the community?

    • @matt questions whether feedback is coming too late in development for concerns to be acted upon
      • @rmccue notes that the v2 endpoints were created based on user feedback; REST API endpoints are being deployed by plugins and running on VIP, and the content endpoints have been in wide use across a variety of sites, leading to 90+ code contributors and far more developers’ support & feedback on the endpoints
    • @rmccue has also reached out to Phil Sturgeon for feedback and will follow up

    Do Content Endpoints Benefit Core Development?

    Will having these endpoints in core improve future core development, or solve any immediate problems?

    • @bradyvercher suggested that the content API endpoints would remove the need to write a variety of one-off ajax callbacks when developing future WordPress Core AJAX functionality
    • @westonruter notes that the customizer could dynamically create settings for posts and other kinds of content without having to wire up new admin-ajax handlers

    Will Merging Negatively Impact API Development?

    Will having to work through trac instead of GitHub cause development to atrophy?

    • @jjj argues that merging will slow development, because GitHub-hosted plugins are not bound to WordPress release cycles and have less overhead for features to be developed and deployed for testing. @jjj requested a plan for how the REST API will be developed going forward after the merge of these endpoints that would account for the added friction.
    • @krogsgard countered that core increases the visibility of a project like the content endpoints
      • The number of new contributors in this Slack discussion suggests that this merge proposal is bringing in new voices; whether this supports Brian’s point or not, the team is grateful for the breadth of perspectives being shared -Ed.
    • @rachelbaker suggested that the API endpoints are sufficiently inter-dependent with core WordPress code that maintaining the plugin separately amounts to maintaining a fork, and that such separated development is untenable long-term.
    • @matt hopes that a merge of these endpoints would slow release speed, but not development speed; @rmccue feels that development speed will stay the same or increase, and that tying releases to WordPress Core increases the stability and predictability of the API endpoints.
    • The versioning of the API endpoints supports forward compatibility

    Do Content Endpoints Belong on Every WordPress Site?

    What are the pros and cons to having every WordPress site have content API endpoints?

    • @rmccue suggests the API has network effects that can only be realized with a large install base. @krogsgard draws a comparison to RSS, the widespread availability of which enables everything from podcasting from WP to the use of apps like Feedly.
    • @matt suggests that the Atom API is a better analogue than RSS, which is an independent and pre-existing standard, and that network effects could be tested through inclusion in Jetpack
    • @joostdevalk notes that many plugins, like Yoast, have data tied to existing content such as posts and pages; either they expose the content through their own endpoints, or core does. If Core exposes content types through the API then plugins may build on top of that shared foundation, not independently reinvent the wheel. “if this doesn’t end up in core, we’ll start rolling our own API for stuff. Others will too. Interoperability won’t be there, for even the most basic stuff. I think this isn’t like RSS, I think this is much more like all of us using the same table space in MySQL.”
      • @shelob9 and @masonjames agree that merging the endpoints would create a consistent and reliable open “standard” that WordPress developers can use instead of continually reinventing how to read and edit post data over HTTP.
      • In response to the question “what prevents you from building on the endpoints in their plugin form,” @joostdevalk went on to note that plugin dependencies would make that a viable option, but that burden currently lies on the user. Plugin installation is not frictionless.
    • Can these endpoints be bundled? short takeaway: no
      • Woo bundled the API infrastructure before it was merged; doing so for content endpoints would require bundling prohibitively large amounts of endpoint code.
      • @nerrad worries that if plugins bundle different versions of the endpoints plugin, then those plugins may conflict if all bundled copies are not kept in sync.
        • @nerrad clarifies in the comments below that these worries also encompass the additional risk of conflicts when plugin authors each build their own versions of these content endpoints, instead of leveraging a shared standard: if two plugins each expose their own REST collection for posts, a developer working on a site with multiple such endpoints will need to decide which to extend, and will then have their extension tied to that specific plugin rather than to a core API.
    • @schrapel and @jorbin discussed that these content endpoints make it much easier to crawl a site, which also brings some potential performance concerns: no new content is exposed, but the process of aggregating it is easier and more easily automated.
    • In the  comments below @foliovision believes that merging the endpoints will be the best way to assert the level of back-compatibility that mid-size agencies need in order to confidently utilize the endpoints.

    Please leave thoughts, questions, concerns, comments & experience in the comments below. Thank you!

    Edited 2016-10-16 to include the below comments into the body of the post

    • FolioVision 11:27 pm on October 13, 2016 Permalink | Log in to Reply

      Great discussion summary Adam. As the leader of a mid-size development agency, the sooner these endpoints are in core, the sooner we can start to use the REST API. For smaller to medium size clients, trying to play pin the tail on a donkey on a moving train (i.e. different versions of the REST API plugin, different versions of core) is simply not economically or technologically viable.

      As long as the REST API team can commit to retaining some backward compatibility if the API endpoints must change significantly in a couple of major releases, I can’t see any benefit to keeping REST API separate from core. So much great work has gone into creating the additional REST potential, it would be a shame to see it remain bottled up and a niche product only for huge agencies and hosts like VIP.wordpress.com or WordPress.com.

    • Josh Pollock 11:39 pm on October 13, 2016 Permalink | Log in to Reply

      One thing I wanted to add to this is that the REST API adds standards. I and many others have written tons of custom systems for alternative ways to read and edit post data using admin-ajax, or using custom rewrite rules.

      The constant reinventing of the wheal is counter to the spirit of open-source. By agreeing to a standard, with tons of eyes on it, we can all do better with greater efficiency and security. This after all is why we use WordPress and other open-source tools, instead of making our own CMSes.

      • masonjames 12:53 pm on October 14, 2016 Permalink | Log in to Reply

        I want to affirm this point as well. Our agency looks to WordPress (core) to provide an opinion. We value the decisions and respect them (even when we disagree).

        Web development is an incredibly competitive space with pressures in open source and otherwise. Having content end points in core ensures consistency and reliability across the WP community.

    • rag-guay 7:00 am on October 14, 2016 Permalink | Log in to Reply

      I would like to be able to edit widgets from the desktop app. So slow over the net from Thailand!

      • K.Adam White 12:58 pm on October 14, 2016 Permalink | Log in to Reply

        That’s a good point and I agree we need a solution for it. On behalf of the API Team, support for editing widgets is on the roadmap but is not part of what’s being proposed for merge this cycle. It is definitely a common request, and is one of our priorities for 4.8 as we expand the site management capabilities of the API!

        You can see some early experiments from earlier this year towards this usage here: https://github.com/WP-API/wp-api-menus-widgets-endpoints

    • Darren Ethier (nerrad) 10:46 am on October 14, 2016 Permalink | Log in to Reply

      Great summary! A lot of great back and forth in that discussion thread that isn’t always easy to capture 🙂

      Just wanted to clarify that the comments I made were not only in regards to the possibility of conflicts if plugin authors bundled the plugin version of the REST API with their own plugins, but also, with the presence of the infrastructure already in WordPress core, there is the possibility of conflicts should plugin authors roll their own different versions of the content endpoints to support what they are doing.

      Imagine plugin author A has used to api infrastructure in WP core to build custom endpoints for his plugin and his users are asking if he can add some endpoints for their posts, pages and users as well, so he goes ahead and does that. In the meantime, plugin author B has users asking her to build custom endpoints for users that support her needs as well so she adds them. Then along comes User Sally who installs and activates both plugins. She contracts mobile app developer Jimmy to build an app for her that interacts with both plugins and her website. Jimmy starts running into conflicts between what “user” endpoint to use but he manages to get it working. Then Sally tells Jimmy that she wants to distribute this app for anybody using plugin A or plugin B and Jimmy starts thinking about building a custom user endpoint in a plugin that site owners will need to install to use the app to save having to worry in the mobile app about what user endpoint to utilize.

      There are definitely different technical solutions to the above example story, but the reality is, things would be MUCH simpler for all the actors in the story above if there was an accepted standard in WordPress core for the content endpoints. It prevents a lot of problems from occurring.

    • K.Adam White 1:00 pm on October 14, 2016 Permalink | Log in to Reply

      If I may make a request of the developer community: Share this with your colleagues and friends outside of WordPress. See what they like, and what they find rough; let us know what they think! We’ve been gathering outside input on this but for more is always better.

    • Mike Schroder 6:03 pm on October 14, 2016 Permalink | Log in to Reply

      I noted this in the #core chat this week, but from my perspective at a host, we’re excited that landing the REST API will have performance benefits — in particular, because it will mean that we can cache requests that could only go through `admin-ajax` previously (and were thus forced to be dynamic).

      This will help with scaling even if it’s found that performance for the actual time in PHP/MySQL is exactly the same.

      Gradually moving those requests (whether they be core related, or added with plugins) out of `admin-ajax` will also help SysEng/Support more easily spot which requests are problematic.

      • Matt Mullenweg 1:15 am on October 18, 2016 Permalink | Log in to Reply

        It probably won’t have any real-world performance benefit — the admin-ajax benchmark was kind of flawed, and you won’t be able to do HTTP-level caching unless you also support some quite-fancy invalidation.

    • Luke Cavanagh 9:49 pm on October 14, 2016 Permalink | Log in to Reply

      I only see this as positive thing to be in WP core.

    • Brian Richards 2:21 pm on October 17, 2016 Permalink | Log in to Reply

      I’m late to the party but I want to officially register my voice in favor of merging the content endpoints into core.

      As @joostdevalk mentioned in Slack (and others have discussed elsewhere), there are a lot of opportunities to include API-based interactions within a plugin that are stifled presently because of the dependency on the REST API as a plugin. While it does seem like a small thing to inform end-users “This plugin requires the WP REST API plugin” it’s still a burden they needn’t bear. Further, by relegating the REST API to a plugin it stifles the ability for API-based interactions across many sites. For instance, a plugin that creates a widget that shows the most recent comments across a number of sites that you don’t control (e.g. getting the latest comments from a variety make/core inside a personal dashboard … and having the ability to bookmark certain comments or posts into a “read later” list for later consumption).

      As @getsource mentions above there are some fantastic wins by moving these interactions that currently depend on admin-ajax.php into standard, cacheable API calls.

      The most convincing dissenting opinion that gave me reason to pause was @JJJ‘s post that merging would hinder development. I do believe that is true. However, I also believe @rachelbaker is correct in that maintaining parity within the plugin as a long-term stand-alone is implausible. Given the choice between a REST API that can adapt and change quickly at the expense of dying slowly from a thousand cuts and a REST API that changes slowly but maintains perfect core parity I will pick the latter, every time.

      TL;DR: I really want to see the REST API land in core because I want to build some fantastic utilities (for myself and others) that can communicate with many sites without necessarily requiring administrative access (the ability to install the REST API plugin) within those sites.

    • K.Adam White 2:30 pm on October 17, 2016 Permalink | Log in to Reply

      I don’t think we’ve noted yet that the endpoints here don’t just encompass the built-in types, but also the endpoints that extend them — `WP_REST_Controller` provides a strong base for implementing new endpoints, and a custom post type with `show_in_rest => true` will automatically pick up behavior extending that class without any further action from the developer than a single line in `register_post_type`.

      Aside from the benefits of augmenting a shared resource like the posts collection @joostdevalk mentions above, having a sharable code foundation for new custom classes has the potential to reduce a lot of endpoint class duplication and fragmentation across the plugin ecosystem.

  • Helen Hou-Sandi 8:01 pm on October 12, 2016 Permalink |
    Tags: , ,   

    Dev Chat Agenda for October 12 (4.7 week 8) 

    This is the agenda for the weekly dev meeting on October 12, 2016 at 20:00 UTC:

    If you have anything to propose to add to the agenda or specific items related to the above, please leave a comment below. See you there!

  • K.Adam White 6:36 pm on October 12, 2016 Permalink |
    Tags: ,   

    REST API Team Update, 4.7 Week 8 

    Summary: Beta 15 has been released, there are open questions that would benefit from your feedback, and the Content API Endpoints and OAuth Server are being proposed for merge as distinct, separate enhancements to the existing WordPress REST API infrastructure.

    REST API v2 Beta 15 released

    The 15th beta release of the REST API content endpoints plugin was released on October 7. This release builds on top of the recent Beta 14 to…

    • Add support for Post Meta, Term Meta, User Meta and Comment Meta within their parent endpoints
    • Introduce a settings endpoint to allow key site setting values to be retrieved & modified using the API
    • Introduce query parameters to query for posts that are NOT IN one or many terms of specific taxonomies
    • Resolve bugs, including bad comparison logic when updating comments.

    Please try it out and report any outstanding issues; the REST API project gained its 90th code contributor this week and the team is deeply grateful for the energy and support of the broader WordPress community in testing out this merge-candidate plugin!

    New Questions & Discussion Items

    Items which have arisen through final ticket triage & review on which the team seeks feedback:

    1. Should the `filter` shim should be removed prior to merge? It is the majority position of the API team that `filter` be deprecated to dramatically improve the simplicity and consistency of API query functionality
    2. How should comments be handled for password-protected posts? Should the password be passed as a query parameter with the PUT/POST request, or is there a better option?
    3. Should the API match core’s logic when users with the `unfiltered_html` capability are creating or updating Posts or Comments?

    Meeting Notes

    At the weekly team meeting on October 10 the group reviewed open issues in the 2.0 milestone, which represents the candidate for our merge proposal shared last week.

    Meeting attendees agreed to review open issues and pull requests individually, and to reconvene on Tuesday at 1500UTC to ensure all priority tickets had an owner.

    At that meeting on October 11, the team reviewed the incoming feedback around the OAuth plugin (linked above). While the API team feels that having a built-in authentication solution provides a much-needed service, particularly to developers building mobile and desktop applications, the design and usability feedback we have received does indicate that the plugin needs more work.

    OAuth’s place in the Merge Proposal

    The API Team believes that the identified issues are resolvable, that the OAuth plugin is on track and that it should still be considered for merge in 4.7. However, after discussion within the team, input from @matt, and advice from @aaroncampbell and other core committers, we have edited our merge proposal to submit the Content API Endpoints and OAuth server as separate merge candidates. The API Team proposes both components for merge, but we submit the content endpoints for consideration independently of the OAuth1 server.

    Content Endpoints Without OAuth

    The Content API endpoints are stable, well-tested, and in wide production use across a variety of applications. Theme and plugin developers will benefit from having canonical, well-tested API endpoints in core, which may be used to query WordPress both from PHP code and from JavaScript applications running on the front-end or admin of WordPress. Sharing the endpoints for core data types enables increased consistency of what data is exposed and how it is persisted across different plugins, improving consistency and shortening development time by using . These themes and plugins have full read and write access to the API using the existing cookie & nonce authentication.

    Mobile and desktop applications can leverage these same endpoints in a read-only capacity to create a variety of powerful reader-oriented applications and tools that expand the capability of what WordPress can do today, such as a unified reader for Make WordPress blogs and other experiments hypothesized by @jorbin.

    Should OAuth 1 not be accepted for 4.7, secure write access for these external applications would still be only a plugin install away; and while having an OAuth server in core will provide a canonical approach for authenticating from remote applications, depending on the needs of a specific site or specific client application other authentication schemes may actually be preferable. Plugins exist for JWT Authentication and of course OAuth 2, and should OAuth 1 not be accepted for 4.7 these plugins may still be installed to enable an external application to opt-in to secure write access to your WordPress site.

    In Summary

    The API team submits for 4.7 merge consideration two enhancements to the REST API infrastructure: the Content API Endpoints for core WordPress datatypes, and an OAuth server which will reduce the setup time needed to securely interact with those endpoints from outside of WordPress. We believe these enhancements are each individually sufficiently tested and mature to meet the quality and security standards of WordPress Core, and each individually provides wide-reaching benefit to WordPress developers, and through them to the authors, readers & publishers of the web.

  • Mike Schroder 6:26 am on October 12, 2016 Permalink |
    Tags: , ,   

    Media Weekly Update (Oct 7) 

    This post serves to jump-start discussion before the weekly check in, which takes place in #core-images on Slack. The next meeting is Friday, October 14 at 17:00 UTC and agenda for these meetings includes moving priority tasks forward, providing feedback on issues of interest, and reviewing media focused tickets on Trac.

    Summary from last week

    The last meeting was Friday, October 7 at 17:00 UTC. You can read the entire chat log in the #core-images channel on Slack.

    Attendees: @karmatosed, @joemcgill, @mikeschroder, @swissspidy, @flixos90, @desrosj, @azaozz, @paaljoachim, @markoheijnen, @adamsilverstein, @jorbin, @designsimply

    • Media organization improvements:
      • @joemcgill opened up conversation about a feature project to start work on this, explaining that we have the chance to take a UI/UX first approach.
      • @karmatosed is going to head up the UI/UX side of things.
      • @joemcgill thinks the likely first step is exploration of base taxonomy support, and a review on how it is currently broken with media.
      • @karmatosed asked all those interested in working on this to create sketches of their ideal media categorization flow for review by next week.
    • Add new core media widget (#32417)@joemcgill noted that the runway for 4.7 is ending, but work can continue for a future release. @designsimply to refresh the current patch on the ticket by Monday (October 10), and may target images specifically as a first step (this is still missing a refreshed patch).
    • Rotate Full Size Images on Upload (#14459)@mikeschroder profiled this and found that while the clock time for checking and setting orientation is minimal, it took ~230ms for an iPhone 7-sized image to be rotated (total 5.6s resize time) on a shared test server. He thinks total resize time should be reduced before this is added, and that #37140 is a better step for 4.7. After discussion with @markoheijnen and @azaozz, consensus seems to be that benchmarking of upload vs manual rotation should be done to prove the UX case for #37140 over #14459.
    • Accents in attachment filenames should be sanitized (#22363)@joemcgill pointed out the new patch here from @gitlost, which looks promising. @swissspidy to take a look over the weekend (feedback is on ticket now, but could use more eyes).
    • Better PDF Upload Management (#31050) – Everyone likes this, but time running out for 4.6. @markoheijnen to target next patch by Wednesday (Oct 12) (this was moved out of the milestone, as it’s currently missing a refreshed patch).
    • Responsive images (srcset) can include images larger than the full size (#36477)@mikeschroder didn’t have time to performance test the patch. To do so shortly and post feedback on the ticket (feedback is on ticket now).

    Agenda for the next meeting

    This week, discussion will continue on priority projects for the 4.7 release. If you have specific tickets that you want to have discussed, feel free to leave a comment on this post or reach out on Slack in the #core-images channel.

    Edit: Updated post per status on Wednesday, Oct 12.

  • Weston Ruter 5:29 am on October 12, 2016 Permalink |
    Tags: , ,   

    Customize Changesets Technical Design Decisions 

    This is a technical deep-dive into Customize Changesets (#30937), a proposed feature formerly known Customizer Transactions. Because changesets make some very low-level changes to how the customizer works, I felt it was important for these technical details to be shared concurrently with a 4.7 merge proposal since developers of themes and plugins that extend the customizer heavily will need to be well advised of the changes. As such, again, this is a long and technical post. Consider it a pre-merge dev note.

    Feedback on the transactions/changesets idea has been positive although somewhat quiet. After the initial patch and the Customize Snapshots feature plugin, there is now a third iteration on the patch, which is currently in testing and review, and I believe it will be ready for inclusion in WordPress 4.7. I’ll first recap the customizer in general and then explain how changesets will open up a lot of new possibilities for live preview and also fix a lot of defects while we’re at it.

    The customizer is WordPress’s framework for doing live previews of any change on your site. Its purpose is to eliminate the “save and surprise” behavior that happens when making changes in the WP admin. All changes you make in the customizer are transient and nothing impacts the live site until you hit the Save & Publish button. A user can feel free to experiment with making changes to their site and be secure in the knowledge that they aren’t going to break their site for visitors since they can preview the impacts of their changes. A very powerful aspect of the customizer is that you can make as many changes to as many settings as you want, including changing the site title, header image, background image, nav menu, widgets, and other aspects of your site, and all of these changes are previewed together and will go live together when published: changes in the customizer are bundled/batched together.

    The TL;DR for this post is that customize changesets make changes in the customizer persistent, like autosave drafts. For users, the customizer tab can be closed and re-opened and the changes will persist. Users can make changes to one theme and switch to another in the customizer without losing the changes upon switching. A customizer session can be bookmarked to come back to later or this URL can be shared with someone else to review and make additional changes (the URLs expire after a week without changes). The new APIs make possible many new user-facing features in future releases and feature plugins, including saving drafts, submitting changesets as pending for review, scheduling changes, and more.

    Limitations before Changesets (WP≤4.6)

    In saying that unsaved changes made in the customizer (before changesets) are transient, I did not mean that they somehow get saved in an actual transient. No, they are much more ephemeral than that. Changes in the customizer currently only exist in your browser’s memory. If you try leaving the customizer with unsaved changes you get prompted with an “Are you sure?” (AYS) dialog because once you leave customize.php all of the changes you made will be permanently lost. This issue is especially painful in the context of switching themes in the current customizer: if you modify the site’s title and static front page and then try switching to a different theme, that AYS dialog will appear and warn you that your changes will be lost (since switching a theme currently requires the customizer reload). Not a great user experience. (See #36485.)

    Since none of the changes made in the current customizer are persistent in any way, this also has implications for how changes are previewed. When a full refresh or selective refresh is done in the preview, all of the changed settings have to be sent with each request so that the customized state is available to the preview filters to apply in the response, and as such each request has needed to use the POST method. What this in turn has meant is that links in the preview can’t work normally. When you click a link the URL gets sent via postMessage from the preview to the parent frame and where an Ajax POST request is then made to that URL and the response is then written into an about:blank iframe window via document.write(). This causes a couple issues: JavaScript running in the preview will return /wp-admin/customize.php when looking at window.location as opposed to the expected URL; this largely prevents using JavaScript for URL routing, and it causes problems with JS libraries like jQuery UI (see #23225, #30028). Additionally, any REST API calls to GET data will not include the customized state applied in the responses (without hacky workarounds with _method).

    Fundamentals for Changesets

    The core concept being introduced in Customize Changesets is that the customized state for a given live preview session should be persistent in the database. Each time the customizer is opened a random UUID is generated to serve as the identifier for the changes in that session: the changeset. As soon as a change is made, the change setting value gets sent in an Ajax request to be written into a customize_changeset custom post type whose post_name is the UUID for the customizer session. Once the changes have been written into the changeset post, then any request to WordPress (including the the REST API) can be made with a customize_changeset_uuid query param with the desired UUID and this will result in the customizer being bootstrapped and the changes from that changeset being applied for preview in the response.

    The data from changesets is designed to be incorporated into the existing customizer API to maximize backwards compatibility. Namely, the way that the customizer obtains the customized state is by making calls to WP_Customize_Manager::unsanitized_post_values(). When there is a changeset associated with the given UUID, then the values from the changeset will serve as the base array that is returned by this method. If there is any $_POST['customized'] in the request, then it will be merged on top of this base array. Likewise, calls to $wp_customize->set_post_value() will also result in the supplied values being merged on top of underlying changeset data.

    Since a UUID query param is all that is needed to apply the customized state, this means that the customizer iframe can now just use the frontend preview URL with UUID query param directly in its src attribute and load the iframe window naturally, as opposed to using about:blank with a document.write(). Likewise, the UUID will also get added as a query parameter to customize.php itself via history.replaceState() which means you can freely reload the customizer and your changes will persist.

    The customize_changeset post uses the post_content to store the changed values in a JSON-encoded object, with the setting IDs as keys mapping to objects that contain the value and other setting params like type.A submitted setting value will only be written into the changeset if it passes the validation constraints, if the setting is recognized, and if the user can do the capability associated with the setting. An example changeset:

        "blogname": {
            "value": "My Blog",
            "type": "option"
        "twentysixteen::header_textcolor": {
            "value": "blank",
            "type": "theme_mod"

    You’ll note that the header_textcolor setting has a theme slug as a prefix. This is done so that changes to the theme mods won’t be carried over from theme to theme when switching between them in a customizer session. If you set the text color in Twenty Sixteen but then switch over to Twenty Seventeen to try changing colors there, you can then switch back to Twenty Sixteen in the same customizer session and the text color you set before the theme switch will be restored. Additionally, when activating a theme in the customizer and there are theme mods for other themes that do not get saved, these theme mods will get stashed in a customize_stashed_theme_mods option to then be restored the next time the theme is previewed in the customizer.

    The customize_changeset posts by default get created with the auto-draft status so that they will get automatically garbage-collected after a week of no modifications. When the Save & Publish button is pressed, a customize_save Ajax request will be sent with a status of publish for that post. When a customize_changeset post transitions to publish, the customizer will hook in to load the values from the changeset post into an active changeset and then iterate over each of the settings and save each one. Upon publishing, a changeset post will by default then get immediately trashed so that it will also get garbage-collected.

    Since transitioning a changeset post to the publish status is what causes its setting values to be saved, this means that setting changes can be scheduled (see #28721). Since setting values are only written into the changeset if they pass validation and authorization checks, the values can be saved asynchronously without a user with the required capabilities being logged in. An update to the site title can be scheduled for publishing even though no user with edit_theme_options will be logged-in when WP Cron runs. Here’s how this can be done with WP-CLI:

    wp post create \
        --post_type=customize_changeset \
        --post_name=$( uuidgen ) \
        --post_status=future \
        --post_date="2017-01-01 00:00:00" \
        --post_content='{"blogname":{"value":"Happy New Year!"}}'

    There is no new UI for changesets being proposed for 4.7 (other than the addition of the customize_uuid query param) and the removal of the theme switch AYS dialog. (Note that the AYS dialog remains for the customizer otherwise since there is no UI that lists changesets to allow the user to navigate back to that state.) Adding a UI for scheduling changesets to core can be explored in future releases.

    Extension Opportunities for Plugins

    There are also exciting new APIs that plugins will be able to leverage to create new UIs and extend functionality.

    • The show_ui flag on the custom post type can be turned on so that all changeset posts can be listed. When viewing the edit post screen for given changeset, a metabox can be added to show the contents of the changeset.
    • By adding adding support for revisions to the customize_changeset post type, published changesets will no longer be automatically trashed (and garbage-collected). With this there is automatic revisions and an audit trail for changes made in the customizer (see #31089).
    • A “Save Draft” button can be added next to “Save & Publish” that calls wp.customize.previewer.save({status: 'draft'}). This will prevent the changeset from being an auto-draft and thus garbage-collected.
    • Users could collaborate together on a single changeset with setting-level concurrency locking.
    • Normally when updating a changeset post, a revision is prevented from being created even when they are enabled. However, when making an update to a changeset via wp.customize.previewer.save() where the status is supplied (such as draft) then a new revision will be made. These revisions can be browsed from the edit post screen. Since the JSON in the post_content is pretty-printed, the diffs are easy to read.
    • The publish_posts meta capability for customize_snapshots post type can be overridden to something other than customize, and for users without the new capability a “Submit” button can be added to the UI to submit a changeset for review via wp.customize.previewer.save({status: 'pending'}).
    • Changesets can be scheduled for publishing from the customizer by hooking up a button to make a call like to wp.customize.previewer.save({status: 'future', date: '2017-01-01 00:00:00'}).
    • The customize_changeset post type supports title even though it is not displayed anywhere by default. A plugin could add a “commit message” UI for changesets where there could be a title could be entered in an input field and sent via wp.customize.previewer.save({status: 'draft', title: 'Add 2017 greeting'}).
    • The can_export flag can be turned on for the registered post type so that customize_changeset posts can be exported.

    Several of these features already exist in the Customize Snapshots plugin among several others, but the plugin is currently using its own standalone snapshots API with a customize_snapshot post type rather than re-using what is being proposed in 4.7 for core, as the plugin is a prototype for changesets in core. The plugin will be able to be refactored after changesets are committed to core, allowing a lot of code to be removed from it. I’ve also put together a couple of these UI features in a little Gist plugin.

    Selective Refresh and Seamless Refresh

    In the original proposal for “transactions”, I said that selective refresh was prerequisite for getting transactions/changesets into core. The reason for this is that the initial patch got rid of the PreviewFrame construct in the customizer JS API since I thought it was no longer necessary. I thought that a refresh should just be invoked simply with location.reload() in the iframe. The reason why I thought selective refresh was a prerequisite was that full page refreshes via location.reload() were not seamless due to a “flash of reloading content”. However, when working on the latest patch I grew to appreciate the approach of loading a new iframe in the background and hot-swapping with the foreground once loaded. And anyway, I realized there was no need to remove the “seamless refresh” functionality.

    Aside: Now that the iframe is loaded with a regular URL supplied in its src attribute, you can now manually refresh the preview iframe just like you would refresh any other iframe. Just context click (right click) on the preview frame and select “Reload Frame” from the context window.

    Frontend Preview

    Again, now that the customizer preview is loaded into the iframe via a regular URL, you can grab the value of the iframe[src] and actually open it in a separate window altogether and not have the customizer controls pane present at all. When you look at the preview URL from the iframe you’ll see the normal frontend URL you’re previewing along with three additional query parameters such as:

    • customize_changeset_uuid=598cdda1-b785-431d-8c6d-6c421300ed9f
    • customize_theme=twentysixteen
    • customize_messenger_channel=preview-1

    Only the first one, customize_changeset_uuid, is required to bootstrap the customizer and preview the state. The second one, customize_theme, must be supplied when previewing a theme switch. Otherwise, it can be omitted. And lastly, when the customize_messenger_channel param is present, the customizer preview will hide the admin bar and yield control of navigation to the parent frame: clicks on links and submitting forms will continue to preventDefault with the intended url destination being sent to the parent frame to populate wp.customize.previewer.previewUrl which then causes the iframe[src] to be set to that URL. Maintaining this method of navigation from the preview is important for compatibility with plugins that add custom params to the URL being previewed by intercepting updates to the previewUrl. When a changeset is published, a new UUID is sent in the response and it is sent to the preview in the saved message and it replaces the old UUID in the URL via history.replaceState(). Also note that calls to history.replaceState() and history.pushState() are wrapped so that the customize state query prams will be injected into whatever url is supplied. Whenever the URL is changed with JavaScript, the new URL will be sent to the parent frame along with the wp.customize.settings for the autofocused panels, sections, and controls. This allows for JS-routed apps to take control over contextual panels, sections, and controls.

    When the customize_messenger_channel query param is absent, then links can be clicked and forms submitted without any preventDefault. The admin bar will be shown and the Customize link will include the changeset UUID param. The customizer preview JS will ensure that the customizer state query params above will persist by injecting them into all site links and by adding them as hidden inputs to all site forms. If a link or form points to somewhere outside of the site (and is thus not previewable) then the mouse will get a cursor:not-allowed and wp.a11y.speak() will explain that it is not previewable (see #31517). The customizer preview will keep sending keep-alive messages up to the controls pane parent window so that if a user does end up getting routed to an non-previewable URL, the customizer controls pane will know that the preview is no longer connected and so when a setting with postMessage transport is modified it will intelligently fallback to using refresh instead.

    The way that REST API requests get the customized state included is via the jQuery.ajaxPrefilter(). If an Ajax request is made with a URL to somewhere on the site, then the customize state query params will be appended to the URL.

    Since changesets can only modified by an authorized user and since previewing is a read-only operation, the URL for the customize preview including the UUID can be shared with unauthenticated users to preview those changes. Since a UUID is random it serves not only as a unique identifier but it also effectively serves as a secret key so that such customizer previews cannot be guessed. Note that unauthenticated users would still be forbidden from accessing the preview URL if they supply a customize_theme that differs from the active theme, as they do not have switch_themes capability.

    Aside: Since the customizer preview can be loaded by itself in its own window, this opens the door to being able to use the customizer for frontend editing and bootstrapping the customizer while on the frontend.

    Another aside: The customizer should be able to point to a headless frontend to preview, as long as the frontend looks for the customize_changeset_uuid query param and passed it along in any REST API calls, while also including the customize-preview.js file.

    REST API Endpoints

    The initial changesets patch does not include REST API endpoints for the 4.7 release. However, there should be a feature plugin developed that adds endpoints for listing all changesets, inspecting the contents of a changeset, and the other CRUD operations. With these endpoints in place, entirely new customizer interfaces can be developed that have nothing to do with customize.php at all. Namely, mobile apps could create changesets and include the associated UUID in REST API requests for various endpoints to preview changes to the app itself. Some initial read-only endpoints were added to the Customize Snapshots plugin.

    Summary of API Changes


    • Added: The WP_Customize_Manager class’s constructor now takes an $args param for passing in the changeset UUID, previewed theme, and messenger channel. This $args param is intended to be used instead of global variables, although the globals will still be read as a fallback for backwards compatibility.
    • Changed: The query param for theme switches has been changed from theme to a prefixed customize_theme. This will reduce the chance of a conflict, although theme will still be read as a fallback.
    • Added: New custom post type: customize_changeset.
    • Changed: Modified semantics of WP_Customize_Manager::save() to handle updating a changeset in addition to the previous behavior of persisting setting values into the database.
    • Added: WP_Customize_Manager::changeset_uuid(), which returns the UUID for the current session.
    • Added: WP_Customize_Manager::changeset_post_id(), which returns the post ID for a given customize_changeset post if one yet exists for the current UUID.
    • Added: WP_Customize_Manager::changeset_data() which returns the array of data stored in the changeset.
    • Changed: WP_Customize_Manager::unsanitized_post_values() now takes parameters for whether to exclude changeset data or post input data. Also, post input data will be ignored by default if the current user cannot customize.
    • Added: customize_changeset_save filter to modify the data being persisted into the changeset.
    • Added: WP_Customize_Manager::publish_changeset_values() which is called when a customize_changeset post transitions to a publish status.
    • Added: Theme mods in a changeset which are not associated with the activated theme will get stored in a customize_stashed_theme_mods option so that they can be restored the next time the inactive theme is previewed.
    • Added: WP_Customize_Manager::is_cross_domain().
    • Added: WP_Customize_Manager::get_allowed_urls().
    • Added: wp_generate_uuid4(), a new global function for generating random UUIDs.
    • Changed: Settings are registered for nav menus and widgets even if the user cannot edit_theme_options so that a changeset containing values for them can be previewed.
    • Deprecated: WP_Customzie_Manager::wp_redirect_status().
    • Deprecated: WP_Customize_Manager::wp_die_handler().
    • Deprecated: WP_Customize_Manager::remove_preview_signature().


    • Added: wp.customize.state('previewerAlive') state containing a boolean indicating whether the preview is sending keep-alive messages.
    • Added: wp.customize.state('saving') state containing a boolean indicating whether wp.customize.preview.save() is currently making a request.
    • Added: wp.customize.state('changesetStatus') state containing the current post status for the customize_changeset post.
    • Added: wp.customize.requestChangesetUpdate() method which allows a plugin to programmatically push changes into a changeset. This allows additional params to be attached to a given setting in a changeset aside from value, and it also allows settings to be removed from a changeset altogether by sending null as the setting params object.
    • Added: changeset-save event is triggered on wp.customize with the pending changes object being sent to to the server.
    • Added: changeset-saved event is triggered on wp.customize when a changeset update request completes successfully, with a changeset-error event triggered on a failure.
    • Added: changeset-saved message is sent to the preview once a changeset has been saved so that JS can safely make make REST API request with the customized state being available.
    • Added: The millisecond values used in debounce and setInterval calls are now stored in wp.customize.settings.timeouts rather than being hard-coded in the JS.
    • Changed: Seamless refreshes will wait for any pending changeset updates to complete before initiating.
    • Changed: The beforeunload event handler for the AYS dialog now has a customize-confirm namespace.
    • Added: Settings for the changeset are exposed under wp.customize.settings.changeset, including the current UUID and the post status.
    • Moved: wp.customize.utils has been moved from customize-controls to customize-base.
    • Added: wp.customize.utils.parseQueryString() to parse a query string into an object of query params.
    • Fixed: Prevent modified nav menus from initiating selective refresh with each page load when customizer is loaded via HTTPS.
    • Fixed: Links in the preview that are just internal jump links no longer have preventDefault called. See #34142.
    • Added: wp.customize.isLinkPreviewable() to customize-preview which returns whether a given link can be previewed.


    The work on transactions/snapshots/changesets has been going on for almost 2 years now. I want to thank Derek Herman (@valendesigns) for a lot of his work on the Customize Snapshots plugin that took the key concepts from the initial transactions proposal and started to combine them with a lot of compelling user-facing features.

    I hope that changesets will make the Customize API all the more powerful to build compelling cutting-edge applications in WordPress.

    • Ahmad Awais 6:24 am on October 12, 2016 Permalink | Log in to Reply

      Wow! That was a long read. Thanks a lot for documenting it, Weston. Will come in handy.

    • Matthew Taylor 6:24 am on October 12, 2016 Permalink | Log in to Reply

      This is great! As a front end developer, not all of my clients have more than just their one site and are sometime looking for simple changes. Being able to use a native WP feature on sites to preview customizations for a client would be invaluable. I have worked with the current customizer api to extend features for theme to provide live feedback on changes. I found it a little cumbersome to code for without that much return on investment time-wise. This would make coding for the customizer worth the time and effort.

    • NateWr 8:24 am on October 12, 2016 Permalink | Log in to Reply

      Thanks for all your work on this Weston (and Derek). It will take me a while to get to grips with all of this, but I think it could be a real sea-change in how WP sites are built and managed.

    • Per Søderlind 8:24 am on October 12, 2016 Permalink | Log in to Reply

      nice nice nice !

    • Jonathan Bardo 2:53 pm on October 12, 2016 Permalink | Log in to Reply

      Thank you Weston, you rock! This opens the door to so many things!

  • Weston Ruter 5:29 am on October 12, 2016 Permalink |
    Tags: , , ,   

    Customize Changesets (formerly Transactions) Merge Proposal 

    This is a merge proposal and overview of Customize Changesets (#30937), a project formerly known and proposed as Customizer Transactions back in January 2015. The customizer is WordPress’s framework for doing live previews of any change on your site. One of the biggest problems the customizer faces right now is that changes are ephemeral. If you navigate away, you lose what you are working on. Additionally, you can not share proposed changes with others, nor can you take the changes you are working on and save to continue working later.

    Imagine a WordPress user named Tina. Tina is building a website for her daughter’s band. The band has been getting more and more popular, and Tina wants to experiment with some new widgets in the sidebar but also wants to be able to share the proposed solutions with her husband Matthew. Right now, Tina and Matthew would need to be in the same room to collaborate. Or Tina would need to take screenshots, but that kind of defeats the purpose of live preview. If only there was a way to make customizer changes persistent without publishing them.

    Introducing Customize Changesets

    Customize changesets make changes in the customizer persistent, like autosave drafts. Users can make changes to one theme and switch to another in the customizer without losing the changes upon switching. A customizer session can be bookmarked to come back to later or this URL can be shared with someone else to review and make additional changes (the URLs expire after a week without changes). The new APIs make possible many new user-facing features in future releases and feature plugins, including saving long-lived drafts, submitting changesets as pending for review, scheduling changes, seeing the previewed state on the frontend without being in an iframe, sharing preview URLs with others who do not have customizer access, and others.

    Customize changesets allow each change you make in the customizer for a given live preview session to be persistent in the database. A unique identifier (a UUID like f67efbbf-c663-4271-ab1c-95ce1d447979) for each live preview session is generated and as soon as a change is made, the change setting value is sent in an Ajax request to be written into a custom post type whose post_name is the UUID for the customizer session. Once the changes have been written into the changeset post, then any request to WordPress (including to the REST API) can be made with a customize_changeset_uuid query param with the desired UUID and this will result in the customizer being bootstrapped and the changes from that changeset being applied for preview in the response. The unique UUID means that customizer sessions can be sent to other users and also that they can be used as query parameters on the front end.

    Design and Technical Decisions

    For the initial core merge, no UI changes are being proposed. The feature will be only be exposed as the new query parameter on the URL. Adding a UI to this feature will happen in a future release. As such, the proposal for customize changesets is similar to the proposal for including the REST API infrastructure: it provides a foundation for new core features in future releases and a platform for plugins to add new features. Nevertheless, while the customize changesets patch doesn’t introduce any new features it does fix several long-standing issues related to incompatibilities between JavaScript running on the site’s frontend when previewed in the customizer. Under the hood, the customize changesets patch touches on many of the lowest level pieces of the customizer. Please check out the Customize Changesets Technical Design Decisions to see what is happening under the hood.


    Please test! If you use any plugins that extend the customizer, please ensure that there aren’t any regressions. The patch is intended to be fully backwards compatible and users shouldn’t notice any difference in normal use. Two things to look for when testing is as soon as you make a change, you should see a customize_uuid query param added to the URL. You should be able to reload and find your changes persist (note the AYS dialog is retained because there is no UI yet for listing changesets). Also, when you navigate around the preview it should feel much more natural like normal browsing as opposed to having a fade effect. Otherwise, previewing settings that require refresh should still work as normal, as will settings that preview with JavaScript and selective refresh.

    The patch is in a GitHub pull request and you can apply the patch via:

    grunt patch:https://github.com/xwp/wordpress-develop/pull/161

    If you’re using the Git repo from develop.git.wordpress.org then you can check out the branch directly via:

    git remote add -f xwp https://github.com/xwp/wordpress-develop.git && git checkout xwp/trac-30937

    I’d appreciate code review feedback directly on the pull request. For any revisions to the patch, please open a pull request to that trac-30937 branch if possible.

    The Future

    In future releases we can explore new UIs to take advantage of the new capabilities that changesets provide. New UIs can provide a way to schedule changes, the ability to undo the last change, show an audit log (revision history) for changes, collaborative editing of a customizer changeset, and so on. Future feature projects will explore many of these and feature plugins will start to prototype them.

    Thanks to @jorbin who contributed to this proposal post.

    • Dominik Schilling (ocean90) 8:34 pm on October 12, 2016 Permalink | Log in to Reply

      The customizer needs this to get rid of some odd limitations and to provide a more “native” live-preview feeling. +💯 from me.

    • Ahmad Awais 10:06 pm on October 12, 2016 Permalink | Log in to Reply

      ^What Dominik said! +1 for Customize Changeset.

    • Philip Ingram 7:41 pm on October 19, 2016 Permalink | Log in to Reply

      Love this idea. Curious to see how this can be applied to team development workflows to the live css topic we’ve been discussing

      • Weston Ruter 10:59 pm on October 19, 2016 Permalink | Log in to Reply

        @pingram3541 you can collaborate on the CSS now by making a change, copying the customizer URL with the changeset_uuid query param intact, sending the URL to a colleague, your colleague can make some changes, and then you can reload the customizer on your end and their changes will be visible on your end for additional changes. Note that the changeset is autosaved every 60 seconds or whenever focus is removed from the customizer window (or when it is unloaded). Eventually there should be a “Save Draft” button to proactively save the state (#31089), and there should also be support for concurrency locking (#31436).

        • Philip Ingram 2:40 pm on October 20, 2016 Permalink | Log in to Reply

          @westonruter Thanks Weston this is really great stuff. I often help other devs where css is not their strength and this is a perfect way for me to suggest an edit and let them preview it without actually applying the changes on the public side. I could see a great use case for an enhancement plugin to provide diffs revealing the proposed changes even more clearly

  • Helen Hou-Sandi 5:58 pm on October 11, 2016 Permalink |
    Tags: ,   

    The Road to 4.7 Beta 1 

    For the last 55 days, trunk has been in an alpha state and open for all commits. In 15 days this will change and the first beta for 4.7 will be released. During beta, no new enhancements or feature requests should be committed to WordPress core. While some may desire to wait for just one more thing, that is a rabbit hole which is inconsistent with the WordPress philosophies. Here is a list of things that need to happen during the next 15 days in order to get ready for Beta 1 on October 26th.

    The deadline for merging feature projects into WordPress core is in 8 days. There are currently three proposals for projects to merge published with several additional proposals actively being worked on. All committers and active contributors should review these proposals (I’ll add links to additional proposals when they are made):

    There are 60 enhancements and feature requests milestoned for 4.7.  Of these, 21 have no owner.  At the end of this week, all enhancements and feature requests without an owner will be punted.  Tickets will also be regularly evaluated this week.  Over the next two weeks, tickets will be evaluated during both scheduled and unscheduled bug scrubs, and tickets not moving forward will be removed from the milestone. The next scheduled bug scrub will be at Wednesday, October 12, 2016 17:00 UTC.

    During this week’s dev chat, we will discuss all the proposals that have been made thus far. If additional meetings for considering any of the proposals before the merge deadline are needed, this will be decided then.

compose new post
next post/next comment
previous post/previous comment
show/hide comments
go to top
go to login
show/hide help
shift + esc
Skip to toolbar