You know how they come to that anti-pattern though, right? They want to isolate the query, so that if it was more easily cowboy coded — add and remove print and debug.
Wonder if prepare() having a debug/echo parameter would be useful, or too abstract… aside, does WP still not have as good of debug infrastructure as bbPress?
Note: Most of the code here is specific to my environment on Webfaction, github and for use with WordPress plugins. You can make it work for other setups (i.e. different hosts, local gits, or even SVN) but will involve some tweaking.
Scott recently had a great idea to run the bleeding edge release of Edit Flow on our official site. I usually do this for most of my plugins before releasing, though, it’s a manual process: FTP up the latest code and give it a test run. That’s not fun.
Here’s a far better, automatized way to keep your repo up-to-date. You can either use cron or githooks. Pick your poison.
With the custom post type enhancements introduced in WordPress 3, site builders and plugins developers now have access to what you could call “dynamic scaffolding”. With a couple of lines of code, you can easily generate the necessary UIs to help users easily manage and create new types of content.
You can add new post types (e.g. Movies, Reviews, Products, Projects, etc.) and specify the features each should support (e.g. title, body, authors, revisions, etc.) . Beyond that, you can add use the ever-flexible hook and filter system to add your own features. Combine that with custom fields and you can add your own fields (so a “movie” post type can have new fields to add things like “release date”, “rating”, and so on) .
However the code involved in adding those additional fields can get cumbersome, especially when you start looking at lots of content types with numerous fields. Add in other object types like users and comments and you’re now looking at a huge code base that needs to be maintained, updated and so on.
Well, I’m making it easier.
Overview
Custom Metadata Manager introduces a very WordPress-like way of adding additional fields to your object types. The goal is to help you rapidly build familiar, intuitive interfaces for your users.
Consider this:
That one line of code kicks into gear some of that “dynamic scaffolding” magic I mentioned earlier. The Edit Post page now has a metabox with a text field. The plugin handles all the heavy-lifting for you behind-the-scenes, so that you can focus on more on building out and connecting your data rather than all the minor details. Checkit:
A magical new field with one line of code!
The API is similar to that used for registering custom post types and taxonomies so it should be familiar territory.
Object Types
But let’s not stop there. Let’s say I want comments and users to all have this magical new field. Let’s try something like this:
And we get the same field added for users and comments!
A magical new field for users with one line of code!
Note: I’ve omitted a screenshot for comments since it looks exactly the same as the posts screen.
Custom Metadata Manager supports fields for:
posts (built-in and any custom post types)
comments
users
If/when links and taxonomies get metadata support, I’ll add support for them as well.
Labels and Descriptions!
Avoid cryptic slug-like names and make it easy for users by assigning friendly labels and descriptions!
'Field Label',
'description' => 'This is a friendly description for the field to help you enter your data.'
) );
?>
Groups
To avoid clutter on the Edit Post page, you can group sets of fields together.
Text fields can get boring, so I’ve cooked in a number of different field types (just specify the field_type in the $args parameter and go!):
All sorts of different field types
Custom Callbacks
Notice that last one in the screenshot above? That’s using a custom display callback! You can override a bunch of different things (display callback, sanitize callback, etc.) to get even more control over the fields you add. That means you can do cool stuff like this:
Custom callbacks make custom fields even more fun!
Columns
We’ll throw in an easy way to add your fields to the Manage Post/User/Comments pages as well (in your $args, just set display_column to true). By default, the column will just the value of the field, but if you’ve got something complex going on, you can just as easily include a display_column_callback.
Columns made easy!
Example Code
I’ve included fairly detailed docs on Extend and for kicks, I’ve thrown in example code along with the plugin. (To see it in action, turn on WP_DEBUG.)
Why this plugin?
Don’t get me wrong: this isn’t anything revolutionary. Lots and lots and lots and lots have come before me. But my approach is probably the most “WordPress-like” there is (Bonus points to Easy Custom Fields which uses a code-based and very object-oriented approach).
The API is simple, intuitive and very flexible, providing lots of overrides if you don’t like the default functionality (or have specific use cases).
The plugin doesn’t use extra tables and stores all data in a WordPress native way, so you can use the standard get_metadata function to retrieve your custom data. That way you also don’t have to worry about losing your data should you choose to stop using this plugin.
(I have already deployed and used the plugin across a number of production sites and it’s working great and saving me significant amounts of time and code!)
Why a code-based approach instead of a UI?
Because most of the plugins I mentioned above do the UI thing (and some it really well!) and it’d be lame to just copy them. The code-based approach, though, more closely aligns with the existing WordPress approach of registering new types of content (post types, taxonomies, etc.).
This is also a developer feature, aimed towards site builders. And real developers don’t need UIs ;)
TODOs
What stuff am I cooking up for future versions?
Improved styling of rendered fields
Ability Pass in attributes for built-in fields (e.g. class, data-*, etc.)
Additional field types
Limit or exclude groups and fields for specific ids (e.g. show only on post id = 145)
Autosave support for fields on post types
Option to enqueue scripts and styles
Client- and server-side validation support
Add groups and fields to Quick Edit
—-
Download
Grab it from the WordPress Plugin Directory or just search for “Custom Metadata Manager” from the Plugin Manager within your WordPress install.
If you’ve read all the way through, thanks! Like what you see? Want more field types and features added? Just want say hi? Get in touch.
I pushed out an update to Plugin Notes last week bumping up the version number to 1.1. Only three changes in this update:
Ability to add select HTML tags to notes, so you can now do cool stuff like the image above. Full list of allowed tags available here. (Thanks to Dave A. for the suggestion)
Fixed a bunch of PHP Error Notices that were popping up across the plugin (thanks to WP_DEBUG)
I pushed up v1.1 of Zen yesterday. Not much changed in this new version. Key improvement is that the content textarea is now a bit bigger so things don’t look really disproportionate on larger resolutions.
John Gadbois turned some code I gave him into short and useful write-up on how to hook into AJAX calls triggered when saving widgets. It makes use of jQuery’s Global AJAX event handlers, which allow for some very cool things, especially when you’re working with external libraries that use the jQuery AJAX methods. A future blog post will cover how plugins can use the ajaxSend event to hook into WordPress’ autosave.
Mohammad Jangda 3:31 pm on November 23, 2011 Permalink |
And, yes, the query in the example makes no sense.
Alex Mills (Viper007Bond) 3:32 pm on November 23, 2011 Permalink |
Actually it’s a valid way to see if a post ID exists. :)
And +1 to your post.
Lloyd Budd 7:19 pm on November 23, 2011 Permalink |
You know how they come to that anti-pattern though, right? They want to isolate the query, so that if it was more easily cowboy coded — add and remove print and debug.
Wonder if prepare() having a debug/echo parameter would be useful, or too abstract… aside, does WP still not have as good of debug infrastructure as bbPress?
Mohammad Jangda 10:48 am on November 24, 2011 Permalink |
The problem is that prepare doesn’t do much other than sprintf the query with the values passed in. Developers can still do something like:
$query = $wpdb->prepare( "SELECT ID from {$wpdb->posts} WHERE ID = %d", $value ); error_log( 'Woo! I'm querying IDs! My query: ' . $query ); $id = $wpdb->get_col( $query );Which is why this anti-pattern baffles me…