Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

update to 0.6

  • Loading branch information...
commit 18327dd15f4eb5b1c8a3aae533c7b26f3a36a9e7 1 parent 4c8b243
@jkudish authored
View
162 README.md
@@ -22,7 +22,7 @@ This is also a developer feature, aimed towards site builders. And real develope
(But really, though, the main benefit of this fact comes into play when you're working with multiple environments, i.e. development/local, qa/staging, production. This approach makes it easy to replicate UIs and features without having to worry about database synchronization and other crazy things.)
-For another really well-done, really powerful code-based plugin for managing custom fields, check out [Easy Custom Fields](http://wordpress.org/extend/plugins/easy-custom-fields/).
+For another really well-done, really powerful code-based plugin for managing custom fields, check out [Easy Custom Fields](http://wordpress.org/extend/plugins/easy-custom-fields/) and the [Custom Metaboxes and Fields For WordPress Class](https://github.com/jaredatch/Custom-Metaboxes-and-Fields-for-WordPress).
#### Why isn't the function just `add_metadata_field`? Do you really need the stupid `x_`? =
@@ -36,6 +36,23 @@ There are usage instructions in the readme.txt file
# Changelog
+= 0.6 =
+
+* note: the plugin now requires WordPress 3.3+ (chiefly for the wysiwyg + datepicker fields)
+* update/clean-up the examples file
+* properly enqueue admin css for WP 3.3+
+* added a filter for the CUSTOM_METADATA_MANAGER_URL constant
+* fix fields not appearing when editing users in WP 3.3+ (props @FolioVision)
+* now passing the $value for a display_callback (props @FolioVision)
+* use the new 'wp_editor()' function (since WP 3.3+) instead of 'the_editor()' (now deprecated)
+* wysiwyg fields are no longer cloneable (may be revisited in a future version)
+* note: metaboxes that have a wysiwyg field will break when moved, this is not a bug per-se (may be revisited in a future version)
+* password fields are now cloneable
+* added filters for most of the plugin's internal variables
+* now using WordPress' built-in jQuery UI for the datepicker field
+* updated the screenshots
+* updated the instructions in readme.txt
+
= 0.5.7 =
* pass additional params for display_callback
@@ -105,6 +122,149 @@ There are usage instructions in the readme.txt file
* Initial release
+# Usage
+
+#### Object Types
+
+The main idea behind this plugin is to have a single API to work with regardless of the object type. Currently, Custom Metadata Manager works with `user`, `comment` and any built-in or custom post types, e.g. `post`, `page`, etc.
+
+#### Registering your fields
+
+For the sake of performance (and to avoid potential race conditions), always register your custom fields in the `admin_menu` hook. This way your front-end doesn't get bogged down with unnecessary processing and you can be sure that your fields will be registered safely. Here's a code sample:
+
+`
+add_action( 'admin_menu', 'my_theme_init_custom_fields' );
+
+function my_theme_init_custom_fields() {
+ if( function_exists( 'x_add_metadata_field' ) && function_exists( 'x_add_metadata_group' ) ) {
+ x_add_metadata_field( 'my_field', array( 'user', 'post' ) );
+ }
+}
+`
+
+#### Getting the data
+
+You can get the data as you normally would using the `get_metadata` function. Custom Metadata manager stores all data using the WordPress metadata APIs using the slug name you provide. That way, even if you decide to deactivate this wonderful plugin, your data is safe and accessible. For options, you can use `get_option`.
+
+Example:
+`
+$value = get_metadata( 'post', get_the_ID(), 'featured', true ); // Returns post metadata value for the field 'featured'
+`
+
+#### Adding Metadata Groups
+
+A group is essentially a metabox that groups together multiple fields. Register the group before any fields
+
+`
+x_add_metadata_group( $slug, $object_types, $args );
+`
+
+
+= Parameters =
+
+* `$slug` (string) The key under which the metadata will be stored.
+* `$object_types` (string|array) The object types to which this field should be added. Supported: post, page, any custom post type, user, comment.
+
+
+= Options and Overrides =
+
+`
+$args = array(
+ 'label' => $group_slug, // Label for the group
+ 'context' => 'normal', // (post only)
+ 'priority' => 'default', // (post only)
+ 'autosave' => false, // (post only) Should the group be saved in autosave? NOT IMPLEMENTED YET!
+ 'exclude' => '', // see below for details
+ 'include' => '', // see below for details
+);
+`
+
+#### Adding Metadata Fields
+
+`x_add_metadata_field( $slug, $object_types, $args );`
+
+
+= Parameters =
+
+* `$slug` (string) The key under which the metadata will be stored. For post_types, prefix the slug with an underscore (e.g. `_hidden`) to hide it from the the Custom Fields box.
+* `$object_types` (string|array) The object types to which this field should be added. Supported: post, page, any custom post type, user, comment.
+
+
+= Options and Overrides =
+
+`
+$args = array(
+ 'group' => '', // The slug of group the field should be added to. This needs to be registered with x_add_metadata_group first.
+ 'field_type' => 'text', // The type of field; 'text', 'textarea', 'password', 'checkbox', 'radio', 'select', 'upload', 'wysiwyg', 'datepicker', 'taxonomy_select', 'taxonomy_radio'
+ 'label' => '', // Label for the field
+ 'description' => '', // Description of the field, displayed below the input
+ 'values' => array(), // Values for select and radio buttons. Associative array
+ 'display_callback' => '', // Callback to custom render the field
+ 'sanitize_callback' => '', // Callback to sanitize data before it's saved
+ 'display_column' => false, // Add the field to the columns when viewing all posts
+ 'display_column_callback' => '', // Callback to render output for the custom column
+ 'required_cap' => '', // The cap required to view and edit the field
+ 'exclude' => '', // see below for details
+ 'include' => '', // see below for details
+ 'multiple' => false, // true or false, can the field be duplicated with a click of a button?
+);
+`
+
+= Include / Exclude =
+
+You can exclude fields and groups from specific object. For example, with the following, field-1 will show up for all posts except post #123:
+
+`
+$args = array(
+ 'exclude' => 123
+);
+x_add_metadata_field( 'field-1', 'post', $args );
+`
+
+Alternatively, you can limit ("include") fields and groups to specific objects. The following will ''only'' show group-1 to post #456:
+
+`
+$args = array(
+ 'include' => 123
+);
+x_add_metadata_group( 'group-1', 'post', $args );
+`
+
+You can pass in an array of IDs:
+
+`
+$args = array(
+ 'include' => array( 123, 456, 789 );
+);
+
+With multiple object types, you can pass in an associative array:
+
+`
+$args = array(
+ 'exclude' => array(
+ 'post' => 123,
+ 'user' => array( 123, 456, 789 )
+ )
+);
+
+
+# Examples
+
+For examples, please see the [custom_metadata_examples.php](http://svn.wp-plugins.org/custom-metadata/trunk/custom_metadata_examples.php) file included with the plugin. Add a constant to your wp-config.php called `CUSTOM_METADATA_MANAGER_DEBUG` with a value of `true` to see it in action:
+
+`define( 'CUSTOM_METADATA_MANAGER_DEBUG', true );`
+
+# TODOs
+
+Stuff we have planned for the future:
+
+* Ability Pass in attributes for built-in fields (e.g. class, data-*, etc.)
+* Additional field types (multi-select, multi-checkbox)
+* Limit or exclude groups and fields using a custom callback
+* Autosave support for fields on post types
+* Client- and server-side validation support
+* Add groups and fields to Quick Edit
+
# Credits
This plugin is built and maintained by [Mo' Jangda](http://digitalize.ca/ "Mo' Jangda"), [Stresslimit Design](http://stresslimitdesign.com/about-our-wordpress-expertise "Stresslimit Design") & [Joachim Kudish](http://jkudish.com "Joachim Kudish")
View
16 css/custom-metadata-manager.css
@@ -6,7 +6,7 @@
.custom-metadata-field > div > label {display: block; margin: 5px 0;}
.custom-metadata-field .error {color: red; font-style: italic;}
-/* text feilds */
+/* text fields */
.custom-metadata-field input[type=text], .custom-metadata-field input[type=url], .custom-metadata-field input[type=password], .custom-metadata-field input[type=email] {width:75%; margin: 3px 0;}
/* radio fields */
@@ -24,16 +24,12 @@
/* textarea fields */
.custom-metadata-field textarea {width:99%; height:4em;}
-/* tiny mce */
-.customEditor {margin: 10px 0 40px 0;}
-.custom-metadata-field .mceIframeContainer {background: #fff;}
-.custom-metadata-field .wp-editor-wrap {clear: both;}
-.custom-metadata-field.wysiwyg textarea.wp-editor-area {width: 99%;}
-.custom-metadata-field.wysiwyg #quicktags {display: none;}
+/* wysiwyg fields */
+.custom-metadata-field.wysiwyg > label, .user-metadata-group .custom-metadata-field.wysiwyg > label {display: block; width: 100%; float: none;}
+.custom-metadata-field.wysiwyg .wp-editor-container {background: #fff}
/* user fields */
-.user-metadata-group .custom-metadata-field label {color:#222; display:block; text-align:left; vertical-align:top; width:200px; font-size:13px; line-height:24px; float:left;}
+.user-metadata-group .custom-metadata-field > label {color:#222; display:block; text-align:left; vertical-align:top; width:200px; font-size:13px; line-height:24px; float:left;}
.user-metadata-group .custom-metadata-field input[type=text], .user-metadata-group .custom-metadata-field input[type=url], .user-metadata-group .custom-metadata-field input[type=password], .user-metadata-group .custom-metadata-field input[type=email] {width:25em;}
.user-metadata-group .custom-metadata-field textarea {width:25em;}
-.user-metadata-group .custom-metadata-field .description {margin-left:200px;}
-#profile-page .user-metadata-group .custom-metadata-field.wysiwyg textarea.wp-editor-area {width: 99%;}
+.user-metadata-group .custom-metadata-field .description {margin-left:200px;}
View
0  js/images/calendar.png → css/images/calendar.png
File renamed without changes
View
100 custom_metadata.php
@@ -4,10 +4,10 @@
Plugin URI: http://wordpress.org/extend/plugins/custom-metadata/
Description: An easy way to add custom fields to your object types (post, pages, custom post types, users)
Author: Mohammad Jangda, Joachim Kudish & Colin Vernon
-Version: 0.5.7
-Author URI: http://digitalize.ca/
+Version: 0.6
+Author URI: http://digitalize.ca/wordpress-plugins/custom-metadata/
-Copyright 2010 Mohammad Jangda, Joachim Kudish, Colin Vernon
+Copyright 2010-2012 Mohammad Jangda, Joachim Kudish, Colin Vernon
GNU General Public License, Free Software Foundation <http://creativecommons.org/licenses/GPL/2.0/>
@@ -26,15 +26,20 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-if( ! defined( 'CUSTOM_METADATA_MANAGER_DEBUG' ) ) define( 'CUSTOM_METADATA_MANAGER_DEBUG', false );
-if( CUSTOM_METADATA_MANAGER_DEBUG ) require_once( 'custom_metadata_examples.php' );
+/**
+ * set this to true in your wp-config.php file to enable debug/test mode
+ */
+if ( ! defined( 'CUSTOM_METADATA_MANAGER_DEBUG' ) )
+ define( 'CUSTOM_METADATA_MANAGER_DEBUG', false );
+
+if ( CUSTOM_METADATA_MANAGER_DEBUG )
+ include_once( 'custom_metadata_examples.php' );
/*
TODO:
- Additional Field types (multi-select, multi-checkboxes, taxonomy checkbox)
- Group description field
-- Update custom metadata examples test file
- Multiple display in the same order as saved
- Limit group based on caps?
@@ -64,14 +69,28 @@ class custom_metadata_manager {
// field types
var $_field_types = array( 'text', 'textarea', 'password', 'checkbox', 'radio', 'select', 'upload', 'wysiwyg', 'datepicker', 'taxonomy_select', 'taxonomy_radio' );
// field types that are cloneable
- var $_cloneable_field_types = array( 'text', 'textarea', 'upload', 'wysiwyg');
+ var $_cloneable_field_types = array( 'text', 'textarea', 'upload', 'password');
// Object types whose columns are generated through apply_filters instead of do_action
var $_column_filter_object_types = array( 'user' );
// Whitelisted pages that get stylesheets and scripts
var $_pages_whitelist = array( 'edit.php', 'post.php', 'post-new.php', 'users.php', 'profile.php', 'user-edit.php', 'edit-comments.php', 'comment.php');
+ // the default args used for the wp_editor function
+ var $default_editor_args = array();
function __construct( ) {
+
+ // filter our vars
+ $this->_non_post_types = apply_filters( 'custom_metadata_manager_non_post_types', $this->_non_post_types );
+ $this->_builtin_object_types = apply_filters( 'custom_metadata_manager_builtin_object_types', $this->_builtin_object_types );
+ $this->_column_types = apply_filters( 'custom_metadata_manager_column_types', $this->_column_types);
+ $this->_field_types = apply_filters( 'custom_metadata_manager_field_types', $this->_field_types);
+ $this->_cloneable_field_types = apply_filters( 'custom_metadata_manager_cloneable_field_types', $this->_cloneable_field_types);
+ $this->_column_filter_object_types = apply_filters( 'custom_metadata_manager_column_filter_object_types', $this->_column_filter_object_types);
+ $this->_pages_whitelist = apply_filters( 'custom_metadata_manager_pages_whitelist', $this->_pages_whitelist);
+ $this->default_editor_args = apply_filters( 'custom_metadata_manager_default_editor_args', $this->default_editor_args );
+
+
// We need to run these as late as possible!
add_action( 'init', array( &$this, 'init' ), 1000, 0 );
add_action( 'admin_init', array( &$this, 'admin_init' ), 1000, 0 );
@@ -84,8 +103,8 @@ function init() {
function admin_init() {
global $pagenow;
- define( 'CUSTOM_METADATA_MANAGER_VERSION', '0.5.7' );
- define( 'CUSTOM_METADATA_MANAGER_URL' , plugins_url(plugin_basename(dirname(__FILE__)).'/') );
+ define( 'CUSTOM_METADATA_MANAGER_VERSION', '0.6' );
+ define( 'CUSTOM_METADATA_MANAGER_URL' , apply_filters('custom_metadata_manager_url', trailingslashit(plugins_url('', __FILE__))) );
// Hook into load to initialize custom columns
if( in_array( $pagenow, $this->_pages_whitelist ) ) {
@@ -107,12 +126,11 @@ function init_metadata() {
$object_type = $this->_get_object_type_context();
add_action( 'admin_enqueue_scripts', array( &$this, 'enqueue_scripts' ) );
- add_action( 'admin_print_styles', array( &$this, 'enqueue_styles' ) );
+ add_action( 'admin_enqueue_scripts', array( &$this, 'enqueue_styles' ) );
$this->init_columns();
// Handle actions related to users
- // TODO: I really don't like hard-coding this...
if( $object_type == 'user' ) {
// Editing another user's profile
add_action( 'edit_user_profile', array( &$this, 'add_user_metadata_groups' ) );
@@ -166,17 +184,9 @@ function init_columns() {
function enqueue_scripts() {
wp_enqueue_script('jquery');
- wp_enqueue_script('jquery-ui-core');
- wp_enqueue_script('common');
- wp_enqueue_script('postbox');
- wp_enqueue_script('media-upload');
- wp_enqueue_script('thickbox');
- wp_enqueue_style('jquery-custom-ui');
- wp_enqueue_script('word-count');
- wp_enqueue_script('post');
- wp_enqueue_script('editor');
+ wp_enqueue_script('jquery-ui-datepicker');
wp_enqueue_script('custom-metadata-manager-js', apply_filters( 'custom-metadata-manager-default-js', CUSTOM_METADATA_MANAGER_URL .'js/custom-metadata-manager.js' ), array( 'jquery' ), CUSTOM_METADATA_MANAGER_VERSION, true);
- wp_enqueue_script('jquery-ui-datepicker', apply_filters('custom-metadata-manager-datepicker-js', CUSTOM_METADATA_MANAGER_URL .'js/jquery-ui-datepicker.min.js'), array('jquery', 'jquery-ui-core'));
+ // wp_enqueue_script('jquery-ui-datepicker', apply_filters('custom-metadata-manager-datepicker-js', CUSTOM_METADATA_MANAGER_URL .'js/jquery-ui-datepicker.min.js'), array('jquery', 'jquery-ui-core'));
}
function enqueue_styles() {
@@ -225,19 +235,18 @@ function add_metadata_column_content( $name, $object_id ) {
function add_metadata_field( $field_slug, $object_types = array( 'post' ), $args = array() ) {
$defaults = array(
- 'group' => '' // To which meta_box the field should be added
- , 'field_type' => 'text' // The type of field; possibly values: text, checkbox, radio, select, image
- , 'label' => $field_slug // Label for the field
- , 'description' => '' // Description of the field, displayed below the input
- , 'values' => array() // values for select, checkbox, radio buttons
- , 'display_callback' => '' // function to custom render the input
- , 'sanitize_callback' => ''
- //, 'client_validation_callback' => '' // function name for client-side validation
- //, 'server_validation_callback' => '' // function name for server-side validation
- , 'display_column' => false // Add the field to the columns when viewing all posts
- , 'display_column_callback' => ''
- , 'add_to_quick_edit' => false // (post only) Add the field to Quick edit
- , 'required_cap' => '' // the cap required to view and edit the field
+ 'group' => '', // To which meta_box the field should be added
+ 'field_type' => 'text', // The type of field; possibly values: text, checkbox, radio, select, image
+ 'label' => $field_slug, // Label for the field
+ 'description' => '', // Description of the field, displayed below the input
+ 'values' => array(), // values for select, checkbox, radio buttons
+ 'display_callback' => '', // function to custom render the input
+ 'sanitize_callback' => '',
+ 'display_column' => false, // Add the field to the columns when viewing all posts
+ 'display_column_callback' => '',
+ 'add_to_quick_edit' => false, // (post only) Add the field to Quick edit
+ 'required_cap' => '', // the cap required to view and edit the field
+ 'multiple' => false, // can the field be duplicated with a click of a button
);
// Merge defaults with args
@@ -263,11 +272,11 @@ function add_metadata_field( $field_slug, $object_types = array( 'post' ), $args
function add_metadata_group( $group_slug, $object_types, $args = array() ) {
$defaults = array(
- 'label' => $group_slug // Label for the group
- , 'description' => '' // Description of the group
- , 'context' => 'normal' // (post only)
- , 'priority' => 'default' // (post only)
- , 'autosave' => false // (post only) Should the group be saved in autosave?
+ 'label' => $group_slug, // Label for the group
+ 'description' => '', // Description of the group
+ 'context' => 'normal', // (post only)
+ 'priority' => 'default', // (post only)
+ 'autosave' => false, // (post only) Should the group be saved in autosave?
);
// Merge defaults with args
@@ -704,8 +713,7 @@ function _get_object_type_context() {
$object_type = '';
- // This is a hack!
- if( $pagenow == 'profile.php' ) {
+ if( $pagenow == 'profile.php' || $pagenow == 'user-edit.php' || $pagenow == 'users.php' ) {
return 'user';
}
@@ -841,14 +849,13 @@ function _metadata_column_content( $field_slug, $field, $object_type, $object_id
}
function _display_metadata_field( $field_slug, $field, $object_type, $object_id ) {
+ $value = $this->get_metadata_field_value( $field_slug, $field, $object_type, $object_id );
if (isset($field->display_callback) && function_exists($field->display_callback)) :
- call_user_func($field->display_callback, $field_slug, $field, $object_type, $object_id);
+ call_user_func($field->display_callback, $field_slug, $field, $object_type, $object_id, $value);
else :
?>
<div class="custom-metadata-field <?php echo $field->field_type ?>">
<?php
- $value = $this->get_metadata_field_value( $field_slug, $field, $object_type, $object_id );
-
if (!in_array($object_type, $this->_non_post_types)) global $post;
if (isset($field->multiple) && $field->multiple && @!in_array($field->field_type, $this->_cloneable_field_types)) {
$field->multiple = false;
@@ -921,7 +928,10 @@ function _display_metadata_field( $field_slug, $field, $object_type, $object_id
<?php break; ?>
<?php case 'wysiwyg': ?>
- <?php the_editor($v, $field_id); ?>
+ <?php
+ $args = apply_filters('custom_metadata_manager_wysiwyg_args_field_'.$field_id, $this->default_editor_args, $field_slug, $field, $object_type, $object_id );
+ wp_editor($v, $field_id, $args);
+ ?>
<?php break; ?>
<?php case 'upload': ?>
View
436 custom_metadata_examples.php
@@ -1,6 +1,6 @@
<?php
/*
-Copyright 2010 Mohammad Jangda
+Copyright 2010-2012 Mohammad Jangda, Joachim Kudish, Colin Vernon
GNU General Public License, Free Software Foundation <http://creativecommons.org/licenses/GPL/2.0/>
@@ -19,332 +19,214 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-add_action( 'init', 'init_my_custom_post_types' );
-
-function init_my_custom_post_types() {
-
- register_post_type( 'custom-metatadata-milestone', array(
- 'labels' => array(
- 'name' => 'Milestones'
- , 'singular_name' => 'Milestone'
- , 'add_new' => 'Add New'
- , 'add_new_item' => 'Add New Milestone'
- , 'edit_item' => 'Edit Milestone'
- , 'new_item' => 'Add Milestone'
- , 'view_item' => 'View Milestone'
- , 'search_items' => 'Search Milestones'
- , 'not_found' => 'No Milestones found'
- , 'not_found_in_trash' => 'No Milestones found in Trash'
- ),
- 'public' => true,
- 'capability_type' => 'post',
- 'hierarchical' => false,
- 'rewrite' => true,
- 'query_var' => false,
- 'taxonomies' => array( 'milestone-category' ),
- 'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt', 'custom-fields', 'revisions' ),
- ) );
+
+/**
+ * register a test post type just for the examples
+ * @return void
+ */
+add_action( 'init', 'x_init_custom_post_types' );
+function x_init_custom_post_types() {
+
+$labels = array(
+ 'name' => _x('Tests', 'post type general name'),
+ 'singular_name' => _x('Test', 'post type singular name'),
+ 'add_new' => _x('Add New', 'Test'),
+ 'add_new_item' => __('Add New Test'),
+ 'edit_item' => __('Edit Test'),
+ 'new_item' => __('New Test'),
+ 'all_items' => __('All Tests'),
+ 'view_item' => __('View Test'),
+ 'search_items' => __('Search Tests'),
+ 'not_found' => __('No Tests found'),
+ 'not_found_in_trash' => __('No Tests found in Trash'),
+ 'parent_item_colon' => '',
+ 'menu_name' => 'Tests'
+
+ );
+ $args = array(
+ 'labels' => $labels,
+ 'public' => true,
+ 'publicly_queryable' => true,
+ 'show_ui' => true,
+ 'show_in_menu' => true,
+ 'query_var' => true,
+ 'rewrite' => true,
+ 'capability_type' => 'post',
+ 'has_archive' => true,
+ 'hierarchical' => false,
+ 'menu_position' => null,
+ 'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' )
+ );
+ register_post_type('x_test', $args);
}
-add_action( 'admin_init', 'init_my_custom_fields' );
-function init_my_custom_fields() {
+/**
+ * register custom metadata groups and fields
+ * this is the example code that you should use
+ * make sure to use the 'admin_init' hook as below
+ * @return void
+ */
+add_action( 'admin_init', 'x_init_custom_fields' );
+function x_init_custom_fields() {
+ // check that the metadata manager plugin is active by checking if the two functions we need exist
if( function_exists( 'x_add_metadata_group' ) && function_exists( 'x_add_metadata_field' ) ) {
- x_add_metadata_group( 'x_metaBox1', 'post', $args = array(
+ // adds a new group to the test post type
+ x_add_metadata_group( 'x_metaBox1', 'x_test', array(
'label' => 'Group with Multiple Fields'
- , 'include' => 2476
) );
- x_add_metadata_group( 'x_metaBox2', array( 'post', 'user' ), $args = array(
+ // adds another group to the test post type + posts + users
+ x_add_metadata_group( 'x_metaBox2', array( 'x_test', 'post', 'user' ), array(
'label' => 'Group for Post and User'
- , 'exclude' => array( 'user' => array( 67, 35 ) )
) );
- x_add_metadata_field('x_fieldName1', 'post', array(
- 'group' => 'x_metaBox1'
- , 'description' => 'This is field #1. It\'s a simple text field.'
- , 'label' => 'Field #1'
- , 'display_column' => true
+ // adds a text field to the first group
+ x_add_metadata_field('x_fieldName1', 'x_test', array(
+ 'group' => 'x_metaBox1', // the group name
+ 'description' => 'This is field #1. It\'s a simple text field.', // description for the field
+ 'label' => 'Field #1', // field label
+ 'display_column' => true // show this field in the column listings
));
- x_add_metadata_field('x_fieldName2', 'post', array(
- 'group' => 'x_metaBox1'
- , 'display_column' => 'My Column (with Custom Callback)'
- , 'display_column_callback' => 'fieldName2_columnCallback'
+ // adds a text field to the 2nd group
+ x_add_metadata_field('x_fieldName2', 'x_test', array(
+ 'group' => 'x_metaBox1',
+ 'display_column' => 'My Column (with Custom Callback)', // show this field in the column listings
+ 'display_column_callback' => 'fieldName2_columnCallback' // custom function to display the column results (see below)
));
- function fieldName2_columnCallback( $field_slug, $field, $object_type, $object_id, $value ) {
- echo sprintf( 'The value of field "%s" is %s. <br /><a href="http://icanhascheezburger.files.wordpress.com/2010/10/04dc84b6-3dde-45db-88ef-f7c242731ce3.jpg">Here\'s a LOLCat</a>', $field_slug, $value ? $value : 'not set' );
- }
- x_add_metadata_field('x_fieldTextarea1', 'post', array(
- 'group' => 'x_metaBox1'
- , 'field_type' => 'textarea'
+ // adds a cloneable textarea field to the 1st group
+ x_add_metadata_field('x_fieldTextarea1', 'x_test', array(
+ 'group' => 'x_metaBox1',
+ 'field_type' => 'textarea',
+ 'multiple' => true,
));
- x_add_metadata_field('x_fieldCheckbox1', 'post', array(
- 'group' => 'x_metaBox1'
- , 'field_type' => 'checkbox'
+ // adds a wysiwyg (full editor) field to the 2nd group
+ x_add_metadata_field('x_fieldWysiwyg1', array('x_test', 'user'), array(
+ 'group' => 'x_metaBox2',
+ 'field_type' => 'wysiwyg',
));
- x_add_metadata_field('x_fieldRadio1', 'post', array(
- 'group' => 'x_metaBox1'
- , 'field_type' => 'radio'
- , 'values' => array(
- 'option1' => 'Option #1'
- , 'option2' => 'Option #2'
- )
+ // adds a datepicker field to the 1st group
+ x_add_metadata_field('x_fieldDatepicker1', 'x_test', array(
+ 'group' => 'x_metaBox1',
+ 'field_type' => 'datepicker',
));
- x_add_metadata_field('x_fieldSelect1', 'post', array(
- 'group' => 'x_metaBox1'
- , 'field_type' => 'select'
- , 'values' => array(
- 'option1' => 'Option #1'
- , 'option2' => 'Option #2'
- )
+ // adds an upload field to the 1st group
+ x_add_metadata_field('x_fieldUpload1', 'x_test', array(
+ 'group' => 'x_metaBox1',
+ 'field_type' => 'upload'
));
- x_add_metadata_field('x_fieldName2', array( 'post', 'user' ), array(
- 'group' => 'x_metaBox2'
+ // adds a checkbox field to the first group
+ x_add_metadata_field('x_fieldCheckbox1', 'x_test', array(
+ 'group' => 'x_metaBox1',
+ 'field_type' => 'checkbox'
));
- x_add_metadata_field('x_fieldName3', 'post', array(
-
- ));
-
- x_add_metadata_field('x_fieldCustomHidden1', 'post', array(
- 'group' => 'x_metaBox1'
- , 'display_callback' => 'fieldCustomHidden1_display'
- ));
-
- function fieldCustomHidden1_display( $field_slug, $field, $value ) {
- if( ! $value ) $value = 'This is a secret hidden value! Don\'t tell anyone!';
- ?>
- <hr />
- <p>This is a hidden field rendered with a custom callback. The value is "<?php echo $value; ?>".</p>
- <input type="hidden" name="<?php echo $field_slug; ?>" value="<?php echo $value; ?>" />
- <hr />
- <?php
- }
-
- x_add_metadata_field('x_fieldCustomList1', array( 'post', 'user' ), array(
- 'label' => 'Post Action Items'
- , 'display_callback' => 'fieldCustomList1_display'
-
- ));
-
- function fieldCustomList1_display( $field_slug, $field, $object_type, $object_id, $value ) {
- $value = (array)$value;
- $field_class = sprintf( 'field-%s', $field_slug );
- $count = 0;
- ?>
- <p>This is an example field rendered with a custom display_callback. All done with about 40 lines of code!</p>
-
- <?php if( empty( $value ) ) $value = array(); ?>
- <?php foreach( $value as $v ) : ?>
- <div class="f1_my-list-item">
- <input type="text" name="<?php echo $field_slug; ?>[]" value="<?php echo esc_attr( $v ); ?>" />
- <?php if( $count > 0 ) : ?>
- <a href="#" class="f1_btn-del-list-item hide-if-no-js" style="color:red;">Delete</a>
- <?php endif; ?>
- </div>
- <?php $count++; ?>
- <?php endforeach; ?>
- <p><a href="#" class="f1_btn-add-list-item hide-if-no-js">+ Add New</a></p>
-
- <script>
- ;(function($) {
- $('.f1_btn-add-list-item').click(function(e) {
- e.preventDefault();
- var $last = $('.f1_my-list-item:last');
- var $clone = $last.clone();
-
- $clone
- .insertAfter($last)
- .find(':input')
- .val('')
- ;
- });
- $('.f1_btn-del-list-item').live('click', function(e) {
- e.preventDefault();
- $(this).parent().remove();
- });
- })(jQuery);
- </script>
- <?php
- }
-
- x_add_metadata_field('x_fieldCustomList2', array( 'post' ), array(
- 'label' => 'Post Action Items (With Links!)'
- , 'display_callback' => 'fieldCustomList2_display'
- , 'sanitize_callback' => 'fieldCustomList2_sanitize'
- ));
-
- function fieldCustomList2_display( $field_slug, $field, $object_type, $object_id, $value ) {
- $value = (array) $value;
- $field_class = sprintf( 'field-%s', $field_slug );
- $count = 0;
- ?>
- <p>This is an example field rendered with a custom display_callback (renders multiple fields and js) and a custom sanitize_callback (aggregates the submitted data into a single array).</p>
-
- <?php if( empty( $value ) ) array_push( $value, array() ); ?>
-
- <?php foreach( $value as $v ) : ?>
- <?php
- $text = isset( $v['text'] ) ? $v['text'] : '';
- $url = isset( $v['url'] ) ? $v['url'] : '';
- ?>
- <div class="f2_my-list-item">
- <label>Text</label>
- <input type="text" name="<?php echo $field_slug; ?>_text[]" value="<?php echo esc_attr( $text ); ?>" />
-
- <label>URL</label>
- <input type="text" name="<?php echo $field_slug; ?>_url[]" value="<?php echo esc_attr( $url ); ?>" />
-
- <?php if( $count > 0 ) : ?>
- <a href="#" class="f2_btn-del-list-item hide-if-no-js" style="color:red;">Delete</a>
- <?php endif; ?>
- <?php $count++; ?>
- </div>
- <?php endforeach; ?>
-
- <p><a href="#" class="f2_btn-add-list-item hide-if-no-js">+ Add New</a></p>
-
- <script>
- ;(function($) {
- $('.f2_btn-add-list-item').click(function(e) {
- e.preventDefault();
- var $last = $('.f2_my-list-item:last');
- var $clone = $last.clone();
-
- $clone
- .insertAfter($last)
- .find(':input')
- .val('')
- ;
- });
- $('.f2_btn-del-list-item').live('click', function(e) {
- e.preventDefault();
- $(this).parent().remove();
- });
- })(jQuery);
- </script>
- <?php
- }
-
- function fieldCustomList2_sanitize( $field_slug, $field, $object_type, $object_id, $value ) {
- $values = array();
- $text_key = $field_slug . '_text';
- $url_key = $field_slug . '_url';
-
- if( isset( $_POST[$text_key] ) ) {
- $count = 0;
- foreach( (array) $_POST[$text_key] as $text ) {
- $url = isset( $_POST[$url_key][$count] ) ? $_POST[$url_key][$count] : '';
- if( $text || $url ) {
- array_push( $values, array(
- 'text' => $text
- , 'url' => $url
- ) );
- }
- $count++;
- }
- }
-
- return $values;
- }
-
- x_add_metadata_field( 'x_search-engine', 'post', array(
- 'field_type' => 'radio'
- , 'label' => 'Preferred Search Engine'
- , 'values' => array(
- 'google' => 'Google!'
- , 'bing' => 'Bing!'
+ // adds a radio button field to the first group
+ x_add_metadata_field('x_fieldRadio1', 'x_test', array(
+ 'group' => 'x_metaBox1',
+ 'field_type' => 'radio',
+ 'values' => array( // set possible value/options
+ 'option1' => 'Option #1', // key => value pair (value is stored in DB)
+ 'option2' => 'Option #2',
)
- , 'display_column' => 'Blog Links'
- , 'display_column_callback' => 'blog_links_column_callback'
));
- function blog_links_column_callback( $field_slug, $field, $object_type, $object_id, $value ) {
- switch( $value ) {
- case 'google':
- $url = 'http://google.com';
- break;
- case 'bing':
- $url = 'http://bing.com';
- break;
- default:
- $url = '';
- break;
- }
- if( $url )
- return sprintf( '<a href="%s" target="_blank">Go to search</a>', $url );
- return __( 'Search Engine not selected' );
- }
-
- x_add_metadata_field('x_pageField1', 'page', array(
- 'display_column' => 'My Page Field'
- ));
-
- x_add_metadata_field('x_userField1', 'user', array(
- 'display_column' => true
- , 'description' => 'This is a field for a user. Enter information in here!'
+ // adds a select box in the first group
+ x_add_metadata_field('x_fieldSelect1', 'x_test', array(
+ 'group' => 'x_metaBox1',
+ 'field_type' => 'select',
+ 'values' => array( // set possible value/options
+ 'option1' => 'Option #1', // key => value pair (value is stored in DB)
+ 'option2' => 'Option #2'
+ )
));
- x_add_metadata_field('x_userCheckboxField1', 'user', array(
- 'label' => 'Checkbox says what?'
- , 'field_type' => 'checkbox'
+ // adds a field to posts and users
+ x_add_metadata_field('x_fieldName2', array( 'post', 'user' ), array(
+ 'group' => 'x_metaBox2'
));
- x_add_metadata_field('x_userAndPostField1', array( 'post', 'user' ), array(
-
+ // adds a field with a custom display callback (see below)
+ x_add_metadata_field('x_fieldCustomHidden1', 'x_test', array(
+ 'group' => 'x_metaBox1',
+ 'display_callback' => 'fieldCustomHidden1_display' // this function is defined below
));
- x_add_metadata_field('x_cap-limited-field', 'post', array(
- 'label' => 'Cap Limited Field (edit_posts)'
- , 'required_cap' => 'edit_posts' // limit to users who can edit posts
- ));
- x_add_metadata_field('x_user-cap-limited-field', 'user', array(
- 'label' => 'Cap Limited Field (edit_user)'
- , 'required_cap' => 'edit_user' // limit to users who can edit other users
+ // field with capabilities limited
+ x_add_metadata_field('x_cap-limited-field', 'x_test', array(
+ 'label' => 'Cap Limited Field (edit_posts)',
+ 'required_cap' => 'edit_posts' // limit to users who can edit posts
));
+ // field with role limited
x_add_metadata_field('x_author-cap-limited-field', 'user', array(
- 'label' => 'Cap Limited Field (author)'
- , 'required_cap' => 'author' // limit to authors
- ));
-
- x_add_metadata_group( 'x_milestone-info', 'milestone', $args = array(
- 'label' => 'Milestone Info'
- ) );
-
- x_add_metadata_field('x_year', 'milestone', array(
- 'group' => 'x_milestone-info'
- , 'description' => 'Enter the year for this milestone, e.g. 1991'
- , 'label' => 'Year'
- , 'display_column' => true
+ 'label' => 'Cap Limited Field (author)',
+ 'required_cap' => 'author' // limit to authors
));
+ // comment field
x_add_metadata_field('x_commentField1', 'comment', array(
- 'label' => 'Field for Comment'
- , 'display_column' => true
+ 'label' => 'Field for Comment',
+ 'display_column' => true
));
+ // field that exludes posts
x_add_metadata_field('x_fieldNameExcluded1', 'post', array(
- 'description' => 'This field is excluded from Post ID#2476'
- , 'label' => 'Excluded Field'
- , 'exclude' => 2476
+ 'description' => 'This field is excluded from Post ID#2476',
+ 'label' => 'Excluded Field',
+ 'exclude' => 2476
));
+ // field that includes certain posts only
x_add_metadata_field('x_fieldNameIncluded1', 'post', array(
- 'description' => 'This field is only included on Post ID#2476'
- , 'label' => 'Included Field'
- , 'include' => 2476
+ 'description' => 'This field is only included on Post ID#2476',
+ 'label' => 'Included Field',
+ 'include' => 2476
));
}
+}
+
+/**
+ * this is an example of a column callback function
+ * it echoes out a bogus description, but it's just so you can see how it works
+ *
+ * @param string $field_slug the slug/id of the field
+ * @param object $field the field object
+ * @param string $object_type what object type is the field associated with
+ * @param int $object_id the ID of the current object
+ * @param string $value the value of the field
+ * @return void
+ */
+function fieldName2_columnCallback( $field_slug, $field, $object_type, $object_id, $value ) {
+ echo sprintf( 'The value of field "%s" is %s. <br /><a href="http://icanhascheezburger.files.wordpress.com/2010/10/04dc84b6-3dde-45db-88ef-f7c242731ce3.jpg">Here\'s a LOLCat</a>', $field_slug, $value ? $value : 'not set' );
+}
+
+/**
+ * this is another example of a custom callback function
+ * we've chosen not to include all of the params this time
+ *
+ * @param string $field_slug the slug/id of the field
+ * @param object $field the field object
+ * @param string $object_type what object type is the field associated with
+ * @return void
+ */
+function fieldCustomHidden1_display( $field_slug, $field, $value ) {
+ if( ! $value ) $value = 'This is a secret hidden value! Don\'t tell anyone!';
+ ?>
+ <hr />
+ <p>This is a hidden field rendered with a custom callback. The value is "<?php echo $value; ?>".</p>
+ <input type="hidden" name="<?php echo $field_slug; ?>" value="<?php echo $value; ?>" />
+ <hr />
+ <?php
}
View
17 js/custom-metadata-manager.js
@@ -1,6 +1,7 @@
var formfield;
jQuery(document).ready(function($) {
+ // duplicating fields
if ( $('.add-multiple').length ) {
$('.add-multiple').live('click', function(e) {
e.preventDefault();
@@ -15,6 +16,7 @@ jQuery(document).ready(function($) {
});
}
+ // deleting fields
if ( $('.del-multiple').length ) {
$('.del-multiple').live('click', function(e) {
e.preventDefault();
@@ -24,19 +26,7 @@ jQuery(document).ready(function($) {
});
}
- if ( $('.custom-metadata-field.wysiwyg #editor-toolbar a').length ) {
- $('.custom-metadata-field.wysiwyg #editor-toolbar a').click(function(){
- $(this).siblings().removeClass('active');
- $(this).addClass('active');
- var parent_id = $(this).parent().parent().attr('id');
- if ($('#'+parent_id+' #edButtonHTML').hasClass('active')){
- $('#'+parent_id+' #quicktags').show();
- } else {
- $('#'+parent_id+' #quicktags').hide();
- }
- });
- }
-
+ // init the upload fields
if ( $('.upload_button').length ) {
$('.upload_button').live('click', function(e) {
formfield = $(this).parent().attr('id');
@@ -53,6 +43,7 @@ jQuery(document).ready(function($) {
}
}
+ // init the datepicker fields
if ( $('.datepicker').length ) {
$( '.datepicker input' ).datepicker({changeMonth: true, changeYear: true});
}
View
97 readme.txt
@@ -2,9 +2,9 @@
Contributors: batmoo, jkudish, cvernon, stresslimit
Donate link: http://digitalize.ca/donate
Tags: custom metadata, custom metadata manager metadata, postmeta, post meta, user meta, custom post types, custom fields, metabox, metadata api, metadata
-Requires at least: 3.0
-Tested up to: 3.3.1
-Stable tag: 0.5.7
+Requires at least: 3.3
+Tested up to: 3.4-alpha
+Stable tag: 0.6
An easy way to add custom fields to your object types (post, pages, custom post types, users)
@@ -41,7 +41,7 @@ This is also a developer feature, aimed towards site builders. And real develope
(But really, though, the main benefit of this fact comes into play when you're working with multiple environments, i.e. development/local, qa/staging, production. This approach makes it easy to replicate UIs and features without having to worry about database synchronization and other crazy things.)
-For another really well-done, really powerful code-based plugin for managing custom fields, check out [Easy Custom Fields](http://wordpress.org/extend/plugins/easy-custom-fields/).
+For another really well-done, really powerful code-based plugin for managing custom fields, check out [Easy Custom Fields](http://wordpress.org/extend/plugins/easy-custom-fields/) and the [Custom Metaboxes and Fields For WordPress Class](https://github.com/jaredatch/Custom-Metaboxes-and-Fields-for-WordPress).
= Why isn't the function just `add_metadata_field`? Do you really need the stupid `x_`? =
@@ -50,38 +50,63 @@ We're being good and ["namespacing" our public functions](http://andrewnacin.com
== Screenshots ==
1. Write easy, intuitive and WordPress-like code to add new fields.
-2. Custom Metadata Manager supports basic field types with an way to render your own.
-3. An example of what's possible with only 40 lines of code.
-4. Adding custom columns is also easy. You can go with a default display, or specify your own output callback
+2. Custom Metadata Manager supports many field types with an easy way to render your own.
+3. Adding custom columns is also easy. You can go with a default display, or specify your own output callback
== Changelog ==
+= 0.6 =
+
+* note: the plugin now requires WordPress 3.3+ (chiefly for the wysiwyg + datepicker fields)
+* update/clean-up the examples file
+* properly enqueue admin css for WP 3.3+
+* added a filter for the CUSTOM_METADATA_MANAGER_URL constant
+* fix fields not appearing when editing users in WP 3.3+ (props @FolioVision)
+* now passing the $value for a display_callback (props @FolioVision)
+* use the new 'wp_editor()' function (since WP 3.3+) instead of 'the_editor()' (now deprecated)
+* wysiwyg fields are no longer cloneable (may be revisited in a future version)
+* note: metaboxes that have a wysiwyg field will break when moved, this is not a bug per-se (may be revisited in a future version)
+* password fields are now cloneable
+* added filters for most of the plugin's internal variables
+* now using WordPress' built-in jQuery UI for the datepicker field
+* updated the screenshots
+* updated the instructions in readme.txt
+
+
= 0.5.7 =
+
* pass additional params for display_callback
= 0.5.6 =
+
* fix bugs with datepicker
= 0.5.5 =
+
* remove all whitespace
* fix some bugs with the tinymce field
= 0.5.4 =
+
* fix display_callback for fields
= 0.5.3 =
+
* removed php opening shorttags `<?` in favor of regular `<?php` tags, which caused parse errors on some servers
= 0.5.2 =
+
* better tiny mce implementation and added html/visual switch
* small css fixes and added inline documentation
* moved DEFINEs in to admin_init() so that they can be filtered more easily
= 0.5.1 =
+
* Bug fix with group context on add meta box
* Remove few lines of old code left-over from 0.4
= 0.5 =
+
* Making the changes from 0.4 public
* Removed ability to generate option pages; after further consideration this is out of scope for this project
* Removed attachment_list field, useless
@@ -92,6 +117,7 @@ We're being good and ["namespacing" our public functions](http://andrewnacin.com
* Other small improvements
= 0.4 =
+
* Enhanced the code which generates the different field types
* Added new types: password, upload, wysiwyg, datepicker, taxonomy_select, taxonomy_radio, attachment_list
* Added field multiplication ability
@@ -99,6 +125,7 @@ We're being good and ["namespacing" our public functions](http://andrewnacin.com
* Can now also generate option pages which use a metabox interface
= 0.3 =
+
* Can now limit or exclude fields or groups from specific ids
* Added updated screenshots and new code samples!
* Bug fix: the custom display examples weren't working well
@@ -106,18 +133,20 @@ We're being good and ["namespacing" our public functions](http://andrewnacin.com
* Bug fix: fields not showing on "My Profile" page. Thanks Mike Tew!
= 0.2 =
+
* Added a textarea field type
* Added support for comments (you can now specify comments as an object type)
* Added basic styling for fields so that they look nice
= 0.1 =
+
* Initial release
== Usage ==
= Object Types =
-The main idea behind this plugin is to have a single API to work with regardless of the object type. Currently, Custom Metadata Manager works with `user`, `comment` and any built-in or custom post types, e.g. `post`, `page`, etc. Since version 0.4 of the plugin, option pages are also supported.
+The main idea behind this plugin is to have a single API to work with regardless of the object type. Currently, Custom Metadata Manager works with `user`, `comment` and any built-in or custom post types, e.g. `post`, `page`, etc.
= Registering your fields =
@@ -133,7 +162,6 @@ function my_theme_init_custom_fields() {
}
`
-
= Getting the data =
You can get the data as you normally would using the `get_metadata` function. Custom Metadata manager stores all data using the WordPress metadata APIs using the slug name you provide. That way, even if you decide to deactivate this wonderful plugin, your data is safe and accessible. For options, you can use `get_option`.
@@ -161,12 +189,12 @@ x_add_metadata_group( $slug, $object_types, $args );
**Options and Overrides**
`
$args = array(
- 'label' => $group_slug // Label for the group
- , 'context' => 'normal' // (post only)
- , 'priority' => 'default' // (post only)
- , 'autosave' => false // (post only) Should the group be saved in autosave? NOT IMPLEMENTED YET!
- , 'exclude' => '' // see below for details
- , 'include' => '' // see below for details
+ 'label' => $group_slug, // Label for the group
+ 'context' => 'normal', // (post only)
+ 'priority' => 'default', // (post only)
+ 'autosave' => false, // (post only) Should the group be saved in autosave? NOT IMPLEMENTED YET!
+ 'exclude' => '', // see below for details
+ 'include' => '', // see below for details
);
`
@@ -185,24 +213,25 @@ $args = array(
**Options and Overrides**
`
$args = array(
- 'group' => '' // The slug of group the field should be added to. This needs to be registered with x_add_metadata_group first.
- , 'field_type' => 'text' // The type of field; possible values: text, textarea, checkbox, radio, select
- , 'label' => '' // Label for the field
- , 'description' => '' // Description of the field, displayed below the input
- , 'values' => array() // Values for select and radio buttons. Associative array
- , 'display_callback' => '' // Callback to custom render the field
- , 'sanitize_callback' => '' // Callback to sanitize data before it's saved
- , 'display_column' => false // Add the field to the columns when viewing all posts
- , 'display_column_callback' => '' // Callback to render output for the custom column
- , 'required_cap' => '' // The cap required to view and edit the field
- , 'exclude' => '' // see below for details
- , 'include' => '' // see below for details
+ 'group' => '', // The slug of group the field should be added to. This needs to be registered with x_add_metadata_group first.
+ 'field_type' => 'text', // The type of field; 'text', 'textarea', 'password', 'checkbox', 'radio', 'select', 'upload', 'wysiwyg', 'datepicker', 'taxonomy_select', 'taxonomy_radio'
+ 'label' => '', // Label for the field
+ 'description' => '', // Description of the field, displayed below the input
+ 'values' => array(), // Values for select and radio buttons. Associative array
+ 'display_callback' => '', // Callback to custom render the field
+ 'sanitize_callback' => '', // Callback to sanitize data before it's saved
+ 'display_column' => false, // Add the field to the columns when viewing all posts
+ 'display_column_callback' => '', // Callback to render output for the custom column
+ 'required_cap' => '', // The cap required to view and edit the field
+ 'exclude' => '', // see below for details
+ 'include' => '', // see below for details
+ 'multiple' => false, // true or false, can the field be duplicated with a click of a button?
);
`
= Include / Exclude =
-With v0.3, you can exclude fields and groups from specific object. For example, with the following, field-1 will show up for all posts except post #123:
+You can exclude fields and groups from specific object. For example, with the following, field-1 will show up for all posts except post #123:
`
$args = array(
@@ -232,8 +261,8 @@ With multiple object types, you can pass in an associative array:
`
$args = array(
'exclude' => array(
- 'post' => 123
- , 'user' => array( 123, 456, 789 )
+ 'post' => 123,
+ 'user' => array( 123, 456, 789 )
)
);
@@ -253,4 +282,10 @@ Stuff we have planned for the future:
* Limit or exclude groups and fields using a custom callback
* Autosave support for fields on post types
* Client- and server-side validation support
-* Add groups and fields to Quick Edit
+* Add groups and fields to Quick Edit
+
+== Upgrade Notice ==
+
+= 0.6 =
+
+Version 0.6 and higher of the plugin uses new APIs available in WordPress 3.3+, so please make sure you're running WordPress 3.3 or higher before upgrading this plugin.
View
BIN  screenshot-1.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  screenshot-1.png
Deleted file not rendered
View
BIN  screenshot-2.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  screenshot-2.png
Deleted file not rendered
View
BIN  screenshot-3.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  screenshot-3.png
Deleted file not rendered
View
BIN  screenshot-4.png
Deleted file not rendered
Please sign in to comment.
Something went wrong with that request. Please try again.