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

Framework: Extract the block API to a generic block-api module without global registration #2182

Closed
wants to merge 1 commit into from

Conversation

youknowriad
Copy link
Contributor

In our road to modularize the editor this PR is huge step but I think it can't be broken into smaller PRs. In this PR I create a new module blockscore that contain what we had before in blocks/api except the registration: Parsing, Serializing, Factory, PastHandler...

But all these methods don't rely on the globally registered blocks anymore, they take as an argument a config with the following shape:

const config = {
  blockTypes: [],
  fallbackBlockName: 'core/freeform',
};

Registering the blocks has only one purpose: declare that a block has been registered in WP but to make the blockTypes available in the editor, we need to provide the settings object above to the root element of the Editor (EditorSettingsProvider).

This resolves previous concerns about the global usage expressed here #336 and #1132 (comment)

This PR has a side effect of reducing the role of the blocks module to registering the default blocks essentially. There’s no real reason to keep this module separate from the editor module. As a follow-up I propose to merge them (before extracting a generic block Editor Component maybe)

Caveats:

  • I had to reintroduce the editorSettings to the redux store because of their usage in the effects. Extracting a generic block editor will help us remove this (see Framework: Extract the block editor from the editor chrome to make it reusable #2065 as an example)
  • The module name is blockscore because our current setup don't work well with dashes in the module name (should be easy to rename when necessary). I'm hoping to rename it just blocks once we merge blocks and editor

Please help review this quickly since this will be hard to keep updated without an enormous amount of conflicts.

Testing instructions
Verify that everything is working as expected :)

@youknowriad youknowriad added the Framework Issues related to broader framework topics, especially as it relates to javascript label Aug 3, 2017
@youknowriad youknowriad self-assigned this Aug 3, 2017
@nylen
Copy link
Member

nylen commented Aug 3, 2017

"block score"? "blocks core"? Let's call it block-api instead.

@nylen
Copy link
Member

nylen commented Aug 3, 2017

There’s no real reason to keep this module [the library of blocks] separate from the editor module.

I'd propose calling this block-library instead. But I agree that is a task for a separate PR :)

@aduth
Copy link
Member

aduth commented Aug 3, 2017

Thinking out loud here and continuing conversation from #2119 (comment), as this was on my mind yesterday. I started to question: What is a block without an editor? One cannot exist without the other. But indeed we made a decision early on to split out blocks into its own module because we wanted them to be agnostic to the specific editor, in our case the post editor we're building. But if we're now discussing extracting the core editor bits (#2065), should we not reevaluate whether it makes sense that the block core be independent from the editor core, or should instead seek to converge them?

@youknowriad
Copy link
Contributor Author

should we not reevaluate whether it makes sense that the block core be independent from the editor core, or should instead seek to converge them?

Not against merging them but at the moment the editor is not the editor-core, it's everything. So this PR extracts blocks-core. Once we extract editor-core we can decide if these two belong together or not.

@youknowriad
Copy link
Contributor Author

"block score"? "blocks core"? Let's call it block-api instead.

I'm ok with that, blockapi then :)

@aduth
Copy link
Member

aduth commented Aug 3, 2017

If we're splitting a blocks "core" from blocks with the intent that what would remain of blocks is to be merged into an editor core anyways, why would we even take the step of creating a separate core instead of just moving out the bits that aren't relevant as "core" from blocks. i.e. it sounds like you're suggesting we'll have block-api, and then eliminate blocks. Why can't we just keep the core as blocks?

I think we're getting a little ahead of ourselves...

@youknowriad
Copy link
Contributor Author

I'm suggesting we create blocks-api in this PR and rename it later to blocks once we merge what's currently remaining in blocks into editor. I just don't want this PR to be bigger.

@youknowriad
Copy link
Contributor Author

Anyway, I think I'm missing something obvious but can anyone tell me why the JS tests are failing?

@youknowriad
Copy link
Contributor Author

Ok so renamed the module blockapi and fixed the JS unit tests. Should be better now

@nylen
Copy link
Member

nylen commented Aug 3, 2017

Let's go with block-api with a hyphen separator for readability.

I haven't reviewed this in detail, but at a high level the changes are reasonable, and removing the global state from the block registration API makes sense.

I'm suggesting we create blocks-api in this PR and rename it later to blocks once we merge what's currently remaining in blocks into editor. I just don't want this PR to be bigger.

I am not so convinced about this part.

I think we should merge this PR and continue to discuss the next steps.

@youknowriad
Copy link
Contributor Author

youknowriad commented Aug 4, 2017

@nylen Can't you hyphen, right now. I haven't taken a deep look to this, but for some reason, our build fails. Will see if I can fix it.

Edit: I don't know what happened the first time I tried, but block-api worked like a charm. Updated.

@youknowriad youknowriad force-pushed the drop/global-block-types branch 3 times, most recently from 282b086 to 38131e3 Compare August 4, 2017 09:24
@youknowriad
Copy link
Contributor Author

I think I'll merge this right after today's release.

@youknowriad youknowriad force-pushed the drop/global-block-types branch 2 times, most recently from 11d6c69 to 836df0e Compare August 4, 2017 15:08
@codecov
Copy link

codecov bot commented Aug 4, 2017

Codecov Report

Merging #2182 into master will increase coverage by 0.08%.
The diff coverage is 33.33%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #2182      +/-   ##
==========================================
+ Coverage   26.44%   26.53%   +0.08%     
==========================================
  Files         157      158       +1     
  Lines        4851     4892      +41     
  Branches      819      820       +1     
==========================================
+ Hits         1283     1298      +15     
- Misses       3015     3041      +26     
  Partials      553      553
Impacted Files Coverage Δ
block-api/paste/strip-attributes.js 100% <ø> (ø)
blocks/library/button/index.js 26.66% <ø> (ø) ⬆️
blocks/library/text-columns/index.js 33.33% <ø> (ø) ⬆️
blocks/library/pullquote/index.js 33.33% <ø> (ø) ⬆️
blocks/library/table/index.js 36.36% <ø> (ø) ⬆️
blocks/library/freeform/index.js 100% <ø> (ø) ⬆️
blocks/library/audio/index.js 36.36% <ø> (ø) ⬆️
block-api/validation.js 94.33% <ø> (ø)
block-api/source.js 95.45% <ø> (ø)
block-api/paste/remove-spans.js 77.77% <ø> (ø)
... and 38 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c8c8078...1f23e41. Read the comment docs.

@mtias
Copy link
Member

mtias commented Aug 4, 2017

I'd like to give this a look, but won't be able until next week.

@nylen
Copy link
Member

nylen commented Aug 5, 2017

I thought of a reason not to do this: prohibiting plugins from registering blocks in the core namespaces.

This is much easier to achieve if our registered blocks live in the same ES6 module as the block API, because then we can use an internal flag that is not exported out of that module. See #2241 - the approach taken there would no longer work after this PR.

I think we can probably achieve the main goal of this PR ("don't rely on the globally registered blocks anymore") without creating the new block-api module.

@youknowriad
Copy link
Contributor Author

@nylen I don't see why the approach in #2241 won't work with this PR, The global variable and the registration API are still in the same module.

@youknowriad
Copy link
Contributor Author

@mtias do you mind taking a look at this, I'd like to merge it soon in the week :)

@nylen
Copy link
Member

nylen commented Aug 7, 2017

@nylen I don't see why the approach in #2241 won't work with this PR, The global variable and the registration API are still in the same module.

Because this flag is completely internal to the blocks module, it is not accessible by third-party code.

In this PR the flag would be internal to the block-api module. So the blocks module - which registers the blocks for the editor - cannot use it.

In order to achieve "don't rely on the globally registered blocks anymore", why do we need to split the blocks module in two? Why should the block API be separate from the blocks that will use it most often?

@youknowriad
Copy link
Contributor Author

@nylen Registration is not part of the block-api module so why should we declare this variable in this module?

Why should the block API be separate from the blocks that will use it most often?

Because the block API is used by a generic Block Editor while the registration and the blocks are WP specific. A potential generic editor module, let's call it "editor-core" will be dependent on the "block-api" module but do not depend on the "blocks" module, and the final "blocks" module will depend on both "block-api" and "editor-core", so this PR resolves the inter-dependency issue.

"block-api" and "editor-core" could be merged later (like suggested by @aduth) since they'll be both low-level modules but if we merge "blocks" and "block-api", this means we'll have to merge everything in a unique module.

@nylen
Copy link
Member

nylen commented Aug 8, 2017

Registration is not part of the block-api module so why should we declare this variable in this module?

I assumed that registerBlockType would be part of block-api since it's the main function of our block API today.

What role does registerBlockType play after this PR? I expected that the changes here would make it accept and modify a config object rather than a global config.

@youknowriad
Copy link
Contributor Author

What role does registerBlockType play after this PR? I expected that the changes here would make it accept and modify a config object rather than a global config.

It has the same role as today which is: "declare that a block type in WordPress"
but For an editor to actually use this block type, it has to be included in its config when initializing the editor (see EditorSettingsProvider). For now, the init function just retrieves all the registered blocks to build this config object, but later a PostEditor, a FieldEditor, a CustomizationEditor, a CPT Editor could pick different block types.

@youknowriad
Copy link
Contributor Author

The rebase today was very difficult to do, I'd really appreciate some help to move this forward.

@nylen
Copy link
Member

nylen commented Aug 10, 2017

but later a PostEditor, a FieldEditor, a CustomizationEditor, a CPT Editor could pick different block types

Won't all of these things want basically the same block types, with some minor variation that could be easily captured in the block settings? e.g. { showInContent: false, showInCustomizer: true }

Because the block API is used by a generic Block Editor while the registration and the blocks are WP specific. A potential generic editor module, let's call it "editor-core" will be dependent on the "block-api" module but do not depend on the "blocks" module, and the final "blocks" module will depend on both "block-api" and "editor-core", so this PR resolves the inter-dependency issue.

I'm not convinced that this distinction will actually be so valuable in practice: we're not building a generic block editor, we're building a WP block editor.

@@ -133,9 +133,15 @@ function gutenberg_register_scripts_and_styles() {
filemtime( gutenberg_dir_path() . 'components/build/index.js' )
);
wp_register_script(
'wp-blocks-api',
Copy link
Member

Choose a reason for hiding this comment

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

I think this should be wp-block-api under the current structure of the PR

@@ -5,6 +5,7 @@
'components',
'utils',
'blocks',
'blocksapi',
Copy link
Member

Choose a reason for hiding this comment

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

I am not sure what this should be but blocksapi isn't used anywhere else in this PR

@youknowriad
Copy link
Contributor Author

Won't all of these things want basically the same block types, with some minor variation that could be easily captured in the block settings? e.g. { showInContent: false, showInCustomizer: true }

That's exactly how I see it too, but to avoid filtering the blocks in all the places we use the block types, we only filter them once, once initializing the editor.

I'm not convinced that this distinction will actually be so valuable in practice: we're not building a generic block editor, we're building a WP block editor.

Good point, but despite the architectural benefits genericity brings, there are practical benefits too. I'd imagine us needing to load multiple block editors in the same page (say one for the editor, one for a meta-box) or multiple ones in the customizer for different areas. It's not possible right now because all the editor's state is mangled with the Application state (posts, ....). This PR is the first step to bring this genericity.

@BE-Webdesign
Copy link
Contributor

BE-Webdesign commented Aug 11, 2017

it sounds like you're suggesting we'll have block-api, and then eliminate blocks. Why can't we just keep the core as blocks?

I think this is relevant, and from a quick glance it looks like this is not what is happening.

Overall this looks good, but would need more time to review this.

@youknowriad youknowriad changed the title Framework: Extract the block API to a generic blockscore module without global registration Framework: Extract the block API to a generic block-api module without global registration Aug 14, 2017
@youknowriad
Copy link
Contributor Author

closing this one, it needs more thinking

@youknowriad youknowriad deleted the drop/global-block-types branch September 18, 2017 00:18
@gziolo gziolo added the [Feature] Extensibility The ability to extend blocks or the editing experience label Feb 2, 2018
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 Framework Issues related to broader framework topics, especially as it relates to javascript
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants