Ready to get started?Download WordPress

Make WordPress Core

Updates from Ryan McCue Toggle Comment Threads | Keyboard Shortcuts

  • Ryan McCue 7:08 am on April 14, 2014 Permalink | Log in to leave a Comment

    JSON REST API: Meeting Time Change 

    As announced on the team o2, the meeting time for the API team is changing to Tuesday, 0:00 UTC, in #wordpress-dev.

    This week we’re discussing OAuth (which, P.S., is now available for testing), 1.0 and custom post type data privacy.

    Hopefully I’ll see you there!

  • Ryan McCue 2:12 am on April 14, 2014 Permalink | Log in to leave a Comment
    Tags: , , , symlinks   

    Symlinked Plugins in WordPress 3.9 

    One of the cool little features included with 3.9 is the ability to symlink plugin directories. While it has been possible to symlink plugins in the past, functions such as plugins_url() return the wrong URL, which causes breakage in most plugins.

    In #16953, r27158 and the followup r27999, we corrected this with the help of a new function: wp_register_plugin_realpath(). This function is called automatically during the plugin loading phase, and registers which plugin directories are symlinked, and where they’re symlinked to. This functionality is then used by plugin_basename() (the core of plugins_url(), along with other
    functions) to reverse symlinks and find the correct plugin directory.

    This enhancement means that you can symlink individual plugin directories, or even the whole plugins directory itself.

    For anyone who’d like to use this, keep in mind that there are a few caveats:

    • Single-file plugins are not handled by this code. Any plugins you’d like to symlink must be in subdirectories of the main plugins folder. This restriction is due to the way these paths are registered.

      You can still symlink single-file plugins, however any use of plugin_basename() will be as broken as it was before 3.9. This is not a huge issue, as the main use of this is in plugins_url(), which is not frequently used in single-file plugins.

    • Must-use plugins cannot be symlinked. For the same reasons as single-file plugins, mu-plugins are not handled.

      For anyone using the common pattern of subdirectories within mu-plugins with a common loader file, you can use wp_register_plugin_realpath() directly to ensure that your subdirectories are handled.

      The following example code demonstrates how to use the function:

      $plugins = array(
      foreach ( $plugins as $plugin ) {
      	$path = dirname( __FILE__ ) . '/' . $plugin;
      	// Add this line to ensure mu-plugins subdirectories can be symlinked
      	wp_register_plugin_realpath( $path );
      	include $path;

      Hopefully this change is as helpful for you as it was for me! One of the great advantages to this is that plugin developers can keep their plugin separate from their WordPress installation. This is a boon for developers with multiple installs who want to test compatibility; keep in mind that you can symlink the entire plugins directory if you're testing multiple!

      If you have any questions about this, please leave a comment on this post and we'll be happy to help you out!

    • PeterRKnight 2:29 am on April 14, 2014 Permalink | Log in to Reply

      This is super handy

    • Mike Schinkel 4:25 am on April 14, 2014 Permalink | Log in to Reply

      Kudos Ryan for pushing that feature through.

    • Julien 6:50 am on April 14, 2014 Permalink | Log in to Reply

      That’s great news! Thanks!

    • Fab1en 7:36 am on April 14, 2014 Permalink | Log in to Reply

      Thanks for this Ryan !
      I was using a custom plugin that tweaked `plugin_basename` to make it work with symlinked plugins. Thanks to you, I will not need this plugin anymore !

    • klihelp 12:37 pm on April 14, 2014 Permalink | Log in to Reply

      Thanks for the post.

      >> This is a boon for developers with multiple installs who want to test compatibility
      Tell me more about this.
      Could I read as a multiple WP installs uses the same plugin directory, so you don’t have multiple copies of the plugins?

      • Fab1en 3:42 pm on April 15, 2014 Permalink | Log in to Reply

        yes, that is what you can read ! Just add a symlink to a shared plugins directory in each WP install wp-content folder, and your installs will share the same plugins copy.

    • hinnerk 3:06 pm on April 14, 2014 Permalink | Log in to Reply

      Thanks a lot! Great enhancement! Makes my developer live much easier!

    • Frank 3:18 pm on April 14, 2014 Permalink | Log in to Reply

      Really useful, reduce the custom work.

    • Brian Layman 3:44 pm on April 14, 2014 Permalink | Log in to Reply

      This is a neat little thing. We’d experimented with symlinking the files back in b5media days with our 350ish sites, but there were enough little oddities to make it not the right choice for a poor man’s MU option.

    • Primoz Cigler 5:33 pm on April 14, 2014 Permalink | Log in to Reply

      Very important and useful update. But I have a question: is something like this possible with the themes as well? Would make perfect sense for the same reason, if you are a theme developer: “One of the great advantages to this is that theme developers could keep their theme separate from their WordPress installation. This is a boon for developers with multiple installs who want to test compatibility; keep in mind that you could symlink the entire themes directory if you’re testing multiple!”

      • Ryan McCue 2:12 am on April 17, 2014 Permalink | Log in to Reply

        But I have a question: is something like this possible with the themes as well?

        I can’t think of any issues with allowing this; file a ticket on Trac! :)

    • Primoz Cigler 5:34 pm on April 14, 2014 Permalink | Log in to Reply

      This is very important and useful update. But I wonder if something similar would be possible with the themes too? For the same obvious reasons as for plugins.

    • hinnerk 7:25 am on April 15, 2014 Permalink | Log in to Reply

      I had to add Options +FollowSymLinks to my .htaccess in order to remove a 403 Forbidden on all pages (using symlinks in plugins directory).

    • hinnerk 7:27 am on April 15, 2014 Permalink | Log in to Reply

      I had to add Options +FollowSymLinks to my .htaccess to remove a 403 Forbidden on all pages (using symlinks in /wp-content/plugins/).

    • Todd Lahman 8:45 am on April 15, 2014 Permalink | Log in to Reply

      This is totally awesome!

    • elimc 7:00 pm on April 16, 2014 Permalink | Log in to Reply

      I’m a bit confused about what this future does. Does this allow me to define a constant on my local server that links to the plugin directory on remote sites, thereby, preventing the need to duplicate the same plugins on both the local and remote server?

      • Ryan McCue 2:13 am on April 17, 2014 Permalink | Log in to Reply

        This doesn’t allow you to share plugin files across HTTP, no. It does allow you to have certain plugins live outside of your WordPress content directory, which means you can share the same code between multiple installations on the same server.

    • experiencedbadmom 11:39 pm on April 17, 2014 Permalink | Log in to Reply

      Total newbie here. I blog as a hobby. I do not know code. I updated to 3.9 today and now ALL I get is this error message:

      Fatal error: Call to undefined function wp_register_plugin_realpath() in /home/content/92/8889792/html/wp-settings.php on line 213

      I can’t get to my login page or see my blog anymore. I found this thread by searching “Fatal error: Call to undefined function wp_register_plugin_realpath()”. Any advice would be greatly appreciated to restore my blog! Thank you.

      • Ryan McCue 11:26 am on April 18, 2014 Permalink | Log in to Reply

        This sounds like your site didn’t fully update correctly. :( Try doing a manual update instead, hopefully that fixes it :)

        • experiencedbadmom 11:57 am on April 18, 2014 Permalink | Log in to Reply

          Thank you for the link to the manual instructions. My blog is experiencedbadmom.com tho, not experiencedbadmom.com/wordpress/ – does that matter? Also, one of the steps says to deactivate plugins – how do I deactivate plugins if I can’t even get into my dashboard? GoDaddy is my host – do I deactivate plugins somewhere on their servers?

  • Ryan McCue 6:49 am on April 6, 2014 Permalink | Log in to leave a Comment

    JSON REST API: Version 0.9 

    Hi everyone! I’m happy to announce that version 0.9 of the JSON REST API is finally available.

    Apologies for the extremely long delay here. I would have liked to ship OAuth authentication with 0.9, and the release was delayed due to that. However, it’s still not in a shippable state, and we’re well overdue for a release.

    Important note: There are backwards compatibility breaks and deprecations in this release. These are all listed before, but exercise caution in upgrading. Backwards compatibility will be maintained from 1.0 onwards only.

    Here’s the big changes:

    • Move from wp-json.php/ to wp-json/

      This breaks backwards compatibility and requires any clients to now use wp-json/, or preferably the new RSD/Link headers.

      (props @rmccue, @matrixik, #46, #96, #106)

    • Move filter registration out of CPT constructor. CPT subclasses now require you to call $myobject->register_filters(), in order to move global state out of the constructor.

      This breaks backwards compatibility and requires any subclassing to now call $myobject->register_filters()

      (props @rmccue, @thenbrent, #42, #126)

    • Introduce Response/ResponseInterface

      Endpoints that need to set headers or response codes should now return a WP_JSON_Response rather than using the server methods. WP_JSON_ResponseInterface may also be used for more flexible use of the response methods.

      Deprecation warning: Calling WP_JSON_Server::header, WP_JSON_Server::link_header and WP_JSON_Server::query_navigation_headers is now deprecated. This will be removed in 1.0.

      (props @rmccue, #33)

    • Change all semiCamelCase names to underscore_case.

      Deprecation warning: Any calls to semiCamelCase methods require any subclassing to update method references. This will be removed in 1.0.

      (props @osiux, #36, #82)

    • Add multisite compatibility. If the plugin is network activated, the plugin is now activated once-per-site, so wp-json/ is always site-local.

      (props @rachelbaker, #48, #49)

    • Add RSD and Link headers for discovery

      (props @rmccue, #40)

    • WP_JSON_Posts->prepare_author() now verifies the $user object is set.

      (props @rachelbaker, #51, #54)

    • Added unit testing framework. Currently only a smaller number of tests, but we plan to increase this significantly as soon as possible.

      (props @tierra, @osiux, #65, #76, #84)

    As always, you can view all changes on GitHub as well as view all closed tickets.

    For those interested, here’s the list of contributors to this release:

    $ git shortlog 0.8... --summary
         1  Aaron Jorbin
         1  Anders Lisspers
         6  Bryan Petty
         1  Dobrosław Żybort
         7  Eduardo Reveles
         1  K.Adam White
        10  Rachel Baker
        41  Ryan McCue
         2  Taylor Lovett

    I’m still desperately seeking feedback on our OAuth implementation. This is a hugely important part of the API, and we need to get this nailed down as soon as possible.

    General comments and posts are always welcome on our team o2.

  • Ryan McCue 1:54 pm on December 14, 2013 Permalink  

    JSON REST API: Version 0.8 

    Hi everyone! Sorry about the late release, I’ve been a bit sick for most of the week, which has helped my blogging abilities but hindered my coding abilities. In any event, version 0.8 of the JSON REST API is now available.

    As always, here’s what’s changed:

    • Add compatibility layer for JsonSerializable. You can now return arbitrary
      objects from endpoints and use the jsonSerialize() method to return the data
      to serialize instead of just using the properties of the object.

      (props @rmccue, #24)

    • Fix page parent links to use /pages

      (props @thenbrent, #27)

    • Remove redundant WP_JSON_Pages::type_archive_link() function

      (props @thenbrent, #29)

    • Removed unneeded executable bit on all files

      (props @tierra, #31)

    • Don’t include the featured_image property for post types that don’t
      support thumbnails

      (props @phh, #43)

    • Use wp_json_server_before_serve instead of plugins_loaded in the Extending
      documentation for plugins

      (props @phh, #43)

    • Parse the avatar URL from the get_avatar() function in core, allowing custom
      avatar implementations

      (props @rachelbaker, #47, #35)

    • Ensure that the author is set if passed

      (props @kuchenundkakao, #44)

    • Clarify the usage of WP_JSON_CustomPostType in plugins

      (props @rmccue, #45)

    • Ensure JSON disabled error messages are translated

      (props @rmccue, #38)

    • Remove extra “Link: ” from link headers

      (props @jmusal, #56, #30)

    • Remove redundant get_avatar method in WP_JSON_Posts

      (props @rachelbaker, #35)

    • Rename WP_JSON_Server::get_avatar() to WP_JSON_Server::get_avatar_url()

      (props @rachelbaker, #35)

    You can also check out the full list of changes. We had seven contributors to this release, and I’d like to thank everyone who helped us, including creating support issues in the forum.

    The big change this week is the introduction of JsonSerializable support for all versions of PHP. This allows more complex APIs to return full objects and ensure that no data leaks via the API. This should help with reuse of the API internally, as you can now return objects with methods, private data, etc. It’s also a key stepping stone towards adding response objects, which should land in version 0.9.

    For those that have been following along, you may notice that OAuth authentication has been bumped to 0.9. The implementation of OAuth has been a bit of a thorny one, so we’re still deciding some of the implementation for this. Given the size and scope of authentication, we don’t want to rush anything this important. That said, however, I’m aiming to push out both versions 0.9 and 1.0 in the next week to meet our Christmas deadline for version 1.0. This will result in a bit of rescheduling, but shouldn’t be a major concern.

    We’re also desperately seeking help with testing the plugin. Unfortunately, while many of us are familiar with unit testing and can write the tests easily, the framework for doing so is evading us. If anyone can help us set up a testing framework, your help would be greatly appreciated.

  • Ryan McCue 7:00 am on December 2, 2013 Permalink

    JSON REST API: Version 0.7 

    Apologies for the delay on this one, but it’s here now: version 0.7 of the JSON REST API! Go download it now. This is mainly a bugfix release to catch up on all the unreleased items:

    • The response handler object is now passed into the endpoint objects via the constructor, allowing you to avoid excess global state where possible. It’s recommended to use this where possible rather than the global object.

      (props @rmccue, #2)

    • Fix undefined variables and indices
      (props @pippinsplugins, #5)
    • Correct call to deactivation hook
      (props @ericpedia, #9)
    • Check metadata access correctly rather than always hiding for users without
      the edit_post_meta capability
      (props @kokarn, #10)
    • Return all term metadata, rather than just the last one
      (props @afurculita, #13)
    • Access post metadata from cache where possible – Note, this is a backwards compatibility break, as the format of the metadata has changed. This may change again in the near future, so don’t rely on it until 1.0.
      (props @afurculita, #14)
    • Add term_link to prepare_term
      (props @afurculita, #15)
    • Fix hardcoded /pages references in WP_JSON_CustomPostType
      (props @thenbrent, #26)
    • Sanitize headers for newlines
      (props @kokarn, #7)
    • Register rewrite rules during plugin activation
      (props @pippinsplugins, #17)

    (As you can see, we had 6 separate contributors to this release, with 3 team members also reviewing and merging code. Thanks to everyone who was involved with this release!)

    We’ve also got some future plans, which I’d like to share with you guys now if you haven’t seen them previously (you’re always welcome over at the team o2). This slightly delayed release is a catch-up release, and we’re planning on hitting 0.8 this week, then 0.9 on December 11th and 1.0 on December 18th. We’ll then be taking a short break over Christmas, and letting the code settle for a bit.

    The 1.0 release will freeze our (internal PHP and external JSON) core API, with any future changes to be completely backwards compatible. This should coincide with the 3.9-early stage, and we’ll be able to get underway on core integration discussions with this backwards compatibility policy.

    The big feature we’re working on now is authentication. After much discussion, we’ve decided that OAuth 1.0a is really the only way to go here. While Basic authentication is nice and simple, it doesn’t give us any sort of CSRF protection, which is a blocker. Luckily for us, WooCommerce has recently added a JSON REST API (based on this project; giant props to Max Rice for his effort and feedback here) and implemented OAuth, so I’m working on porting this back upstream. This should hopefully land in 0.8 (this week) or 0.9 (next week).

    As always, if you want to get involved, head on over to our team o2. Now that we’re established, comments have been opened to all, and you’re welcome to suggest new topics via the form too!

    • Andrew Nacin 2:40 pm on December 2, 2013 Permalink | Log in to Reply

      The 1.0 release will freeze our (internal PHP and external JSON) core API, with any future changes to be completely backwards compatible.

      This is a noble idea, but how does it affect merger? Things are going to need to change based on additional feedback and eyes. I would not make this promise in any plugin specifically built to be included in core, until core actually merges it. The work here being done is fantastic. I’ve kept an arms length to let others influence direction, but at some point, I and other lead developers are going to need to roll up our sleeves and dive in. I just don’t want this to handcuff us. If this policy is to apply to the plugin only, that’s fine.

      • Ryan McCue 8:53 pm on December 2, 2013 Permalink | Log in to Reply

        To clarify, yes, this applies to the plugin only and does not affect merge. Here’s how I see it playing out:

        • We hit 1.0, and internal API freezes. Any future changes have backwards compatibility.
        • Merge begins and the plugin is branched twice: once for the merge candidate, and once for the last major version.
        • The prefix is changed in the merge candidate branch (likely from `json_` to `api_` and `WP_JSON_` to `WP_API_`)
        • The core team begins suggesting changes for merge, and those are implemented in the merge candidate branch
        • The merge candidate branch is merged into core, hurray!
        • The last major version is changed to become a backwards compatibility shim for the core version. Anyone who wants to use the plugin right now can continue using it with no change to prefixes/etc, but using the new code actually in core.
        • The plugin version eventually dies out.

        Maintaining the compatibility shim might be hard, but it offers huge guarantees to users that outweigh that. Plus, who doesn’t love a challenge. :)

    • Mte90 2:30 pm on December 27, 2013 Permalink | Log in to Reply

      Why use OAuth 1.0a instead of 2?
      The 1.0a is not widely used, even the big names like Google, Microsoft and Facebook support it anymore!

      • Ryan McCue 7:41 am on December 28, 2013 Permalink | Log in to Reply

        Unfortunately, OAuth 2 isn’t a replacement for OAuth 1.0a, as it only works on SSL-enabled sites. We can’t guarantee that we have SSL on every site, so OAuth 2 is out of the question.

    • Dave Navarro, Jr. 5:45 pm on February 23, 2014 Permalink | Log in to Reply

      Are you still on 0.7? I see you were hoping to hit 1.0 last December.

  • Ryan McCue 2:36 am on September 28, 2013 Permalink
    Tags: ,   

    JSON REST API: Version 0.6 and The Future 

    We’ve finally come to the end of Summer of Code, so it’s time for the final GSoC release in this slightly late update (hey, would it be a post by me if not?). This release is mainly a stability release, so there are only minor changes:

    • Huge documentation update – Guides on getting started and extending the API are now available for your perusal
    • Add generic CPT class – Plugins are now encouraged to extend
      WP_JSON_CustomPostType and get free hooking for common actions. This
      removes most of the boilerplate that you needed to write for new CPT-based
      routes and endpoints (#380)
    • Use defined filter priorities for endpoint registration – It’s now easier to
      inject your own endpoints at a defined point
    • Update the schema – Now includes documentation on the Media entity, plus more
    • Add better taxonomy support – You can now query for taxonomies and terms directly. The routes here might seem strange (/posts/types/post/taxonomies/category for example), but the intention is to future-proof them as much as possible (#275)
    • Ensure the JSON URL is relative to the home URL (#375)
    • Check all date formats for If-Unmodified-Since (#378)
    • Register the correct URL for the JS library (#376)
    • Correct the usage of meta links (#379)
    • Add filters for post type and post status data (#380)
    • Separate parent post and parent comment relation (#330)

    The big feature for this final week is a bunch of documentation changes. I’ve created guides and documents on how to use the API, intended for both beginners and experts. I’d especially like to highlight the Getting Started guide, as well as the Extending the API guide for plugin developers. The documentation in the past has been less than fantastic, so I’ve made a concerted effort towards it this week. In addition, I’ve also fixed up all the remaining bugs reported via Trac.

    Now that GSoC’s over, what’s next? The aim with the project is to now move it from a solo project to a team one, and to that end, I’ve been working on assembling a fantastic team to work on the project with, with aim to integrate the API into core in the future. 3.8 time is fast approaching, so we’ve elected to aim for 3.9 as a more realistic target, although the advantage of the Feature as a Plugin method of development is that we’re not locked down here.

    We’re held two meetings so far as a team, and I’ll announce a proper office hours time next week, but I’m also looking to try something new with the organisation of the team. More to come on that in the next team update, but in the meantime, you can check out the internal team discussion site. Anyone looking to get involved in the team is welcome to join as always, but I’d ask that only those serious about working on the project join, as there are a fair few people committed already.

    Thanks to everyone, especially my mentors and Jen, for making this project a joy to work on so far. Here’s hoping we can keep the momentum as we push forward with the project.

  • Ryan McCue 8:27 am on September 12, 2013 Permalink
    Tags: ,   

    JSON REST API: Version 0.5 

    This week, I finally have a new release for you! Version 0.5 is now available, with the following changes (and more!):

    • Add support for media – This has been a long time coming, and it’s finally at a point where I’m happy to push it out. Good luck. (#272)
    • Separate the post-related endpoints – Post-related endpoints are now located in the WP_JSON_Posts class. When implementing custom post type support, it’s recommended to subclass this.

      The various types are now also only registered via hooks, rather than directly in the server class, which should make it easier to override them as well (#348)

    • Add page support – This is a good base if you’re looking to create your own custom post type support (#271)
    • Switch from fields to context – Rather than passing in a list of fields that you want, you can now pass in a context (usually view or edit) (#328).
    • Always send headers via the server handler – Endpoints are now completely separate from the request, so the server class can now be used for non-HTTP/JSON handlers if needed (#293)
    • Use better error codes for disabled features (#338)
    • Send X-WP-Total and X-WP-TotalPages headers for information on post/pagination counts (#266)

    As always, the full changes are available if you’re interested.

    This week finally brings media into the fold. The process for uploading media is a little different to creating normal posts, so here’s how you do it.

    First, upload the file via a POST request to /media. This can either be as a standard HTTP multipart body, with the name field set to file, or as a raw file in the body with the Content-Type header. (You can also optionally send a Content-MD5 header if you’d like the server to check the consistency of your file.) This will give you a 201 Created status, and point you to the new resource. You can now update that resource with the correct post data.

    This multistep procedure is required to enable raw file uploads, and I’m not entirely pleased with it, but it’s the only way without requiring multipart requests. I’d love to have feedback on this system, as I think practical use will eventually reveal the correct method here.

    So, it’s time to start winding up the Summer of Code portion of the project. There’s still one week left for the Summer of Code project, so you may still see a release next week, but most likely in the form of smaller updates, especially with documentation and testing. As I finish up, it’s time to look forward to the future of the project. The plan is to form a Feature as a Plugin team as we work towards core integration in future releases. People have already volunteered for the team back in the 3.8 scoping days, and I’ll be getting in contact with them shortly, but it’s not too late to nominate yourself for the team; let me know if you’re interested.

    Thanks to everyone for testing and for your feedback. Stay beautiful.

  • Ryan McCue 2:20 pm on September 4, 2013 Permalink
    Tags: ,   

    JSON REST API: Coming Soon 

    It’s been a while since you’ve all heard from me, so I wanted to check in and assure you I am still alive. I’ve been plodding along behind the scenes with the JSON API and mostly getting design documents sorted.

    The big feature I’m working on at the moment – media – has turned out to be tricker than I initially thought. While media is technically handled via custom post types, it’s a completely different kettle of fish to normal post types, so I’ve been working through the conceptual issues behind this to ensure that the API stays consistent both internally and externally. I really believe that it’s worth my time to sit down and consider these conceptual issues in depth rather than pumping out the feature as soon as possible. (The implementation of the media-related endpoints is working locally, but I don’t want to push this up while it’s still in flux.)

    I still hold out hope to push through media, but will likely reduce the scope of the other tasks to compensate, due to the complexity of media and the time it has taken so far. I’d like to personally apologise for this, this is a result of improper scheduling for the second half of the project.

    Personally, the past month or so has been pretty stressful as well, due to a number of other things going on in the background. Balancing this project with university work has become a big issue recently, so I’m working through this as best as I can. Ideally, my preferred option at this point would be to push this project out of the Summer of Code phase and into the open source team phase rather than continuing to work on the project in isolation.

    Along those lines, revisions will be bumped from the Summer of Code phase completely. While they are part of core functionality, they’re a rather large task that is secondary in importance to media and also behind taxonomy handling. I’d love to see these in the plugin at some point, but that won’t be happening during the Summer of Code phase. What I would love is for someone to volunteer to develop this (in a separate plugin for now, thanks to GSoC’s restrictions) for integration back in as soon as possible, which would also help with validating the API’s usefulness.

    So again, sorry and hopefully I’ll have something better to show you next week. Thanks for your patience.

  • Ryan McCue 1:00 am on August 8, 2013 Permalink
    Tags: ,   

    JSON REST API: Version 0.4 

    After a week’s hiatus thanks to WCSF and the midsemester review, I’m back with a new release of WP API! Version 0.4 is now available with the following changes:

    • Add Backbone-based models and collections – These are available to your code by declaring a dependency on wp-api (#270)
    • Check json_route before using it (#336)
    • Conditionally load classes (#337)
    • Add additional test helper plugin – Provides code coverage as needed to the API client tests. Currently unused. (#269)
    • Move json_url() and get_json_url() to plugin.php – This allows using both outside of the API itself (#343)
    • getPost(0) now returns an error rather than the latest post (#344)

    As always, the full changes are available if you’re interested.

    This release brings the first version of the Javascript API, based on Backbone models and collections. To use it, simply declare `wp-api` as a dependency to your script, then start using the `wp.api` classes. Here’s a quick example of how to use it:

    var posts = new wp.api.collections.Posts();
    	success: function (posts) {
    		var post = posts.at(0);
    		var title = post.get('title');
    		post.set('title', title + ' (Updated!)');

    These are intended purely as building blocks for your own software. I had been looking at rewriting P2 partially to use these, however it appears that would require gutting P2 and basically starting from scratch, due to P2′s architecture. I’d love to see what you can do with this though, and bonus points if you can get a API-ified P2!

    The coming week will introduce some specialised page handling as an example of how to enable custom post type support, plus the beginning of the media/attachment-related APIs. These will probably be a fair bit of work, so it’s possible only basic functionality will land next week.

    • John Blackbourn (johnbillion) 1:27 am on August 8, 2013 Permalink | Log in to Reply

      I didn’t realise you were planning a JavaScript interface to the API too. That’s extremely cool.

      • Ryan McCue 1:28 am on August 8, 2013 Permalink | Log in to Reply

        It serves as an example of how to use the API, plus another way to test it, so it kills two birds with one stone. :)

    • Manny Fleurmond 1:58 am on August 8, 2013 Permalink | Log in to Reply

      This is so going to help me with my gallery plugin when you add Media support

    • Beau Lebens 3:10 pm on August 19, 2013 Permalink | Log in to Reply

      This is really cool stuff Ryan, especially the Backbone wrappers. I’m going to check it out in detail as we’re working on http://geto2.com, which is the next generation of P2, and is already based on Backbone (although most of that was written well before this was available, so we’ve implemented it all ourselves).

  • Ryan McCue 2:52 pm on July 24, 2013 Permalink
    Tags: ,   

    JSON REST API: Testing Updates 

    This week is a little different to the previous ones, as it’s a primarily testing focussed week. I’m skipping the release for this week in favour of just an update post.

    I noticed fairly late this week that the aforementioned client library wasn’t actually public and available to you guys, so I’ve now fixed that up. Given the lack of comments, I’d hazard a guess this also means no one tried using it. :)

    Previous Week

    Over the past week, I’ve been looking at a variety of testing-related items, including code coverage and schema validation. I’ve finally sorted the schema validation out with the help of a JSON Schema validation library, after much messing around. The unit tests now integrate this schema validation with the normal testing suite, which should ensure that the API is conformant to the specification as well as fully functional. I do suspect that the schema is slightly outdated and is missing a few items, so I’ll be ensuring the documentation and schema are consistent in the next week.

    Another area of the testing that I’ve been looking at is working with code coverage. After exploring the inner workings of PHPUnit’s code coverage, I think I’ve worked out a solution using a test helper plugin. This gathers the statistics on the server, then serialises them to send them back to the client. This still needs the PHPUnit end to connect to, which should be simple once I work out how to override the PHP_CodeCoverage object. (Help here would be appreciated if anyone has familiarity with PHPUnit.)

    I’ve also started work on the Backbone client, however that’s currently not in a state to release. The plan here is to create a generic set of Backbone-based classes that can be used as a library, with the proof-of-concept itself being a theme based on P2. I’ve started work on the Backbone side of things, however I’ve not worked on much here with the theme side. I suspect that P2′s Javascript will be discarded in large part, but hopefully I can avoid that as much as possible.

    Next week, you can look forward to more testing updates and the Backbone client. I’ll also be pushing out a new version with some bug fixes (thanks to Mike Schinkel for reporting these) as well as the usual slate of updates.


    I’ve also discovered that my documentation thus far has been a little lacking, so here’s a bit of an intro to using the API.

    After downloading and activating the plugin, your site will now capable of serving up data from its API. The API is accessible at /wp-json.php from your site (if you’re not sure where this is, copy your admin URL and replace wp-admin with wp-json.php), with the specific route added after this. For example, the index is available at /wp-json.php/ and a list of your posts is available at /wp-json.php/posts.

    If you’d just like to take a look around, you can view this in your browser and navigate via the links in the JSON. I personally use JSON View for this in Firefox, which converts the URLs in the data into proper hyperlinks as well as making it easier to view the data. The API uses a concept called HATEOAS, which basically means that all the possible data is discoverable via these links.

    Some endpoints will add extra data if you’re logged in with the correct permissions. You can log in via the normal WP login page if you’re just viewing this in your browser (using cookie-based authentication), but if you’re accessing the API programatically, the API also has built-in support for HTTP Basic authentication. (OAuth support is not planned for the core of the plugin, but my OAuth provider plugin might be a good start for anyone who wants to write this as a plugin.)

    I’m always open to questions regarding how to use this, so let me know here or on Twitter if there’s anything I can do to help you out.

    • Aaron Brazell 3:00 pm on July 24, 2013 Permalink | Log in to Reply

      Love it. I did submit a ticket you should consider for your next release. Making the whole thing Multisite aware. Good work and good luck!

      • Ryan McCue 4:56 am on July 25, 2013 Permalink | Log in to Reply

        I replied on the ticket (note that notification settings aren’t copied across from core Trac); multisite is out-of-scope for the GSoC project, but there’s a multisite plugin you can activate that should maybe hopefully work. Integrating this is out-of-scope, since I don’t actually have a multisite install handy (so testing would be appreciated).

    • Mike Schinkel 5:26 pm on July 24, 2013 Permalink | Log in to Reply

      Thanks for the ack.

      A note about HATEOAS. One of the primary benefits of HATEOAS is that it allows the server to change its URL space as needed however if an API publishes its URL structures to allow developers to construct URLs then the primary benefit of HATEOAS and the justification people use for the significantly increased complexity on the client is pretty much moot. Those developers coupling their apps to the APIs make it not viable to change the URL space in the future as too many existing apps would break.

      That said, IMO the URL space for “well-known” APIs should be accessible by URL construction though me stating this drives the REST purists mad.

      Additionally, if the API serves a generic content type such as "application/json" vs. a content like something like "application/wordpress+json" a client should not know how to handle the response representation as doing so violates RESTful constraints. If the latter content type were used then it would be RESTful to write a client that knows the structure which as a side note diminishes the need for a schema.

      OTOH having a WordPress-specific content type could have real benefits because it would allow for the development and evolution of RESTful WordPress-specific clients that don’t violate “the rules”; it would allow WP clients to avoid the need to layer application logic on top of a generic content type. And it could potentially result is a slew of new clients that can integrate with the WordPress API. But then again maybe that’s something that can be considered before WordPress 4.0+.

      Speaking of schemas this post discusses REST and description documents. It discusses WADL not JSON Schema but many of the concerns still apply.

      Back to HATEOAS, if the URL structure is published for URL composition and a generic media type is used them the only real benefit you get from HATEOAS is inline documentation, which is a real benefit. But to say an API supports HATEOAS and also URL construction is analogous to owning a Ferrari without an engine; you get to admire it’s looks but you can’t use it for what it’s meant for, to be driven.

      Finally, HATEOAS is not required, it is for stable architecture meant to last decades; URL construction if perfectly workable and probably 95+% of APIs on the open web use it, although it does annoy the REST purists. But URL construction makes decades long implementations much less likely. FWIW.

      • Ryan McCue 5:08 am on July 25, 2013 Permalink | Log in to Reply

        So, given that we’re aiming to have set routing, you might ask why HATEOAS is needed at all. The primary motivation for this is to ensure that we have at least some sort of workable solution for pluggability. It’s conceivable that a plugin could change all of the routes, or rework some of them, so adding this means that clients can be robust in terms of routing if they’d like.

        A content type (likely application/vnd.wordpress.api.v1+json) is something that I’d like to use eventually, but I haven’t yet for various reasons. The main one of these is that even vnd. types should be registered, but the format is still in flux, so it’d be inappropriate to register it now.

        As for the schema, the intention of that is to be specific about how exactly to parse the responses, without me having to write ABNF for every single field. I’ve written ABNF for the more structured ones, but the point is to be as explicit about the data as possible. The fact that I can use that for automated testing is a huge plus, but it’s primarily a documentation tool (which is also why it lives in the docs directory).

        • Ryan McCue 5:27 am on July 25, 2013 Permalink | Log in to Reply

          (Just to clarify on the registration of vnd. types: you technically don’t have to register these, but it should be at least discussed with IANA. In addition, this would require the consent of the core team, and they’re rather busy, so it’s not worth the pain.)

    • Dan 5:22 am on July 25, 2013 Permalink | Log in to Reply

      Very cool stuff! Do you have any plans to add an endpoint for uploading media?

    • arpowers 7:31 pm on July 28, 2013 Permalink | Log in to Reply

      Can’t figure out how to make this thing work… couple questions:
      what’s a good example url once installed?
      Does this thing work on localhost?
      Are there any special permalinks settings id need?

      We can help you with this thing, just give me some basic help ;)

    • Julien 6:23 am on July 30, 2013 Permalink | Log in to Reply

      Same here, I got issues and nothing happened. On google Chrome, it tells there is a server error 500 when trying the URL /wp-json.php/posts/ and on Firefox it tells anything, just the white screen of death lol.

      Has the user need to set permalinks “on” in order to use the API or not ? Will wp-json.php will be hidden later with permalinks ? Like reaching the API with this kind of url : /api/v1/posts/ or /api/posts/

      Also, is there a way to place the posts IDs in the URL for retrieving a specific post on a GET request => /api/v1/posts/25 ?

      I really like this project, keep up the good work !

      • Ryan McCue 7:23 am on July 30, 2013 Permalink | Log in to Reply

        Yes, permalinks do need to be on. Once integrated into core, this shouldn’t be needed.

        The `wp-json.php` is intentionally in the URL and replaces a `/api/` component in there. Versioning will not be in the URL, but rather in HTTP headers/content-type.

        For a specific post, the URL is `/wp-json.php/posts/` (this is also linked from the `/posts` endpoint).

    • Mat_ 7:33 pm on August 2, 2013 Permalink | Log in to Reply

      Great news, will try this deep next week (as part of an open-data project for a semi-public french structure).

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