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

Provides functions for introducing OO-focused Meta Boxes into OOPS-WP-based Plugins #18

Closed tommcfarlin closed 3 years ago

tommcfarlin commented 5 years ago

What's This Do?

This PR introduces Structure\Content\MetaBox into OOPS-WP. The goal is to make it easy to introduce meta boxes into OOPS-WP-powered plugins.

This is specifically related to issue #16.

How Does It Work?

To use this class, you need to do the following in your code (sample code provided later in this description, when necessary):

  1. Define a MetaBoxService.
  2. Instantiate the class that extends the MetaBox class in the MetaBoxService.
  3. Add it to the plugin that extends the ServiceRegistrar.

The rest of the plugin should pick up what you need from there.

Sample Code

MetaBoxService

This class must extend Service. Note that it's using MetaBoxDemo which is the concrete class that I'll demonstrate later in this comment for rendering the meta box.

Note that three values should be passed into the constructor with the other three being optional. This is documented in the MetaBox class itself.

namespace WebDevStudios\OopsWP\Service;

use WebDevStudios\OopsWP\Structure\Service;
use WebDevStudios\OopsWP\Demo\MetaBoxDemo;

class MetaBoxService extends Service {

    private $content_types = [
        WebDevStudios\OopsWP\MetaBoxDemo::class,
    ];

    public function register_hooks() {
        add_action( 'add_meta_boxes', [ $this, 'register_content_types' ] );
    }

    public function register_content_types() {
        ( new MetaBoxDemo( 'example', 'Example', [ 'post' ] ) )->register();
    }
}

MetaBoxDemo

This is a simple class. All it must do is:

  1. extend MetaBox
  2. and implements Renderable

From there, you can customize the render function as you need to display the contents of the meta box. This can be something as simple as the following:

namespace WebDevStudios\OopsWP\Demo;

use WebDevStudios\OopsWP\Utility\Renderable;
use WebDevStudios\OopsWP\Structure\Content\MetaBox;

class MetaBoxDemo extends MetaBox implements Renderable {
    public function render() {
        echo 'Calling Render';
    }
}

Or it can be more involved where you have a template located in Views and want to render that information to the screen:

public function render() {
    include_once 'Views/meta-box.php';
}

What About Saving Data?

To save data with your meta box, you'll need to update the register_hooks function in your MetaBoxService so that it also includes the following second line:

public function register_hooks() {
    add_action( 'add_meta_boxes', [ $this, 'register_content_types' ] );
    add_action( 'save_post', [ $this, 'save' ] );
}

Note, however, that the save method as called above expects that the serialization functionality exists in the service when, in fact, it might make more sense to have it on the MetaBoxDemo itself. To do this, the MetaBoxDemo would need to be a property of the service and the function above would be redefined as:

public function register_hooks() {
    add_action( 'add_meta_boxes', [ $this->meta_box, 'register_content_types' ] );
    add_action( 'save_post', [ $this->meta_box, 'save' ] );
}

But these can be for points of discussion.

For Discussion

jmichaelward commented 5 years ago

@tommcfarlin, thanks for putting this effort into a new abstract class for OOPS-WP! I love the idea of having an easy-to-extend class for quickly creating metaboxes in WordPress. I'm going to leave some comments in the file – much of it will be conceptual for discussion as we consider how this will get used by the broader team, hence why I'd like this review to be a topic for our next BEE scrum. Overall, I think this is a great start, and I'm looking forward to getting this rolled into the library.

Edit: you raised a couple of points for discussion in your ticket description, and some of those items I'll be touching upon within the comments of the file itself.