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

Add a Global Styles endpoint and use it in the site editor #35801

Merged
merged 15 commits into from
Oct 28, 2021

Conversation

youknowriad
Copy link
Contributor

@youknowriad youknowriad commented Oct 20, 2021

This PR explores the global styles endpoint explored in #35141

At the moment, it only solves the "user global styles" use-cases, so there's no big difference with what we have on trunk aside of the fact that json parsing and serializing is moved to the server.

After that I'd like to explore:

  • getting rid of __experimentalGlobalStylesUserEntityId Done in 369183e
  • getting rid of __experimentalGlobalStylesBaseConfig

The latter here might a bit complex because it will make the source for the base config is not a CPT but the theme file directly, so it's unclear to me at the moment whether it should be dedicated endpoints global-styles/theme/{some_theme} or whether we should try to merge things using the id like we did for templates (which feels too heavy for global styles)

parsedConfig = contentToParse ? JSON.parse( contentToParse ) : {};
// It is very important to verify if the flag isGlobalStylesUserThemeJSON is true.
// If it is not true the content was not escaped and is not safe.
if ( ! parsedConfig.isGlobalStylesUserThemeJSON ) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure how to handle this thing, I thought it was not something the client should be concerned about but I don't understand it enough to do the right things. cc @jorgefilipecosta

Copy link
Member

Choose a reason for hiding this comment

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

Yes, I agree that the client should not care about this validation now that we have an endpoint. I think on the endpoint method prepare_item_for_response we should check if the flag isGlobalStylesUserThemeJSON is present if it is we proceed normally if it is not we return empty styles and settings.

Copy link
Member

Choose a reason for hiding this comment

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

Related to this issue when serializing the user post to the database we should also include isGlobalStylesUserThemeJSON true, so the structure is properly sanitized. Right now we are not including the flag, so the styles load on the site editor, but on the frontend, user styles are ignored.

@youknowriad youknowriad added Core REST API Task Task for Core REST API efforts Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json labels Oct 20, 2021
@github-actions
Copy link

github-actions bot commented Oct 20, 2021

Size Change: +171 B (0%)

Total Size: 1.08 MB

Filename Size Change
build/core-data/index.min.js 12.6 kB +178 B (+1%)
build/edit-site/index.min.js 30.7 kB +2 B (0%)
build/editor/index.min.js 37.7 kB -9 B (0%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 931 B
build/admin-manifest/index.min.js 1.09 kB
build/annotations/index.min.js 2.7 kB
build/api-fetch/index.min.js 2.21 kB
build/autop/index.min.js 2.08 kB
build/blob/index.min.js 459 B
build/block-directory/index.min.js 6.2 kB
build/block-directory/style-rtl.css 1.01 kB
build/block-directory/style.css 1.01 kB
build/block-editor/default-editor-styles-rtl.css 378 B
build/block-editor/default-editor-styles.css 378 B
build/block-editor/index.min.js 135 kB
build/block-editor/style-rtl.css 14 kB
build/block-editor/style.css 14 kB
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 65 B
build/block-library/blocks/archives/style.css 65 B
build/block-library/blocks/audio/editor-rtl.css 58 B
build/block-library/blocks/audio/editor.css 58 B
build/block-library/blocks/audio/style-rtl.css 111 B
build/block-library/blocks/audio/style.css 111 B
build/block-library/blocks/audio/theme-rtl.css 125 B
build/block-library/blocks/audio/theme.css 125 B
build/block-library/blocks/block/editor-rtl.css 161 B
build/block-library/blocks/block/editor.css 161 B
build/block-library/blocks/button/editor-rtl.css 470 B
build/block-library/blocks/button/editor.css 470 B
build/block-library/blocks/button/style-rtl.css 560 B
build/block-library/blocks/button/style.css 560 B
build/block-library/blocks/buttons/editor-rtl.css 309 B
build/block-library/blocks/buttons/editor.css 309 B
build/block-library/blocks/buttons/style-rtl.css 317 B
build/block-library/blocks/buttons/style.css 317 B
build/block-library/blocks/calendar/style-rtl.css 207 B
build/block-library/blocks/calendar/style.css 207 B
build/block-library/blocks/categories/editor-rtl.css 84 B
build/block-library/blocks/categories/editor.css 83 B
build/block-library/blocks/categories/style-rtl.css 79 B
build/block-library/blocks/categories/style.css 79 B
build/block-library/blocks/code/style-rtl.css 90 B
build/block-library/blocks/code/style.css 90 B
build/block-library/blocks/code/theme-rtl.css 131 B
build/block-library/blocks/code/theme.css 131 B
build/block-library/blocks/columns/editor-rtl.css 206 B
build/block-library/blocks/columns/editor.css 205 B
build/block-library/blocks/columns/style-rtl.css 497 B
build/block-library/blocks/columns/style.css 496 B
build/block-library/blocks/cover/editor-rtl.css 546 B
build/block-library/blocks/cover/editor.css 547 B
build/block-library/blocks/cover/style-rtl.css 1.17 kB
build/block-library/blocks/cover/style.css 1.17 kB
build/block-library/blocks/embed/editor-rtl.css 488 B
build/block-library/blocks/embed/editor.css 488 B
build/block-library/blocks/embed/style-rtl.css 417 B
build/block-library/blocks/embed/style.css 417 B
build/block-library/blocks/embed/theme-rtl.css 124 B
build/block-library/blocks/embed/theme.css 124 B
build/block-library/blocks/file/editor-rtl.css 300 B
build/block-library/blocks/file/editor.css 300 B
build/block-library/blocks/file/style-rtl.css 255 B
build/block-library/blocks/file/style.css 255 B
build/block-library/blocks/file/view.min.js 322 B
build/block-library/blocks/freeform/editor-rtl.css 2.44 kB
build/block-library/blocks/freeform/editor.css 2.44 kB
build/block-library/blocks/gallery/editor-rtl.css 977 B
build/block-library/blocks/gallery/editor.css 982 B
build/block-library/blocks/gallery/style-rtl.css 1.6 kB
build/block-library/blocks/gallery/style.css 1.59 kB
build/block-library/blocks/gallery/theme-rtl.css 122 B
build/block-library/blocks/gallery/theme.css 122 B
build/block-library/blocks/group/editor-rtl.css 159 B
build/block-library/blocks/group/editor.css 159 B
build/block-library/blocks/group/style-rtl.css 57 B
build/block-library/blocks/group/style.css 57 B
build/block-library/blocks/group/theme-rtl.css 78 B
build/block-library/blocks/group/theme.css 78 B
build/block-library/blocks/heading/style-rtl.css 114 B
build/block-library/blocks/heading/style.css 114 B
build/block-library/blocks/home-link/style-rtl.css 247 B
build/block-library/blocks/home-link/style.css 247 B
build/block-library/blocks/html/editor-rtl.css 332 B
build/block-library/blocks/html/editor.css 333 B
build/block-library/blocks/image/editor-rtl.css 731 B
build/block-library/blocks/image/editor.css 730 B
build/block-library/blocks/image/style-rtl.css 502 B
build/block-library/blocks/image/style.css 505 B
build/block-library/blocks/image/theme-rtl.css 124 B
build/block-library/blocks/image/theme.css 124 B
build/block-library/blocks/latest-comments/style-rtl.css 284 B
build/block-library/blocks/latest-comments/style.css 284 B
build/block-library/blocks/latest-posts/editor-rtl.css 137 B
build/block-library/blocks/latest-posts/editor.css 137 B
build/block-library/blocks/latest-posts/style-rtl.css 528 B
build/block-library/blocks/latest-posts/style.css 527 B
build/block-library/blocks/list/style-rtl.css 94 B
build/block-library/blocks/list/style.css 94 B
build/block-library/blocks/media-text/editor-rtl.css 266 B
build/block-library/blocks/media-text/editor.css 263 B
build/block-library/blocks/media-text/style-rtl.css 493 B
build/block-library/blocks/media-text/style.css 490 B
build/block-library/blocks/more/editor-rtl.css 431 B
build/block-library/blocks/more/editor.css 431 B
build/block-library/blocks/navigation-link/editor-rtl.css 642 B
build/block-library/blocks/navigation-link/editor.css 642 B
build/block-library/blocks/navigation-link/style-rtl.css 94 B
build/block-library/blocks/navigation-link/style.css 94 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 299 B
build/block-library/blocks/navigation-submenu/editor.css 299 B
build/block-library/blocks/navigation-submenu/style-rtl.css 195 B
build/block-library/blocks/navigation-submenu/style.css 195 B
build/block-library/blocks/navigation-submenu/view.min.js 343 B
build/block-library/blocks/navigation/editor-rtl.css 1.81 kB
build/block-library/blocks/navigation/editor.css 1.81 kB
build/block-library/blocks/navigation/style-rtl.css 1.71 kB
build/block-library/blocks/navigation/style.css 1.7 kB
build/block-library/blocks/navigation/view.min.js 2.74 kB
build/block-library/blocks/nextpage/editor-rtl.css 395 B
build/block-library/blocks/nextpage/editor.css 395 B
build/block-library/blocks/page-list/editor-rtl.css 377 B
build/block-library/blocks/page-list/editor.css 377 B
build/block-library/blocks/page-list/style-rtl.css 198 B
build/block-library/blocks/page-list/style.css 198 B
build/block-library/blocks/paragraph/editor-rtl.css 157 B
build/block-library/blocks/paragraph/editor.css 157 B
build/block-library/blocks/paragraph/style-rtl.css 273 B
build/block-library/blocks/paragraph/style.css 273 B
build/block-library/blocks/post-author/style-rtl.css 175 B
build/block-library/blocks/post-author/style.css 176 B
build/block-library/blocks/post-comments-form/style-rtl.css 347 B
build/block-library/blocks/post-comments-form/style.css 347 B
build/block-library/blocks/post-comments/style-rtl.css 492 B
build/block-library/blocks/post-comments/style.css 493 B
build/block-library/blocks/post-excerpt/editor-rtl.css 73 B
build/block-library/blocks/post-excerpt/editor.css 73 B
build/block-library/blocks/post-excerpt/style-rtl.css 69 B
build/block-library/blocks/post-excerpt/style.css 69 B
build/block-library/blocks/post-featured-image/editor-rtl.css 396 B
build/block-library/blocks/post-featured-image/editor.css 397 B
build/block-library/blocks/post-featured-image/style-rtl.css 156 B
build/block-library/blocks/post-featured-image/style.css 156 B
build/block-library/blocks/post-template/editor-rtl.css 99 B
build/block-library/blocks/post-template/editor.css 98 B
build/block-library/blocks/post-template/style-rtl.css 391 B
build/block-library/blocks/post-template/style.css 392 B
build/block-library/blocks/post-terms/style-rtl.css 73 B
build/block-library/blocks/post-terms/style.css 73 B
build/block-library/blocks/post-title/style-rtl.css 60 B
build/block-library/blocks/post-title/style.css 60 B
build/block-library/blocks/preformatted/style-rtl.css 103 B
build/block-library/blocks/preformatted/style.css 103 B
build/block-library/blocks/pullquote/editor-rtl.css 198 B
build/block-library/blocks/pullquote/editor.css 198 B
build/block-library/blocks/pullquote/style-rtl.css 378 B
build/block-library/blocks/pullquote/style.css 378 B
build/block-library/blocks/pullquote/theme-rtl.css 167 B
build/block-library/blocks/pullquote/theme.css 167 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B
build/block-library/blocks/query-pagination/editor-rtl.css 262 B
build/block-library/blocks/query-pagination/editor.css 255 B
build/block-library/blocks/query-pagination/style-rtl.css 234 B
build/block-library/blocks/query-pagination/style.css 231 B
build/block-library/blocks/query/editor-rtl.css 131 B
build/block-library/blocks/query/editor.css 132 B
build/block-library/blocks/quote/style-rtl.css 187 B
build/block-library/blocks/quote/style.css 187 B
build/block-library/blocks/quote/theme-rtl.css 223 B
build/block-library/blocks/quote/theme.css 226 B
build/block-library/blocks/rss/editor-rtl.css 202 B
build/block-library/blocks/rss/editor.css 204 B
build/block-library/blocks/rss/style-rtl.css 289 B
build/block-library/blocks/rss/style.css 288 B
build/block-library/blocks/search/editor-rtl.css 165 B
build/block-library/blocks/search/editor.css 165 B
build/block-library/blocks/search/style-rtl.css 397 B
build/block-library/blocks/search/style.css 398 B
build/block-library/blocks/search/theme-rtl.css 64 B
build/block-library/blocks/search/theme.css 64 B
build/block-library/blocks/separator/editor-rtl.css 99 B
build/block-library/blocks/separator/editor.css 99 B
build/block-library/blocks/separator/style-rtl.css 250 B
build/block-library/blocks/separator/style.css 250 B
build/block-library/blocks/separator/theme-rtl.css 172 B
build/block-library/blocks/separator/theme.css 172 B
build/block-library/blocks/shortcode/editor-rtl.css 474 B
build/block-library/blocks/shortcode/editor.css 474 B
build/block-library/blocks/site-logo/editor-rtl.css 770 B
build/block-library/blocks/site-logo/editor.css 770 B
build/block-library/blocks/site-logo/style-rtl.css 165 B
build/block-library/blocks/site-logo/style.css 165 B
build/block-library/blocks/site-tagline/editor-rtl.css 86 B
build/block-library/blocks/site-tagline/editor.css 86 B
build/block-library/blocks/site-title/editor-rtl.css 84 B
build/block-library/blocks/site-title/editor.css 84 B
build/block-library/blocks/social-link/editor-rtl.css 177 B
build/block-library/blocks/social-link/editor.css 177 B
build/block-library/blocks/social-links/editor-rtl.css 824 B
build/block-library/blocks/social-links/editor.css 823 B
build/block-library/blocks/social-links/style-rtl.css 1.32 kB
build/block-library/blocks/social-links/style.css 1.32 kB
build/block-library/blocks/spacer/editor-rtl.css 307 B
build/block-library/blocks/spacer/editor.css 307 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table/editor-rtl.css 471 B
build/block-library/blocks/table/editor.css 472 B
build/block-library/blocks/table/style-rtl.css 481 B
build/block-library/blocks/table/style.css 481 B
build/block-library/blocks/table/theme-rtl.css 188 B
build/block-library/blocks/table/theme.css 188 B
build/block-library/blocks/tag-cloud/style-rtl.css 146 B
build/block-library/blocks/tag-cloud/style.css 146 B
build/block-library/blocks/template-part/editor-rtl.css 560 B
build/block-library/blocks/template-part/editor.css 559 B
build/block-library/blocks/template-part/theme-rtl.css 101 B
build/block-library/blocks/template-part/theme.css 101 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 166 B
build/block-library/blocks/text-columns/style.css 166 B
build/block-library/blocks/verse/style-rtl.css 87 B
build/block-library/blocks/verse/style.css 87 B
build/block-library/blocks/video/editor-rtl.css 571 B
build/block-library/blocks/video/editor.css 572 B
build/block-library/blocks/video/style-rtl.css 173 B
build/block-library/blocks/video/style.css 173 B
build/block-library/blocks/video/theme-rtl.css 124 B
build/block-library/blocks/video/theme.css 124 B
build/block-library/common-rtl.css 815 B
build/block-library/common.css 812 B
build/block-library/editor-rtl.css 9.78 kB
build/block-library/editor.css 9.78 kB
build/block-library/index.min.js 154 kB
build/block-library/reset-rtl.css 474 B
build/block-library/reset.css 474 B
build/block-library/style-rtl.css 10.5 kB
build/block-library/style.css 10.5 kB
build/block-library/theme-rtl.css 668 B
build/block-library/theme.css 673 B
build/block-serialization-default-parser/index.min.js 1.09 kB
build/block-serialization-spec-parser/index.min.js 2.79 kB
build/blocks/index.min.js 46 kB
build/components/index.min.js 212 kB
build/components/style-rtl.css 15.4 kB
build/components/style.css 15.4 kB
build/compose/index.min.js 10.9 kB
build/customize-widgets/index.min.js 11.2 kB
build/customize-widgets/style-rtl.css 1.5 kB
build/customize-widgets/style.css 1.49 kB
build/data-controls/index.min.js 614 B
build/data/index.min.js 7.1 kB
build/date/index.min.js 31.5 kB
build/deprecated/index.min.js 428 B
build/dom-ready/index.min.js 304 B
build/dom/index.min.js 4.44 kB
build/edit-navigation/index.min.js 15.8 kB
build/edit-navigation/style-rtl.css 3.76 kB
build/edit-navigation/style.css 3.76 kB
build/edit-post/classic-rtl.css 492 B
build/edit-post/classic.css 494 B
build/edit-post/index.min.js 29.4 kB
build/edit-post/style-rtl.css 7.12 kB
build/edit-post/style.css 7.12 kB
build/edit-site/style-rtl.css 5.79 kB
build/edit-site/style.css 5.79 kB
build/edit-widgets/index.min.js 16.3 kB
build/edit-widgets/style-rtl.css 4.17 kB
build/edit-widgets/style.css 4.18 kB
build/editor/style-rtl.css 3.78 kB
build/editor/style.css 3.77 kB
build/element/index.min.js 3.21 kB
build/escape-html/index.min.js 517 B
build/format-library/index.min.js 6.34 kB
build/format-library/style-rtl.css 571 B
build/format-library/style.css 571 B
build/hooks/index.min.js 1.55 kB
build/html-entities/index.min.js 424 B
build/i18n/index.min.js 3.6 kB
build/is-shallow-equal/index.min.js 501 B
build/keyboard-shortcuts/index.min.js 1.72 kB
build/keycodes/index.min.js 1.3 kB
build/list-reusable-blocks/index.min.js 1.85 kB
build/list-reusable-blocks/style-rtl.css 838 B
build/list-reusable-blocks/style.css 838 B
build/media-utils/index.min.js 2.92 kB
build/notices/index.min.js 845 B
build/nux/index.min.js 2.03 kB
build/nux/style-rtl.css 747 B
build/nux/style.css 743 B
build/plugins/index.min.js 1.83 kB
build/primitives/index.min.js 921 B
build/priority-queue/index.min.js 582 B
build/react-i18n/index.min.js 671 B
build/redux-routine/index.min.js 2.63 kB
build/reusable-blocks/index.min.js 2.19 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 10.7 kB
build/server-side-render/index.min.js 1.52 kB
build/shortcode/index.min.js 1.48 kB
build/token-list/index.min.js 562 B
build/url/index.min.js 1.74 kB
build/viewport/index.min.js 1.02 kB
build/warning/index.min.js 248 B
build/widgets/index.min.js 7.11 kB
build/widgets/style-rtl.css 1.16 kB
build/widgets/style.css 1.16 kB
build/wordcount/index.min.js 1.04 kB

compressed-size-action

@oandregal oandregal requested a review from geriux October 21, 2021 07:31
@youknowriad
Copy link
Contributor Author

I've updated the PR and removed the __experimentalGlobalStylesUserEntityId flag. The only remaining thing for me is __experimentalGlobalStylesBaseConfig and it's not clear to me yet how to solve that: should it be part of the themes endpoint, a sub endpoint /themes/{name}/global-styles or should it be its own endpoint or merged with the global-styles endpoint with the smart "id" logic (like templates). I'd love your thoughts on this one @TimothyBJacobs @oandregal I'm thinking the first one might be the simplest for me (aka /themes/{name}/global-styles)

@oandregal
Copy link
Member

Hey, took some time to read through the discussion and take stock of the data used by consumers:

global-styles-settings-data

They take the settings & styles, either standalone such as user or merged such as core+theme+user and do things with them. When it comes to generating the stylesheet from the given set of styles&settings, some of the consumers filter the data taking into account origins (core, theme, user) and types of styles (CSS variables, block classes, preset classes).

Additionally, note that some settings (presets) contain data for the three origins (i.e.: the data in settings.__experimentalFeatures.color.palette has core, theme, and user sub-keys).

We've also talked about "global styles variations" which I presume is just a list of different core+theme data.

@oandregal
Copy link
Member

In the mental model I have for this, the endpoint would be something like:

/wp/v2/global-styles/user/{ID} => user data for the active theme
/wp/v2/global-styles/base => core+theme data for the active theme
/wp/v2/global-styles/merged => core+theme+user data for the active theme

This pattern allows us to grow later, should we need it:

/wp/v2/global-styles/list => a list of global styles variations that offer core+theme data for the active theme
/wp/v2/global-styles/theme => theme data for the active theme

In terms of naming: is there an alternative namespace to global-styles that communicates that data is both settings & styles?

@youknowriad
Copy link
Contributor Author

/wp/v2/global-styles/user/{ID} => user data for the active theme

This one is currently already implemented in this PR as /wp/v2/global-styles/{ID}

/wp/v2/global-styles/base => core+theme data for the active theme
/wp/v2/global-styles/merged => core+theme+user data for the active theme

It is not clear to me whether these should be part of the same endpoint or more something specific to the themes endpoint

/wp/v2/themes/{theme}/global-styles

/wp/v2/global-styles/list

This one is already implemented in this PR (kind of, just missing query support) /wp/v2/global-styles

I'd like some input from @TimothyBJacobs to get things as close as possible to the REST API guidelines.

@spacedmonkey
Copy link
Member

This endpoint should really extend post controller and not be a custom endpoint. We can override anything we need to on that controller.

@youknowriad
Copy link
Contributor Author

This endpoint should really extend post controller and not be a custom endpoint

I thought about that, it only works if we limit it to the CPT (only server user modified settings and styles) which is still uncertain. #35801 (comment) and #35801 (comment)

Copy link
Member

@TimothyBJacobs TimothyBJacobs left a comment

Choose a reason for hiding this comment

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

Overall this looks good to me. I've left some feedback inline.

I think in this case, considering how custom the global styles API is, I think it is fine to extend the base controller instead of using WP_REST_Posts_Controller.

/wp/v2/global-styles/base => core+theme data for the active theme
/wp/v2/global-styles/merged => core+theme+user data for the active theme
It is not clear to me whether these should be part of the same endpoint or more something specific to the themes endpoint

Yeah, my preference would be for this to be linked to by the themes endpoint.

/wp/v2/global-styles/list
This one is already implemented in this PR (kind of, just missing query support) /wp/v2/global-styles

Yeah, the list should just be the collection endpoint.

@spacedmonkey
Copy link
Member

I think it is fine to extend the base controller instead of using WP_REST_Posts_Controller

Disagree. Much of this logic can be removed by extending this controller. Not to mention of all the filters and hooks in the post controller that are very useful.

@youknowriad youknowriad marked this pull request as ready for review October 26, 2021 09:41
@youknowriad
Copy link
Contributor Author

/wp/v2/global-styles/base => core+theme data for the active theme
/wp/v2/global-styles/merged => core+theme+user data for the active theme

Since these are going to be a separate endpoint, I'll leave them to their own PR.

For the Post Controller vs non Post Controller. I personally don't have a big preference here and it should be something we can change with impact on the API itself.

@TimothyBJacobs
Copy link
Member

I think it is fine to extend the base controller instead of using WP_REST_Posts_Controller

Disagree. Much of this logic can be removed by extending this controller. Not to mention of all the filters and hooks in the post controller that are very useful.

I'm not sure this is true. We'd need to be disabling essentially the entirety of how the posts controller works besides the title handling.

@jorgefilipecosta
Copy link
Member

jorgefilipecosta commented Oct 27, 2021

Hi @youknowriad,
I added a commit with changes:

Removed the defaults for settings and styles otherwise isset( $request['styles'] ) does not make sense. The request always contains styles. This change allows the users of the endpoints to change just settings or styles independently.

We have a complex issue, when unserializing in PHP a json object as an array with {settings: {} } it becomes {settings: [] } and then the client crashes everywhere. I made many changes related to this to avoid this issue namely replacing some usages of array() with new stdClass(), replacing some isset with ! empty, and using cleanEmptyObject on the client which is good anyway to avoid wasting the database with empty object keys anyway (otherwise when the user for example resets the color palette we would pass {settings: color: {} } and on the new load the editor would crash because {settings: color: [] } is invalid.

I added the required isGlobalStylesUserThemeJSON flag verifications.

I added a hardcoded version (config['version'] = WP_Theme_JSON_Gutenberg::LATEST_SCHEMA;) when saving so the content properly loads on the frontend. This is a temporary solution to get things going we need to handle versions properly.
We need to make decisions like the endpoint is dumb and just saves/passes the version received to the database as is and the client is responsible for properly migrating things. Or the endpoint always receives and passes the latest version, (this means it is not back-compatible with clients relying on a previous theme.json shape). But in this solution the client does not need to implement any migration logic, if an old theme.json shape is saved on the database, the endpoint can rely on the migration the server already has to render styles and pass the latest version to the client (independently of what is on the database the client would always receive the latest shape).

There is a remaining issue. If a global styles post is not already on the database the site editor crashes right away. Previously the call WP_Theme_JSON_Resolver_Gutenberg::get_user_custom_post_type_id(); would create a post if it did not exist. We need a solution to this issue before merging. I guess a possible solution would be something like we had before and if $global_styles_query does not contain a post we would create a post so we can return it. But I guess a better solution would be to create a post only when saving some custom user styles.

@jorgefilipecosta
Copy link
Member

Something like /themes/{name}/global-styles as @youknowriad proposed may work for themes.

Agreed.

I wonder how one would request the core theme.json? Maybe for the core, it is ok to use the hacky solution given that core theme.json does not require any merge, etc?

Sorry, to clarify, which solution are you referring to here?

For the hacky solution to retrieve the core theme.json would be to make an HTTP request directly to the static path where the core default theme.json is located.

@jorgefilipecosta
Copy link
Member

jorgefilipecosta commented Oct 27, 2021

Hey, I wanted to take a look at the naming of these endpoints all together. Given this and the related PR #35985 it looks like this is what we're aiming for:

  1. user data: wp/v2/global-styles/{ID}
  2. base data: wp/v2/themes/${THEME}/global-styles
  3. merged data: ?

I find the URL patterns not very clear: the first one only offers user data but is named as if was the whole merged data (core+theme+user); the second one is named after the theme but it actually returns core+theme data. It's also not clear to me how we're going to extend them should we need it: how are we naming a future endpoint that returns only the theme data for example?

An alternative would be a model where we only have core, theme, user endpoints (e.g.: wp/v2/global-styles/user, wp/v2/global-styles/theme, wp/v2/global-styles/core) as Jorge suggested. That's appealing, although it requires all the consumers to implement the merging logic (including mobile). I have a slight preference for not requiring this to consumers.

From the alternatives mentioned here, I'd still go with something along the lines of this model.

The issue I see with this model: wp/v2/global-styles/user, wp/v2/global-styles/theme, wp/v2/global-styles/core, is that it is dependent of the current theme. I may want to retrieve the user styles of another theme besides the active one, or the theme styles of a different theme.

That said I imagine a something like wp/v2/global-styles/user/{postid}, wp/v2/global-styles/theme/{theme-slug}, wp/v2/global-styles/core/ would work very well.
And if we need merged wp/v2/global-styles/merged/{theme-slug}/{postid} may also do the trick. But I'm not sure we need an endpoint for the merged styles. Mobile will need to have the merge logic anyway so the change the users are doing can be live previewed. And mobile can reuse our JS merge engine.

@youknowriad
Copy link
Contributor Author

I guess a possible solution would be something like we had before and if $global_styles_query does not contain a post we would create a post so we can return it.

Yes, let's start with this solution first and iterate on it later if needed.

Copy link
Member

@jorgefilipecosta jorgefilipecosta left a comment

Choose a reason for hiding this comment

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

The issues I identified are fixed and I think this PR can be merged and when needed we can iterate on it 👍

@youknowriad youknowriad force-pushed the add/bootstrap-global-styles-endpoint branch from efd7219 to b91a650 Compare October 28, 2021 08:58
@youknowriad youknowriad changed the title Start a Global Styles endpoint and use it in the site editor Add a Global Styles endpoint and use it in the site editor Oct 28, 2021
@youknowriad youknowriad merged commit 3bcfe24 into trunk Oct 28, 2021
@youknowriad youknowriad deleted the add/bootstrap-global-styles-endpoint branch October 28, 2021 09:36
@github-actions github-actions bot added this to the Gutenberg 11.9 milestone Oct 28, 2021
} else {

$wp_query_args = array(
'post_status' => array( 'publish' ),
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
'post_status' => 'publish',

),
);
$global_styles_query = new WP_Query( $wp_query_args );
$id = count( $global_styles_query->posts ) ? $global_styles_query->posts[0]->ID : null;
Copy link
Member

Choose a reason for hiding this comment

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

We could have just request 'fields' => 'ids' in the WP_Query and no need for this $global_styles_query->posts[0]->ID, you could just do this.

$id  = !empty( $global_styles_query->posts ) ? array_shift( $global_styles_query->posts ) : null;

*
* @var string
*/
protected $post_type;
Copy link
Member

Choose a reason for hiding this comment

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

What is this property used for?

@spacedmonkey
Copy link
Member

I am confused. The global style post type is registered to the REST API.

'show_in_rest' => true,
'rest_base' => '__experimental/global-styles',

Is this REST API used for anything? If not this should be disabled no? CC @TimothyBJacobs ?

@youknowriad
Copy link
Contributor Author

Great suggestions @spacedmonkey I opened a follow-up PR here to address these #36071

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Core REST API Task Task for Core REST API efforts Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants