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

Client side data APIs for Gutenberg (and WordPress in general) #3805

Closed
atimmer opened this issue Dec 4, 2017 · 1 comment
Closed

Client side data APIs for Gutenberg (and WordPress in general) #3805

atimmer opened this issue Dec 4, 2017 · 1 comment
Labels
[Feature] Annotations Adding annotation functionality

Comments

@atimmer
Copy link
Member

atimmer commented Dec 4, 2017

Problem

Because Gutenberg takes charge of the UI completely plugin authors can no longer retrieve their data from the DOM. In Yoast SEO we used to rely on the DOM to get all kinds of data. Examples include content, title, taxonomies and the slug.

The DOM was never a great way to get the data we needed. But it was the only way. The clientside in WordPress has long had a lack of good data APIs. This is why a lot of stuff breaks when page builders replace the whole editor. Because TinyMCE is completely removed at that point, there is no way to get to the content data.

So with Gutenberg, we are forced to start solving this problem. I think this is a great time to start thinking about client-side data APIs for WordPress.

Approaches

Redux / Observable

Gutenberg manages its own data in a Redux store. So a simple approach could be exposing a Redux-like API on a global. The first thing that comes to mind is a wp.data global with the following abilities:

  • Listen to the store.
  • Dispatch actions.
  • Connect React elements to the store using react-redux.
  • Add custom actions.
  • Add custom reducers.

Adding a reducer could look like this:

wp.data.addReducer( 'plugin-name', ( store, action ) => {
	// Standard reducer behaviour
} );

This way plugins have their own little reducer 'namespace'. This means that plugin state will always be in sync with core state. For example: If a block is removed, in Yoast SEO we know which content analysis feedback we need to remove based on that.

This could also work on other screens in the admin.

Higher level / Simple APIs

For some people, Redux might be too granular/low-level/complicated. So it would be good to also have higher level APIs that plugin authors can use. My first thought when thinking this up was having a wp.data.getPost() which would return all the post data. In the context of Redux, this could mean that it is just a selector on the state data.

So in Gutenberg the wp.data.getPost() function would serialize the blocks to return a post object like it is on the server. We could also have a wp.data.getPostBlocks() function that would return an array of blocks with relevant data.

Thinking this out further, on the post overview page this could be a wp.data.getPosts() function which would return an array of the posts that are currently shown.

On decision that we at least need to make is if these simple APIs should be synchronous or asynchronous. An asynchronous approach would give us much more freedom in where to get the data from. It would make APIs possible that return 'future' data. Such as a wp.data.getNextPage().getPosts(), this would then do a REST API request (or GraphQL 😄).

Other ideas

  • Saving data: The above ideas are only about retrieving data. We also need to think about how to save data. In Yoast SEO we have a snippet preview which contains a slug field which should be the same as the WordPress' slug field.
  • Everything could be an Observable: We would have a Post observable, a content observable, a title observable. For a philosophical talk about this, check What if the user was a function?
@tg-ephox
Copy link
Contributor

tg-ephox commented Dec 6, 2017

@atimmer I have been exploring the use of hooks for Footnotes here. The next step seems to be to allow access to redux state from the hook (for save post processing in this instance). For this use case it would be handy to have some extra state, a map of block to footnotes. Parsing post_content can initialise this map, and listening to block actions can keep it in sync, as you describe above.

I've seen a couple of issues in regards to annotations and these seem to cross over with functionality that footnotes requires. Might be good to touch bases on slack.

@omarreiss omarreiss added the [Feature] Annotations Adding annotation functionality label Mar 26, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Annotations Adding annotation functionality
Projects
None yet
Development

No branches or pull requests

4 participants