Skip to content
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

Extract ServerSideRender component to an independent package #15635

Conversation

jorgefilipecosta
Copy link
Member

Description

ServerSideRender component was part of WordPress component. I think ServerSideRender is WordPress specific. In WordPress components, we try to keep artifacts that are generic and don't rely on WordPress API's like the rest endpoints.

In wordpress/editor we exposed a similar component that uses the WordPress components version and adds the post id as a property to be passed to the server.
Blocks that used ServerSideRender should have the wordpress/editor version because without the post id blocks, may not render as expected for that post.

WordPress/editor will not be available on the widgets screen and blocks should not rely on WordPress/editor.
This PR extracts ServerSideRender to an independent package. The extracted component checks if it is possible to query the post id from the editor store, if yes the post id is passed to the server, if not the post id is not passed to the server.

We are back-compatible with usages of wp.editor.ServerSideRender.
We are not back-compatible with usages of wp.components.ServerSideRender. To be back-compatible we would create circular reference: wp.components would depend wp.serverSideRender and wp.serverSideRender would depend on wp.components

How has this been tested?

I checked blocks using server-side render( Archives, Calendar, Lastest comments, Legacy Widgets ) still work as expected.

packages/server-side-render/package.json Outdated Show resolved Hide resolved
packages/server-side-render/README.md Show resolved Hide resolved
packages/components/src/index.js Show resolved Hide resolved
packages/components/package.json Show resolved Hide resolved
packages/components/CHANGELOG.md Outdated Show resolved Hide resolved
@gziolo gziolo added npm Packages Related to npm packages [Package] Components /packages/components [Type] Code Quality Issues or PRs that relate to code quality labels May 15, 2019
@jorgefilipecosta jorgefilipecosta force-pushed the update/extracted-server-side-render-to-independent-package branch from b8499c8 to 3f16f23 Compare May 24, 2019 17:48
@jorgefilipecosta
Copy link
Member Author

I added an inline script so we can keep back-compatibility with wp.components.ServerSideRender calls.

@jorgefilipecosta jorgefilipecosta added the [Feature] Widgets Screen The block-based screen that replaced widgets.php. label May 24, 2019
@jorgefilipecosta jorgefilipecosta force-pushed the update/extracted-server-side-render-to-independent-package branch 2 times, most recently from a52956b to 255aa5f Compare May 24, 2019 18:10
packages/server-side-render/README.md Outdated Show resolved Hide resolved
packages/server-side-render/README.md Show resolved Hide resolved
}
)(
( { urlQueryArgs = EMPTY_OBJECT, currentPostId, ...props } ) => {
urlQueryArgs = useMemo( () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that props should be ever mutated. It might cause some unexpected behavior. In addition, it makes this code harder to follow.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @gziolo, I think we were not mutating the props. If we do urlQueryArgs = someObject; the props the component receives stay the same as we just updated the reference to point to another object, we would be mutation the props if we did urlQueryArgs.someKey = value; I may be missing something if that's the case, please correct me, so I avoid these problems in the future. That said, I agree that the code becomes more straightforward if we use another variable, so I updated the code.

@jorgefilipecosta jorgefilipecosta force-pushed the update/extracted-server-side-render-to-independent-package branch from 022d2bd to ec10435 Compare May 27, 2019 11:27
@jorgefilipecosta jorgefilipecosta added Needs Technical Feedback Needs testing from a developer perspective. [Priority] High Used to indicate top priority items that need quick attention labels May 30, 2019
@jorgefilipecosta
Copy link
Member Author

I added a high priority label as this is a blocker to having legacy widgets on the widgets screen.

"react-native": "src/index",
"dependencies": {
"@babel/runtime": "^7.4.4",
"@wordpress/components": "file:../components",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wordpress/api-fetch is missing on the list of dependencies.


export default withSelect(
( select ) => {
const coreEditorSelect = select( 'core/editor' );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part is a bit concerning in my opinion. This package doesn't depend on @wordpress/editor explicitly but it will use it when it happens to be loaded on the page. While it solves the original issue of removing the dependency of core blocks on @wordpress/editor, in fact, it only hides it.

@jorgefilipecosta and @youknowriad, have you considered feeding the block editor provider with some commonly used data which is specific to the page context? In this case, it would be the current post id. In the context of widget areas, it might be necessary to know the id of the widget area. Well, it might turn out that this is the only component which would take advantage of it, so it's all academic :) I definitely don't want to block this PR but I wanted to hear your opinions.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @gziolo, if we follow the context approach (feeding the block editor provider with some commonly used data which is specific to the page context), wouldn't the context consumer component need to be part of @wordpress/editor? In that case, we would even need to have a direct dependency on @wordpress/editor.

Based on your idea, I think a possible solution may be to put context as part of the ServerSideRender package and expose a component ServerSideRenderAdditionalDataProvider that allows to other components to pass additional props that are used in server-side render calls (the default is an empty object and no additional props are passed). The editor would use this component to pass the post id, later if the widgets also need to pass something specific it is possible to do the same.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, ServerSideRenderProvider would solve this issue as well. I don't think there is a perfect solution to this problem. All I can think of have some drawbacks. @youknowriad will know better what is the most anticipated one 😄

packages/server-side-render/README.md Show resolved Hide resolved
Copy link
Member

@gziolo gziolo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still need to test this PR before I give 👍

@@ -15,6 +15,10 @@
- Fixed display of reset button when using RangeControl `allowReset` prop.
- Fixed minutes field of `DateTimePicker` missed '0' before single digit values.

### Breaking Change
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be moved now to Master section. We really need to land this PR :)

packages/server-side-render/package.json Outdated Show resolved Hide resolved

export default withSelect(
( select ) => {
const coreEditorSelect = select( 'core/editor' );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, ServerSideRenderProvider would solve this issue as well. I don't think there is a perfect solution to this problem. All I can think of have some drawbacks. @youknowriad will know better what is the most anticipated one 😄

packages/server-side-render/package.json Outdated Show resolved Hide resolved
@gziolo gziolo removed the Needs Technical Feedback Needs testing from a developer perspective. label Jun 5, 2019
Copy link
Member

@gziolo gziolo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It works perfectly fine. I can confirm you can still use deprecated versions of the component:
Screen Shot 2019-06-05 at 16 23 28

There is still this unresolved indirect reference to core/editor store in the code which will work but should be further discussed. See https://github.com/WordPress/gutenberg/pull/15635/files#r290156306.

If this is blocking your work, feel free to merge this PR but let's make sure this discussion continues.

@jorgefilipecosta jorgefilipecosta force-pushed the update/extracted-server-side-render-to-independent-package branch from ee7f705 to 532a432 Compare June 5, 2019 15:34
@jorgefilipecosta jorgefilipecosta merged commit 01db600 into master Jun 5, 2019
@jorgefilipecosta jorgefilipecosta deleted the update/extracted-server-side-render-to-independent-package branch June 5, 2019 15:56
@jorgefilipecosta
Copy link
Member Author

Thank you for the reviews @gziolo, I think we should follow the ServerSideRenderProvider approach, and I will gladly submit that change in a follow-up PR. @youknowriad do you have any concerns related to that approach?

@@ -117,3 +117,4 @@ export {
withColors,
withFontSizes,
};
export { default as ServerSideRender } from '@wordpress/server-side-render';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add a deprecated call, when using it from this location?

Copy link
Contributor

@mcsf mcsf Mar 23, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just ran into this while writing a plugin. Because wp.components.ServerSideRender is available with no deprecation warnings, it's easy to think that this is still the canonical place for that component.

The other thing is that the wp-components module hasn't listed wp-server-side-render as a dependency, so as a plugin author I have to know that my plugin depends on wp-server-side-render on top of the rest. Finally, we are in a strange situation now because those two modules are interdependent. I believe that, going forward, the only proper solution is to remove ServerSideRender from components's deprecated components.

Of course, before that is possible, we should at least wrap wp.components.ServerSideRender so that it logs a deprecation warning.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, this line was about wp-editor and I missed that. I guess it speaks to the general confusion. :) Never mind the bit about mutual dependencies, then.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"\n",
array(
'( function() {',
' if ( wp && wp.components && wp.serverSideRender && ! wp.components.ServerSideRender ) {',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An issue with this is if wp-components is enqueued after wp-server-side-render, it will never be shimmed. We could potentially resolve this by defining wp-components as a dependency of wp-server-side-render (optionally checking that it's at least registered).

array(
'( function() {',
' if ( wp && wp.components && wp.serverSideRender && ! wp.components.ServerSideRender ) {',
' wp.components.ServerSideRender = wp.serverSideRender;',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is a component, the capitalization of serverSideRender is wrong. It should be ServerSideRender?

'( function() {',
' if ( wp && wp.components && wp.serverSideRender && ! wp.components.ServerSideRender ) {',
' wp.components.ServerSideRender = wp.serverSideRender;',
' };',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The semi-colon here is unnecessary.

@youknowriad youknowriad removed the Needs Dev Note Requires a developer note for a major WordPress release cycle label Sep 23, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Widgets Screen The block-based screen that replaced widgets.php. npm Packages Related to npm packages [Package] Components /packages/components [Priority] High Used to indicate top priority items that need quick attention [Type] Code Quality Issues or PRs that relate to code quality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants