You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
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?
The text was updated successfully, but these errors were encountered:
@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.
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:Adding a reducer could look like this:
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 awp.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
The text was updated successfully, but these errors were encountered: