Skip to content
This repository has been archived by the owner on Nov 6, 2022. It is now read-only.

Refactor 'Edit Block' UI to use React #469

Open
kienstra opened this issue Nov 4, 2019 · 8 comments
Open

Refactor 'Edit Block' UI to use React #469

kienstra opened this issue Nov 4, 2019 · 8 comments

Comments

@kienstra
Copy link
Collaborator

kienstra commented Nov 4, 2019

The 'Edit Block' UI has served the plugin well so far. There have been very few bugs, and I think it's a great UI.

edit-block-ui

But as the UI adds more features, it's going to get harder to maintain. There's a jQuery-based file for it that's over 500 lines.

And some things could be really hard without React. Like Field conditions.

I think there's a risk that if the jQuery-based file file gets much bigger, we might never find time to refactor it.

Still, this might not reduce the lines of code, I just think it'll be easier to maintain. And it could have more bugs than the previous implementation, which had very few.

I'm not proposing here that we change the actual design or UI any more than necessary.

@kienstra
Copy link
Collaborator Author

kienstra commented Nov 4, 2019

I think the first option to consider would be using a basic Gutenberg setup with:

diff --git a/php/post-types/class-block-post.php b/php/post-types/class-block-post.php
index e52a3fb..3a5cc81 100644
--- a/php/post-types/class-block-post.php
+++ b/php/post-types/class-block-post.php
@@ -214,7 +214,8 @@ class Block_Post extends Component_Abstract {
                        'hierarchical'  => true,
                        'capabilities'  => $this->get_capabilities(),
                        'map_meta_cap'  => true,
-                       'supports'      => array( 'title' ),
+                       'supports'      => array( 'title', 'editor' ),
+                       'show_in_rest'  => true,
                );
 
                register_post_type( $this->slug, $args );

no-blocks-used

The 'Document' panel has most of the functionality as before.

But the 'block' UI would need a lot of consideration. Of course, we wouldn't want the ability to add any block. This UI only allows adding fields.

@kienstra
Copy link
Collaborator Author

kienstra commented Nov 4, 2019

Update: per the comment below, it'd probably be better to disable block editing entirely.

By calling something like:

wp.blocks.setDefaultBlockName( false );

...we could prevent users from being able to simply type text into the UI (creating a paragraph block). This would then display:

add-block-to

Then, maybe this could add something like a 'block_lab_field' block, and that would be the only block available.

@kienstra
Copy link
Collaborator Author

It looks like it's possible to disable block editing, as that doesn't apply to this:

wp.data.dispatch( 'core/editor' ).updateEditorSettings( { richEditingEnabled: false } )
.editor-post-text-editor,
[for="post-content-1"] {
	display: none;
}

block-editor

@kienstra
Copy link
Collaborator Author

kienstra commented Nov 18, 2019

In the PHP rendering function for the metabox circled above, it could simply output a container for the metabox, like <div id="bl-field-editor"></div>, and maybe a JavaScript const with any needed data.

Then, a separate script could render the metabox:

render(
	<FieldEditor>,
	document.getElementById( 'bl-field-editor' )
);

The new <FieldEditor> component would render the meta box. I'd probably port admin.block-post.js into that (or child components of it).

This wouldn't require a fundamental change to the block_lab post structure, like if we used a 'Field' block for each field.

@lukecarbis
Copy link
Member

@kienstra That sounds like a really good solution!

@kienstra
Copy link
Collaborator Author

Thanks, Luke!

@kienstra
Copy link
Collaborator Author

The metabox that's rendered as above can access and alter the post content directly.

For example:

const content = 'Brand new content here';
wp.data.dispatch( 'core/editor' ).editPost( { content } );
const blocks = wp.blocks.parse( content );
wp.data.dispatch( 'core/editor' ).resetEditorBlocks( blocks ); // Apparently this is needed so that the new content value isn't overwritten.

Then, the new content should be available with:

wp.data.select( 'core/editor' ).getEditedPostContent();

@kienstra
Copy link
Collaborator Author

kienstra commented Nov 23, 2019

This should ideally allow the meta box that was previously rendered with PHP to be rendered with React, as described above.

Just like in the PHP rendering function, how it gets the post and parses it:

$post = get_post();
$block = new Block( $post->ID );

...the React implementation could parse the post content from:

wp.data.select( 'core/editor' ).getEditedPostContent();

There are still several challenges, like getting around how Gutenberg handles metaboxes. This approach wouldn't need its actions, like REQUEST_META_BOX_UPDATES.

This would function more like an alternate post editor, not a meta box.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants