Skip to content

Instantly share code, notes, and snippets.

@ericandrewlewis
Last active January 2, 2016 10:29
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ericandrewlewis/8290246 to your computer and use it in GitHub Desktop.
Save ericandrewlewis/8290246 to your computer and use it in GitHub Desktop.
WordPress Post Meta ideas
<?php
/**
* Post Meta Box view/controller class.
*
* Extends from a form object base class.
*
* Creates a meta box. Fields can be related to the meta box, but
* all business logic lives within the field object.
*/
class WP_Post_Meta_Box extends WP_Form_Object {
function __construct() {
// Register object-specific UI
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
// Register data saving handler.
add_action( 'save_post', array( $this, 'save' ), 10, 2 );
}
/**
* Register a meta box.
*/
function add_meta_box() {}
/**
* Output the contents of the meta box.
*/
function metabox_callback() {
$this->render_form();
}
/**
* Render input elements for all related fields.
*/
function render_form() {
foreach ( $this->get_fields() as $field ) {
$field->render_input_element();
}
}
/**
* Save data or each field according to the object's data model.
*/
function save( $post_id, $post ) {
foreach ( $this->get_fields() as $field ) {
$this->save_field( $field );
}
}
/**
* Save method specific to the object type.
*/
function save_field( $field ) {
global $post;
update_post_meta( $post->ID, $field->slug, $this->get_field_value( $field ), true );
}
/**
* Retrieve a user-submitted value for a field.
*
* This may need to call the field object/class, depending how
* $_POST variable names are built.
*/
function get_field_value( $field ) {}
/**
* Get field objects related to this form object.
*/
function get_fields() {}
}
add_action( 'init', 'register_custom_fields' );
function register_custom_fields() {
register_field( array(
'objects' => array( 'post', 'page' ),
'slug' => 'background_color',
'type' => 'color', // Relates to a pre-defined class.
'auth_callback' => 'callback_function',
'sanitization_callback' => 'sanitization_function',
) );
}
/**
* Field registration.
*
* Abstracted from the UI view class, so that the field's business logic
* and data describing it can be accessed independently.
*
* Data about fields is stored in a nested array.
*/
function register_field( $args ) {
global $object_fields;
// Parse args with defaults...
// Sanitize data...
if ( is_array( $args['objects'] ) {
foreach ( $objects as $object_type ) {
$object_fields[$object_type][] = array(
// Add data...
);
// register_meta etc depending on object type...
}
}
}
add_action( 'init', 'register_form_containers' );
/**
* Register form contianer.
*/
function register_form_containers() {
// Insantiate a container.
$container = new WP_Post_Meta_Box();
// Relate a registered field to the container.
$container->add_field( array( 'slug' => 'background_color' ) );
}
/**
* Text input class. Essentially, a view.
*
* Provides form element HTML markup, script enqueueing, etc.
*
* Relates to a field type.
*/
class Input_Text extends Input {}
@mikeschinkel
Copy link

Looks good for a first pass. Here are my concerns after a quick read:

  • WP_Post_Meta_Box - Do we want to couple a post form to a meta box?
  • Render - Do we want to use that term when little else in WordPress uses render()? Why not the_form()?
  • 'objects' - Shouldn't this be be 'post_types?' Or shouldn't they be qualified, i.e. 'post/post', 'post/page', 'user', etc.
  • Callbacks - Do we want use callbacks, or use a declarative approach combine with filters for customization?
  • $object_fields - Do we want to use globals vs. a private property as WP_Theme, WP_Screen, WP_Admin_Bar etc. are doing?
  • register_field() - Do we want it to process $args immediately, or store and continue w/later fixup after an 'init' hook?
  • WP_Form_Object - What does it look like?
  • _Object prefix - Do we need that? It's not used anywhere else in WordPress.
  • 'register_form_containers' - How/where does it register it's "containers?" Why is form_ an adjective for container; are WP_Post_Meta_Boxes not more specific forms? Why not register_form() in 'init'?
  • Input - Do we want to use the name Input for base class since HTML data entry fields include <input>, <select>, <textarea> and more?

@sc0ttkclark
Copy link

I think we agree on these, this will definitely be evolving and naming/args haven't been nailed down yet.

@jtsternberg
Copy link

Looking great. I understand this is pseudo-code, but agree with @mikeschinkel about not tying down metaboxes/forms to a post object.

@tomjn
Copy link

tomjn commented Mar 13, 2014

The use of globals here is unwarranted, and will lead to bugs, e.g.:

https://gist.github.com/ericandrewlewis/8290246#file-gistfile1-php-L56

What if I pass in a post ID to save_post that isn't the ID of $post ? What if for whatever reason $post is not defined? In this case there is no reason at all for the post_id not to be an argument, it's available in the calling method save_post.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment