WordPress.org

Make WordPress Core

Opened 4 years ago

Last modified 9 months ago

#18179 new feature request

WP_Meta_Box

Reported by: koopersmith Owned by:
Milestone: Future Release Priority: normal
Severity: normal Version:
Component: Administration Keywords: has-patch 3.4-early
Focuses: Cc:

Description

Ryan, Nacin, and I would like to see a Meta Box class in 3.3. Let's make it happen.

Attached is a first pass (in plugin form, for ease). It provides a basic API and supports multiple instances. Instances are stored in a static meta box registry, which should require minimal interaction.

Keep in mind that meta boxes are not just registered on CPT pages — they are also used on the dashboard, in menus, and in custom UIs. The parent class should be suitable for each of these cases.

I think we should move caps to the main Meta Box class (and allow subclasses/instances to specify/override the cap through $args), and also provide $args to enable/disable any checks we perform before saving (e.g. autosave, etc).

It would also be interesting to integrate this with the proposed metadata API improvements.

See #15066 for prior discussion.

Attachments (6)

meta-box.php (7.8 KB) - added by koopersmith 4 years ago.
meta-box.2.php (7.7 KB) - added by hakre 4 years ago.
Some example code making the registry a singleton and more fluent.
18179.php (9.7 KB) - added by ericlewis 3 years ago.
meta-box.3.php (10.8 KB) - added by ericlewis 2 years ago.
Custom sanitization callback support added, with a default for generic form field types. Basic text and wp_editor meta field types added to begin with. Authorization callbacks supported, with a default of automatic authorization (if the user already has edit_published_post cap). Form rendering has defaults that can be overridden in a subclass.
meta-box.4.php (11.0 KB) - added by ericlewis 2 years ago.
add missing check for nonce existence before validating.
meta-box.5.php (11.9 KB) - added by ericlewis 2 years ago.
Move meta field types into classes, which include their own rendering, sanitization, authorization, and script enqueueing methods.

Download all attachments as: .zip

Change History (89)

@koopersmith4 years ago

comment:1 @c3mdigital4 years ago

  • Cc chris@… added

comment:2 @billerickson4 years ago

  • Cc bill.erickson@… added

comment:3 @hakre4 years ago

Just some feedback while quickly scanning over the code:

WP_Meta_Box::registry()->add( $this ); - takes object instance

WP_Meta_Box::registry()->remove( get_class( $this ), $this->screen, $this->slug ); - has a totally different parameter setup.

It's easier if the correlating methods share the same parameter types and order.

And if you store the object instances hashed (e.g. spl_object_hash) inside the registry, it will reduce the code in the remove part drastically because you always have the right instance to remove by it's hash.

comment:4 @hakre4 years ago

If you need the flexibility to search by class and/or slug in the registry, create another function that can return that result as an array of object instances (e.g. find()). Then it's even more flexible and does provide the tool you're probably looking for.

@hakre4 years ago

Some example code making the registry a singleton and more fluent.

comment:5 @hakre4 years ago

I've added some example code which does show this. Aditionally I've moved the singleton logic from the meta box base class into the registry itself in case this makes sense.

If you want to make extending classes of the base class to call the parents constructor class you can make use of the following methodology:

  • Make the base constructor final
  • Make the base constructor call an init() method of the same instance.
  • Make that init() method within the base class an abstract method.

Extending classes then can initialize themselves inside the init() method instead of the constructor and must not take care any longer for initialization of the parent class.

comment:6 @jaredatch4 years ago

  • Cc jaredatch added

comment:7 @toscho4 years ago

  • Cc info@… added

comment:8 @sirzooro4 years ago

  • Cc sirzooro added

comment:9 @kawauso4 years ago

Related: #17515

comment:10 @travisnorthcutt4 years ago

  • Cc travis@… added

comment:12 @wpsmith4 years ago

  • Cc travis@… added

comment:13 @azizur4 years ago

  • Cc azizur added

comment:14 @ptahdunbar4 years ago

  • Cc trac@… added

comment:15 @WraithKenny4 years ago

  • Cc Ken@… added

comment:16 follow-up: @WraithKenny4 years ago

On the revision check of WP_CPT_Meta_Box: Sometimes authors intend revisions to receive metadata updates and restore metadata on post restore. It'd be nice to have a built in functionality for this in the API (or at least account for it).

Also, if the WP_CPT_Meta_Box is on an Edit screen with a nonce, the cap check wouldn't be necessary as Edit screen checks current_user_can( 'edit_post' ) prior to save_post and any other situations (Quick Edit, for example) won't pass the nonce check.

comment:17 @WraithKenny4 years ago

It'd be nice to include an optional Update/Save Ajax button and Ajax-handler registration.

Being able to specify whether the Meta Box should be added to default_hidden_meta_boxes should be incorporated.

comment:18 @jb5104 years ago

  • Cc jb510 added

comment:19 @sbressler4 years ago

  • Cc sbressler@… added

comment:20 @Tyrun4 years ago

  • Cc Tyrun added

comment:21 @nerrad4 years ago

  • Cc nerrad added

comment:22 @swissspidy4 years ago

  • Cc hello@… added

comment:23 @aaroncampbell4 years ago

  • Cc aaroncampbell added

comment:24 @destastic4 years ago

  • Cc dcox@… added

comment:25 @bainternet4 years ago

  • Cc bainternet added

comment:26 @jamalorg4 years ago

  • Cc jmlworld@… added

comment:27 @alex-ye4 years ago

  • Cc nashwanco_001@… added

comment:28 @prettyboymp4 years ago

  • Cc mpretty@… added

comment:29 @lumpysimon4 years ago

  • Cc piemanek@… added

comment:30 @tollmanz4 years ago

  • Cc tollmanz added

comment:31 @kovshenin4 years ago

  • Cc kovshenin@… added

comment:32 @witthansen4 years ago

  • Cc christopher.witt.hansen@… added

comment:33 @ryanduff4 years ago

  • Cc ryan@… added

comment:34 @GaryJ4 years ago

  • Cc gary@… added

comment:35 @nathanrice4 years ago

  • Cc ncrice@… added

comment:36 @nathanrice4 years ago

I'd like to try to contribute to this, somehow. This has been one of the larger pains in the process of building plugins and themes for us at StudioPress, I definitely concur that there is a need.

The only thing I'm unclear about is the scope. What exactly are you guys thinking in terms of what the class should actually do and handle? I feel like I might be able to work something up based on my experience, but a clear list of features would be a lot better than "let's just make it better."

Thoughts?

comment:37 @ryanduff4 years ago

Well with non-lead feature freeze originally slated for 9/14 and complete feature freeze on 9/21 this needs to move now. I agree that it its either a yes/no at this point and if something needs to be reworked, now is the time. If I can help out in any way to help get ensure this gets in for 3.3 let me know.

comment:38 @eduplessis4 years ago

  • Cc eduplessis@… added

comment:39 @nacin4 years ago

  • Keywords 3.4-early added
  • Milestone changed from 3.3 to Future Release
  • Type changed from task (blessed) to feature request

What exactly are you guys thinking in terms of what the class should actually do and handle?

This is what I was thinking.

Since we now have register_meta(), which includes both sanitization and authorization callbacks, it would be nifty if a method of WP_Meta_Box could wrap register_meta() and then register those pieces of meta against the meta box. We could even enforce sanitization callbacks. Then, there's no need to have anything that hooks into save_post -- whatever gets sent back will automatically be saved.

We'd also want form rendering, but that doesn't need to be too complex. Basic form fields are fine. Likewise, registering a field could potentially mean that A) basic fields are handled and B) so is the corresponding sanitization depending on the field and desired data type.

If all goes well though, there's no need to hook into add_meta_boxes(_$post_type), call add_meta_box(), write your own function to render things, then hook into save_post too. As much as I've gotten used to those steps, it can be tedious and has basically no abstraction.

Not a whole lot of iteration went into this ticket, especially since koopersmith has been on UI stuff for most of the cycle. We're going to need to punt this to 3.4, but I would love it if work started and continued uninterrupted during beta and RC, then the moment we branch, we can commit something awesome.

comment:40 @lgedeon4 years ago

  • Cc luke.gedeon@… added

comment:41 @jayarjo4 years ago

  • Cc jayarjo added

comment:42 @Tyrun4 years ago

  • Cc Tyrun removed

comment:43 @pauldewouters4 years ago

  • Cc pauldewouters added

comment:44 @marfarma4 years ago

  • Cc pauli.price@… added

comment:45 @koopersmith4 years ago

In [19320]:

Add reset CSS (clear) to the admin bar. props scribu. fixes #19260, see #18179.

comment:47 @johnbillion4 years ago

  • Cc johnbillion@… added

comment:48 @dwenaus4 years ago

  • Cc deryk@… added

comment:49 @husobj3 years ago

  • Cc ben@… added

comment:50 @dwenaus3 years ago

Is this going to make it into 3.4? it would be great to get this in there.

About adding form element rendering, as nacin mentions, this would be great to have. The | WPAlchemy MetaBox PHP Class seems to be the most mature in this respect, but maybe overkill as well. Do we pull the good stuff from there or write something new for form handling?

A number of other custom field / meta box libraries and plugins exist also:

A common need seems to be repeatable fields. It's such a common need it would be great if we could get that into the API. Beyond that repeatable field groups would be stellar, but maybe not for the first go.

And what about front end display (ie. | Views or | the loops) I'm guessing that is separate, but related.

comment:51 follow-up: @dwenaus3 years ago

and here is a very well put together elegant and simple plugin that might be just the thing: http://wordpress.org/extend/plugins/custom-field-suite/

comment:52 in reply to: ↑ 51 @lumpysimon3 years ago

and here is a very well put together elegant and simple plugin that might be just the thing: http://wordpress.org/extend/plugins/custom-field-suite/

I agree that plugin does have a nice UI and provides a very quick way to add custom fields, including the much-needed repeating fields, but it also adds six database queries per page and two new database tables (one of which duplicates data from the postmeta table), so is extremely unlikely to make it into core in anything like its current form.

comment:53 follow-up: @jb5103 years ago

What is the goal of this ticket at this point? There is a patch for registering a metabox, but nothing for building the actual box which is what I at least thought the goal was. I guess I'm wondering if "has-patch" is the right category for this at this point?

Personally I was hoping for something like the @norcross, @jaredatch, @billerickson CMB Class or maybe even some of the features from the WP Alchemy Class. Both of which are awesome tools but I'm sure need work to be core compatible.

I personally don't think it needs a UI for creating and adding CMB's to posts like Type and Views or Custom Field Suite does, at least not in it's first iteration.

comment:54 in reply to: ↑ 53 @ryanduff3 years ago

Replying to jb510:

I personally don't think it needs a UI for creating and adding CMB's to posts like Type and Views or Custom Field Suite does, at least not in it's first iteration.

Agreed on lack of UI. There's no UI to generate post types or taxonomies in core, why should there be one for meta?

All that's needed is a simple, extendable way to show/process the field types (and possibly hook in and add new ones) as well as a way to define field sets as meta boxes.

comment:55 @billerickson3 years ago

As described by others, I think the required features should be:

  • An easy way to create metaboxes
  • Common fields built-in
  • Easy way to extend them to add new fields

There shouldn't be any UI for creating metaboxes or fields. That's plugin territory.

I think we've done a pretty good job with our code library ( code | wiki ) and would love to see something similar make it into core.

comment:56 @dwenaus3 years ago

Agreed, axe the UI.

The Custom Metaboxes and Fields code has a nice balance of just enough features with clean code. Also, their way of implementing the meta box array is intuitive. I believe you guys are working on field cloning/repeating right now, right? I would like to see this in the first iteration as well.

The WP_Alchemy class, while more powerful, has a codebase 5 times as large. Also, it doesn't generate the html elements, it just supports it. This approach is more flexible but it's also less intuitive and more work to setup. Special cases are better dealt with using filters.

comment:57 @ryanduff3 years ago

Keep in mind that GaryJ is working on a complete rewrite of CMB so I'd be curious as to how that pans out and what may be gained from it as far as this ticket goes.

comment:58 @billerickson3 years ago

Correct, a rewrite is underway, but it's just a refactoring (at least that's my understanding). I was commenting more that the features of CMB would be a good fit for this ticket rather than the actual code. I'd assume it would be rewritten again for inclusion in WP core (like Menus).

dwenaus, yes I believe repeatable fields is at the top of our feature list and is definitely something we'd like to include, but at the moment we're working on bug fixes and refactoring the code.

comment:59 @dwenaus3 years ago

i wonder if the rewrite should change direction towards a core inclusion rewrite? How does that decision get made?

comment:60 @steveryan3 years ago

  • Cc steveryan added

comment:61 @jgardner033 years ago

  • Cc jgardner03 added

comment:62 @ericlewis3 years ago

  • Cc eric.andrew.lewis@… added

comment:63 @jtsternberg3 years ago

  • Cc justin@… added

comment:64 @martythornley3 years ago

  • Cc martythornley added

@ericlewis3 years ago

comment:65 in reply to: ↑ 16 @ericlewis3 years ago

In 18179.php, I've added a register_meta() method to WP_Meta_Box, which can be called for any meta field associated with the meta box, and will store it in an instance array variable for displaying, saving, and sanitization/auth callbacks. I've created an optional array of arguments, one of them which is "default_display," which defaults to true. This will output a standard form field for the meta entry, and can be easily overridden by setting this option to false, and implementing your own form field rendering. I devved out just a basic text field for now, as I'm not sure how we want to build custom HTML elements and how much control should be in the API. I was thinking an array parameter 'attrs' which would build the attributes for the form field element.

Replying to WraithKenny:

On the revision check of WP_CPT_Meta_Box: Sometimes authors intend revisions to receive metadata updates and restore metadata on post restore. It'd be nice to have a built in functionality for this in the API (or at least account for it).

Also, I think the class WP_Meta_Box should have a basic save() method, which would check autosave and privileges, which could easily be overridden by a subclass as WraithKenny describes.

Last edited 3 years ago by ericlewis (previous) (diff)

comment:66 @WraithKenny3 years ago

Potentially related to this is all of koopersmith's work on the theme customizer. If you're interested in this ticket, you should read the code for that, as I assume many of those conventions would be useful here.

Also, I definitely think UI should be handled. Once the base classes are worked out, generic and generally useful field types (like Color, Email, or whatever) can be extended that handle the typical markup style and behaviors. WordPress has valitation, sanitation, and conventions for markup, style, and behaivor. They wouldn't be required for plugin authors, but they should be available and probably used by WordPress for its own boxes (dogfood).

comment:67 @ethitter3 years ago

  • Cc erick@… added

comment:68 @sabreuse3 years ago

  • Cc sabreuse@… added

comment:69 @simonwheatley2 years ago

  • Cc simon@… added

comment:70 @ericlewis2 years ago

Related: #18909. Adding a post meta entry type such as date can easily be performed with the jQuery UI datepicker plugin, but would require jQuery UI CSS in core.

@ericlewis2 years ago

Custom sanitization callback support added, with a default for generic form field types. Basic text and wp_editor meta field types added to begin with. Authorization callbacks supported, with a default of automatic authorization (if the user already has edit_published_post cap). Form rendering has defaults that can be overridden in a subclass.

@ericlewis2 years ago

add missing check for nonce existence before validating.

comment:71 @emzo2 years ago

  • Cc wordpress@… added

comment:72 @sillybean2 years ago

  • Cc steph@… added

@ericlewis2 years ago

Move meta field types into classes, which include their own rendering, sanitization, authorization, and script enqueueing methods.

comment:73 @desrosj23 months ago

  • Cc desrosj@… added

comment:74 @buffler23 months ago

  • Cc jeremy.buller@… added

comment:75 @dwenaus23 months ago

  • Cc deryk@… removed

comment:76 @mordauk23 months ago

  • Cc pippin@… added

comment:77 @MZAWeb23 months ago

  • Cc wordpress@… added

comment:78 @Messenlehner20 months ago

  • Cc Messenlehner added

comment:79 @goto1020 months ago

  • Cc dromsey@… added

comment:80 @jlambe20 months ago

  • Cc julien@… added

comment:81 @rachelbaker20 months ago

  • Cc rachel@… added

comment:82 @tott20 months ago

  • Cc thorsten@… added

comment:83 @nacin9 months ago

#30058 was marked as a duplicate.

Note: See TracTickets for help on using tickets.