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

A way for plugin developers to access the editor state? #2473

Closed
lumberman opened this issue Aug 19, 2017 · 7 comments · Fixed by #4105
Closed

A way for plugin developers to access the editor state? #2473

lumberman opened this issue Aug 19, 2017 · 7 comments · Fixed by #4105
Labels
[Feature] Extensibility The ability to extend blocks or the editing experience [Type] Question Questions about the design or development of the editor.

Comments

@lumberman
Copy link

Hello,
Is there any way to access the editor state or any system of events that we can act on?
I'm talking about events like:

  • Block focused
  • Block setting adjusted
  • Settings panel opened

Does react has any mechanism for accessing inner state from the outside?

Thanks for clarifications.

@karmatosed karmatosed added the [Type] Question Questions about the design or development of the editor. label Sep 5, 2017
@aduth aduth added the [Feature] Extensibility The ability to extend blocks or the editing experience label Sep 5, 2017
@aduth
Copy link
Member

aduth commented Sep 5, 2017

Related conversation from Slack: https://wordpress.slack.com/archives/C02QB2JS7/p1502904266000534

Within the codebase, the interactions you mention are observed as Redux actions. Most of these are encapsulated as action creators in editor/actions.js. Currently this is not exposed publicly for plugins to consume, but it may be as simple as adding to a window global or a globally-exposed editor instance which plugins could then subscribe to.

Other ideas around extensibility are also well-surfaced by @youknowriad's comment at your related issue #2474 (comment) .

@lumberman
Copy link
Author

Copy/Paste from Slack for the reference:

1- We still need to figure “extension” points to existing blocks.

  • What’s already possible is “unregistering a block” and registering a modified version of it
  • There are some explorations around decorators that could serve as a way to provide extension points to several blocks Try: Components decorator extensibility pattern #1023
    but this question is not settled yet

Given the way React context works, blocks technically have access to the full Redux store. We don’t expose this first-class, nor do we make available the action creators which would more easily allow manipulating state, but it is there. Might be worth discussing the specific use-cases, and whether this is a pattern we want to formalize
(if you use react-redux connect, you can gain access to and dispatch to the store https://github.com/reactjs/react-redux )


I imagine using React-Slot-Fill for sidebar type rendering, adding something like wp.editor.registerFill( slotName, Component ). That or something with the proposed hooks package WordPress/packages#13

@dsifford
Copy link
Contributor

dsifford commented Sep 6, 2017

Subscribed to this thread.

@aduth Kindly directed me here. I was a part of that conversation he referenced. I'm still very interested in brainstorming this as well.

To add a bit more food for thought: (Warning: this is a very "high-level" idea, so bear with me. I'm sure there's technical issues that will appear somewhere that makes this more challenging)...

Consider a system like this:

A plugin author registers a custom toolbar button for a given list of post-types (for the sake of example, let's choose "paragraph" and "heading").

After registering this toolbar button, the plugin author then can attach middleware handlers to a basic set of event handlers on these blocks (e.g., onChange, onFocus, onBlur, etc) and when those handlers are called on the blocks themselves, the event is first passed through the other plugin's (the one who registered the toolbar button) middleware handlers of the same name.

This would benefit me in two ways (recall that my plugin deals with managing academic citations):

  1. I would be able to make insertions of citations at the cursor position when the user presses the toolbar button.
  2. I would be able to react to a change in state of the citations when one is deleted during the middleware handler.

One area that is still left to figure out though is for the following scenario....

[BLOCK]
Content with a citation. 1
[/BLOCK]
[BLOCK]
More content with another citation. 2
[/BLOCK]

If the user deletes citation 1 in the first block, my plugin will be able to be immediately aware of the change, however the adjustment of citation 2 won't be able to happen under the above circumstances until the user modifies content somewhere in block 2.

The only way that I'd be able to do that would be if there was some way to notify/trigger the onChange handler of block two outside of block 2 so that the adjustment of the citation (from 2 to 1) can occur.


Hope that makes sense! Again, just food for thought here. Please, by all means tear that idea apart 😝

@dsifford
Copy link
Contributor

dsifford commented Sep 6, 2017

Speaking more about that last issue... On the other hand, if I instead just serialized each citation with a unique ID instead of the content of the citation itself, it would never have to be re-parsed in the editor if I could parse each of them like how a block is parsed.

So, the same scenario above would be handled like this:

Serialized:

[BLOCK]
Content with a citation. <!-- citation { "id": 123456 } -->
[/BLOCK]
[BLOCK]
More content with another citation. <!-- citation { "id": 67890 } -->
[/BLOCK]

Parsed:

[BLOCK]
Content with a citation. 1
[/BLOCK]
[BLOCK]
More content with another citation. 2
[/BLOCK]

If citation 1 is deleted, I still have all the information I need to re-render ("parse") the actual citation itself in the other blocks.

Edit: My only issue with doing it this way would be that users would then be permanently vendor-locked into using my plugin. If they were to delete it at any point in the future, they'd lose all their citations. That's one of the main reasons why I created the plugin in the first place.

@aduth
Copy link
Member

aduth commented Sep 7, 2017

Edit: My only issue with doing it this way would be that users would then be permanently vendor-locked into using my plugin. If they were to delete it at any point in the future, they'd lose all their citations.

Worth noting that this was one of the ideas behind serializing blocks as HTML, since the same is true of any block: If the plugin implementing that block should later be disabled, the content shouldn't suddenly disappear. Applying this to your use-case, I might imagine a citation is something akin to a nested, inline block. The behavior of nested block is tracked formally at #428 and ties largely into site/layout building, but the idea of an inline block is quite specific and useful to the flow of post authoring. Needless to say, the design and UX surrounding this behavior has not yet been well explored.

To your ideas of middlewares and block extension generally, I've left a comment at #2474 (comment) with some thoughts I've had on my mind lately.

@lumberman
Copy link
Author

@youknowriad #4105 doesn't allow to access the state of the editor as in my initial question.
Is there a reason this thread closed?
Thank you.

@youknowriad
Copy link
Contributor

#4105 allows access to the state of the editor, but we do not want to allow access to everything to be able to break compatibility. What's remaining is to decide which selectors to make available. The mechanism is there so I'm considering the issue closed. We can expose selectors per use-case now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Extensibility The ability to extend blocks or the editing experience [Type] Question Questions about the design or development of the editor.
Projects
None yet
5 participants