WebDevStudios / oops-wp

A collection of abstract classes, interfaces, and traits to promote object-oriented programming practices in WordPress.
57 stars 9 forks source link

Issue/20 refactor editor block to simplify block registration #22

Closed jmichaelward closed 3 years ago

jmichaelward commented 5 years ago

There's kind of a lot to unpack here. This refactor reduces the amount of PHP scaffolding necessary to register a custom Gutenberg block in WordPress.

This class makes some assumptions that are potentially going to be particular to WDS, but it will expose an API via protected methods that extending classes could implement in order to have it work within their own setups.

Assumption 1

Your custom blocks have the following structure from root within a plugin or theme (directory names in bold):

This would work for a stand-alone ES5 implementation of a block structure. If individual block assets are being compiled, then we're also assuming this structure:

Block assets should be compiled, using whatever bundling app of your choice, into standalone directories for each blocks. The BlockName directories should be CamelCase and mirror the PSR-4 style classnames of the PHP files.

Assumption 2

By default, all blocks are registering an index.js file for controlling the block and an editor.css file for styling the block in the admin. Extending classes can set the $has_frontend_styles flag to true if they also have a style.css stylesheet for front-end rendering.

Additional Details

Generally, this class is very extensible and requires only a namespaced $name value in order to register it. WordPress will throw exceptions if the name value is missing or is not correctly namespaced in the fashion that it expects (e.g., /). Customization happens by way of the get_args method (which allows further customization for which properties get passed to register_block_type), get_additional_block_scripts (which allows further customization for which script dependencies a block relies, such as wp-editor, wp-i18n, wp-components, and so on), and get_additional_block_styles, which works the same way, except for styles instead of scripts (e.g., the editor_style value has a dependency on wp-edit-block, but there may be other scripts needed here or on the front-end as well.

The vast majority of the methods in the class are protected, so extending classes can modify elements of block registration to suit their needs. This does expose a significant API for the EditorBlock object, and that is one element I'd like to discuss - how extensible this object should be. Given the open-source nature of this project and that WDS has intended uses that may not mirror the broader community, I'd like to ensure that we're being good stewards of this project and being cognizant of when we're introducing new APIs that we might subsequently break in the future (related: this change very much breaks backward compatibility with the previous EditorBlock implementations).

jmichaelward commented 5 years ago

This PR would close #20

jmichaelward commented 4 years ago

@salcode If you have some time this week, I'd appreciate a look and some feedback on the proposed changes. I first released the EditorBlock class in OOPS-WP at the beginning of this year when I was trying to simplify the block registration process.

Essentially, the goal of this class is to make it easy for engineers to register new editor blocks with WordPress. At the bare minimum, a concrete instance of the EditorBlock class must provide a valid <vendor>/<block-name> string for the $name property, and a set of three asset files: index.js, editor.css, and style.css. The <block-name> portion of the $name property will get set as the root for the block assets, at /src/blocks/{<block-name>}.

I've added some changes to the class that allows it to check whether the package is in the plugins, mu-plugins, or themes directory of wp-content. The goal here is to allow the src/blocks portion of the path to be customizable, in case engineers desire alternate file hierarchies for their assets, and for them to override the $has_frontend_styles property on the chance they're developing a block that has no front-end (or those styles are managed some other way).

Once again, the goal for this structure is to make it easier for engineers to scaffold common WordPress structures. The hard part of Gutenberg development all happens in the JS file itself, so we want the focus there - not the process of scaffolding up resource paths.

I'm interested in getting your feedback on this, as well as @michealengland if wants to offer some thoughts from a front-end perspective.

michealengland commented 4 years ago

@jmichaelward While everything is fresh, I wanted to share some of the ideas from our discussion. I don't have much to contribute about the architecture / code currently as that isn't my strong area.

As we've been working on more and more Gutenberg projects it's become obvious that not each project / plugin startup is the same. In some cases here are some the scenarios I've ran into. It was mentioned about possibly using a singular block approach / multi-block approach depending on the need which changes structure.

On one of the current plugins I'm working on for WDS, we'll be utilizing WP Scripts with extra features on top of their tooling to handle styling.

Possible Block Scenarios

  1. Creating a plugin with a singular block setup to one entry point.

    • Good for one of block functionality types that are complex.
    • In cases where a block requires it's own Webpack entry point, it might be best keep these types of a blocks in a singular plugin.
  2. Creating a plugin that houses multiple blocks with a singular entry point and then using JS import / exports.

    • Using less entry points would cut back on JS Bundles and build times.
    • Using multiple blocks would mean less plugins per project which could save on the amount of NPM
    • installations that need to be maintained locally.
    • Ideal for handling multiple blocks such as a block-library for WDS.
  3. Handling of style.css / editor.css should be optional enqueues if they're present.

    • Some plugins will may not have/need a style.css or editor.css.
    • We will use tooling to extract all block css/scss into a singular style.css & editor.css in the built files directory. In some case there may no files generated.
  4. Moving blockdirectories back to /src and built files back to /build for WP Script defaults. I just wanted to mention this, even though we determined that there are challenges here from the PHP community & React / Gutenberg community utilizing the the same /src directory. I don't know if there is much here that would be an easy improvement that couldn't be managed on a per plugin basis.

Anyhow, thank you for your hard work on this and I'm looking forward to more collaboration.