-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Legacy widget rendering endpoint #34230
Conversation
public function __construct() { | ||
$this->namespace = 'wp/v2'; | ||
$this->rest_base = 'widget-types'; | ||
$this->full_endpoint_instance = new WP_REST_Widget_Types_Controller(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is my way of reusing get_item_permissions_check
. It should be safe because WP_REST_Widget_Types_Controller
is either supplied by core or the Gutenberg plugin.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about extending WP_REST_Widget_Types_Controller
but I don't like bringing over all that code just to be able to check permissions. Inheriting from WP_REST_Controller
is more isolated.
lib/compat/wordpress-trunk/index.php
Outdated
@@ -0,0 +1,8 @@ | |||
<?php | |||
/** | |||
* Temporary compatibility shims for features present in Gutenberg. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't specify version such as 5.8.1 because I can't be certain when this change gets backported. I guess this means that on every core release we'll have to move all the PHP code compat/wordpress-trunk
to compat/wordpress-$CURRENT_VERSION
Ugh, yeah 💀
(Thinking out loud: With #33810, we could have class GB_REST_Widget_Types_Controller extends WP_REST_Widget_Types_Controller {
public function register_routes() {
register_rest_route(
$this->namespace,
'/' . $this->rest_base . '/(?P<id>[a-zA-Z0-9_-]+)/encode',
array(
'args' => array(
...
),
array(
'methods' => WP_REST_Server::CREATABLE,
'permission_callback' => array( $this, 'get_item_permissions_check' ),
'callback' => array( $this, 'encode_form_data' ),
),
),
/* override: */ true
);
}
public function encode_form_data( $request ) {
...
}
} |
It looks like @noisysocks has an idea of how to reuse the existing endpoint. I don't think that the level of complexity that the solution creates in Gutenberg should drive the final implementation. Even if we had to unregister the endpoint from the core and register its copy it is still better in the long term. I wouldn't worry that much about sync issues at this moment. In practice, I don't remember any case where we had to keep REST API endpoints in sync after they were released in WordPress core. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code looks good to me.
However, I can't review the polyfill thing (I haven't used them much).
The rest of the PR is fine.
I just updated this PR to override the |
Isn't it a bit unexpected to render the widget using an encode endpoint? I would rather if we don't use the preview in encode to remove it from there and just have one place to render and another place to encode :) |
I was wrong about the We could try to fix the "is this HTML empty?" logic but, as @draganescu alludes to, it's probably better to maintain a distinction between these two kinds of preview: one is a simple dump of the widget HTML and the other is a contextualised render of the widget complete with scripts and styles. So I think let's revert back to adding a seperate Sorry to mess you about! I think that we definitely should try to land a fix for #33540 in 5.8.1 because I imagine that it is a semi-widespread issue. Lots of servers don't support very long URLs. #30049 is a less urgent issue as I don't imagine it's particularly widespread. Nice to have though. But yes that raises an interesting question: do we add the compatibility shim to |
Yes, we didn't discuss minor WordPress releases in this context because it's a very rare case when so many PHP changes have to be added to the plugin and WP core. There is usually a list of JS-based bug fixes that are cherry-picked to the corresponding major release line. In this case, it's up to you what approach you will take. At the end of the day, it should impact whether we will have to remove one or two folders when the minimum supported version of WordPress is higher than 5.8. |
I saw that Anyway, all good, we're back to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I try to test the endpoint locally I always get a 400
error.
gutenberg (add/legacy-widget-rendering-api) % http -a admin:password POST http://wp-git-build.test/wp-json/wp/v2/widget-types/search/render
HTTP/1.1 400 Bad Request
Access-Control-Allow-Headers: Authorization, X-WP-Nonce, Content-Disposition, Content-MD5, Content-Type
Access-Control-Expose-Headers: X-WP-Total, X-WP-TotalPages, Link
Allow: POST
Cache-Control: no-cache, must-revalidate, max-age=0
Connection: close
Content-Length: 123
Content-Type: application/json; charset=UTF-8
Date: Fri, 27 Aug 2021 06:06:36 GMT
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Link: <http://wp-git-build.test/wp-json/>; rel="https://api.w.org/"
Server: Apache/2.4.48 (Unix) PHP/8.0.9
X-Content-Type-Options: nosniff
X-Powered-By: PHP/8.0.9
X-Robots-Tag: noindex
{
"code": "rest_missing_callback_param",
"data": {
"params": [
"id_base"
],
"status": 400
},
"message": "Missing parameter(s): id_base"
}
It looks like what's happening is that the param is called id
in the $route
but id_base
in the 'params'
array.
It should be id
so that we're consistent with the base class.
Other than that I think this looks good!
@noisysocks Good catch, in my testing I always had |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It works locally! 👍
I still think it's weird to return a Content-Type: application/json
response with one field containing HTML instead of a Content-Type: text/html
response, but... I guess that makes it work easier with existing tooling and forwards compatible.
09a1d67
to
c6b6664
Compare
Description
Follows up on: WordPress/wordpress-develop#1508
This adds a
/wp/v2/widget-types/<widget type>/render
endpoint which accepts POST data and returns the same output as the previous iframe-oriented GET endpoint.This PR is for the Gutenberg plugin and not for core so that we the endpoint may be safely used in other Gutenberg PRs.
The polyfill approach draws on learnings from #33810 and may not be perfect – let's use this PR as a testing ground. One shortcoming is that I can't think of a good way to apply the following feedback from @noisysocks:
I like the idea of re-using the
/encode
endpoint, but I have no idea how to polyfill that. I'd rather avoid overriding the entire endpoint with an updated copy living in this repo – it could send us to a land of two-way synchronization betweenwordpress-develop
andgutenberg
which I think is much more complex than one-way backporting workflow.How has this been tested?
/wp-admin/widgets.php
Alternatives considered
ServerSideRender
– we need to render a full HTML document withwp_head()
, CSS links, maybe some additional scripts, and this is much more that I would like to return from a block rendering API.admin_init
hook handler to work withPOST
requests – it's tricky and doesn't seem right, I don't think we should stretch hooks like that. This clearly is an API request so let's treat it as such.