Be warned! Several people have experienced a nasty bug with this fieldset duplication method. Reports of lost data upon saving multiple field groups has popped up, so be cautious using this. As of 2/10/2010 Hiraoki has updated the plugin to 1.8.2 to resolve these issues, though it hasn’t been verified.
I absolutely love using the Custom Field Template Plugin for WordPress CMS setups. With it you can quickly turn WordPress into a fully fledged content management system that is intuitive and easy to use. Hiroaki Miyashita, the programmer behind the plugin, recently added a few new features that allow you to manage multiple custom fields. Using the multiple = true and multipleButton = true option you’re able to do this for single fields, and also groups of fields.
To create a single field that can be duplicated it’s actually very simply. To create the field in CFT you’ll need to use the following syntax:
[duplicate_field]
type = text
label = Item
multipleButton = true
multiple = true
After that, the following PHP will allow you to get all duplicate fields entered from within one of your theme templates.
// Get duplicate fields
$duplicate_field = get_post_custom_values('duplicate_field', $post->ID);
foreach ( $duplicate_field as $key => $value ) {
echo $value . '<br />';
}
Duplicate groups are wonderful, they allow a group of fields to be re-used an infinite number of times. This opens up many new doors for custom field management. Carousels, content sliders and image galleries are just a few examples of what you can create with this approach.
[cft_group_fieldset]
type = fieldset_open
legend = Group #1
multiple = true
multipleButton = true
[cft_group_title]
type = text
label = Title
blank = true
[cft_group_description]
type = textarea
label = Description
blank = true
[cft_group_size]
type = select
label = Size
value = Small # Medium # Large
default = Right
blank = true
[cft_group_order]
type = text
label = Order
blank = true
[cft_group_fieldset]
type = fieldset_close
The following function is a slightly modified version of a function created by proximity2008 in the Support Forums. It will run a lean WPDB call to query all of the fields in our repeating fieldset group’s. Thanks Proximity!
// Get Custom Field Template duplicates
if( !function_exists('get_cft_repeating_data') ){
function get_cft_repeating_data( $like_item ){
global $post, $wpdb;
$sql = "SELECT * FROM $wpdb->postmeta WHERE post_id = $post->ID AND meta_key LIKE '%" . $like_item . "%' ORDER BY meta_id ASC";
$data_objects = $wpdb->get_results($sql);
$project = array();
$i = 0;
$fieldset = $like_item . '_fieldset';
foreach($data_objects as $data) {
// the name of the fieldset:
if ( $data->meta_key == $fieldset ) {
$limit = $data->meta_value - 1;
}
$i = ( $i <= $limit ) ? $i : 1;
if( $data->meta_key != $fieldset && $data->meta_value !='' ) {
$project[$i]["$data->meta_key"] = $data->meta_value;
}
$i++;
}
if(!$limit && is_user_logged_in() )
echo 'Could not establish Custom Field Limit. The $like_item set was ' .$like_item . '<br /> SQL query was ' . $sql;
return $project;
}
}
Right now it is very rough, and I’ve just begun using this on various projects so hopefully I can continue to improve upon it. If anyone has improvements to this function please let me know, I’m sure it could use some work!
Once we have our group’s stored in a PHP associative array, we’ll probably need to allow CMS users to control the order of the groups. This handy function will do the trick nicely, add it your functions,php file.
// Sort multidimensional array
if( !function_exists('order_array_num') ){
function order_array_num ($array, $key, $order = "ASC"){
$tmp = array();
foreach($array as $akey => $array2){
$tmp[$akey] = $array2[$key];
}
if($order == "DESC"){
arsort($tmp , SORT_NUMERIC );
} else {
asort($tmp , SORT_NUMERIC );
}
$tmp2 = array();
foreach($tmp as $key => $value){
$tmp2[$key] = $array[$key];
}
return $tmp2;
}
}
This will let us control the order and sort of the field group’s using the cft_group_order field we created.
// Get all duplucate fields from the database and store in array
$cft_groups = get_cft_repeating_data('cft_group');
$cft_groups = order_array_num($cft_groups, 'cft_group_order', 'ASC');
// Display groups
echo '<div id="cft-groups">';
foreach ($cft_groups as $s => $v) {
// First check for data then define variables
if( !empty($cft_groups[$s]['cft_group_title']) )
$title = strtolower($cft_groups[$s]['cft_group_title']);
if( !empty($cft_groups[$s]['cft_group_description']) )
$description = strtolower($cft_groups[$s]['cft_group_description']);
if( !empty($cft_groups[$s]['cft_group_size']) )
$size = strtolower($cft_groups[$s]['cft_group_size']);
// Output HTML for a group
echo '<div id="group-'.$s.'" class="group';
if(isset($size)) echo ' ' .$size;
echo '">';
if(isset($title)) echo '<h2>' . $title . '</h2>';
if(isset($description)) echo '<div class="desc">' . $subtitle . '</div>';
echo '</div><!--// end #group-'.$s.' -->';
}
echo '</div><!--// end #cft-groups -->';
You’ll need to switch out the cft_group values to match you’re own implementation.
I hope this example spark’s some ideas for your next WordPress CMS project. If it does, please don’t hesitate to let me know know about them in your comments!