This particular solution is for the Agent theme from StudioPress. If you are not using that theme you may find it less useful. Here's a solution I used for a client which replaced the Write Post Panel Plugin written by Nathan Rice. Under his solution, adding new boxes required using the add_meta_box() WordPress function. Each field is then created by copying and pasting sections of code. I thought to myself, "The program could do all that and free me from that chore." Before writing a solution I trotted over to the StudioPress Support forum to see if anyone had presented a similar solution. Turns out that many people there were having a hard time understanding what they had to edit and to copy. Well, you don't have to hit me over the head with a 2-by-4 (usually) before I get a clue. My solution uses a data structure. The programmer only needs to define the data structure and the code tears that apart behind the scene. To add a box we only need to add a new array of arrays to the data structure. Here's an example:
PHP:
  1. $sp_boxes = array (
  2.     'Property Details' => array (
  3.         array( '_square_feet', 'Square Feet:' ),
  4.         array( '_bedrooms', 'Bedrooms:' ),
  5.         array( '_basement', 'Basement (full, 1/2, finished, unfinished):' ),
  6.         array( '_addtional_features', 'Additional Features:', 'textarea' ),
  7.     ),
  8. );

This data structure tells the script to set up a form similar to this (this isn't exactly it because I am too lazy to find the css in the admin section which controls this stuff):

Property Details

















Perhaps, more importantly, this produces the exact same thing we might have done previously with some editing, copying, pasting and, potentially, human error. Below is a listing of the replacement for the Nathan Rice Plugin file: write-panel.php. You can find a file version here. It's on another web site. I'll move it over to this one soon. I am working on a full Plugin, but it will need to include a page template drop down that is not included here and I'd like to make it a PHP class. Feel free to leave comments at the bottom of this page. (You may need a user account to comment.)
PHP:
  1. <?php
  2. /*
  3.     Plugin Name: Add Dynamic Meta Boxes
  4.     Plugin URI: http://www.clarksonenergyhomes.com/wordpress/wordpress-plugin-add-dynamic-meta-boxes/
  5.     Description: Allows you to add boxes and fields to the Write Post panel, and store the value as a custom field. Based on script by Nathan Rice (http://www.nathanrice.net/)
  6.     Version: 0.1 (Not rigorously tested.)
  7.     Author: Charles Clarkson
  8.     Author URI: http://www.clarksonenergyhomes.com/wordpress/about/
  9. */
  10.  
  11. /*
  12.     Each box has a name and a set of fields. Currently,
  13.     only text and textarea fields are suppoted. 'text'
  14.     fields are the default.
  15.     To add a box named: "Name Box" with a field named
  16.     "_name", add this:
  17.     'Name Box' => array (
  18.         array( '_name', 'Name:', 'text' ),
  19.     ),
  20.     You can leave the 'text' field off. It is the default.
  21.     'Name Box' => array (
  22.         array( '_name', 'Name:' ),
  23.     ),
  24. */
  25.  
  26. // Edit this data structure to change the form in WordPress:
  27.  
  28. $sp_boxes = array (
  29.     'General Property Info' => array (
  30.         array( '_listing_price', 'Listing Price:' ),
  31.         array( '_mls', 'MLS # (if any):' ),
  32.         array( '_address', 'Address:' ),
  33.         array( '_city', 'City:' ),
  34.         array( '_state', 'State:' ),
  35.         array( '_zip_code', 'Zip Code:' ),
  36.     ),
  37.     'Property Details' => array (
  38.         array( '_square_feet', 'Square Feet:' ),
  39.         array( '_bedrooms', 'Bedrooms:' ),
  40.         array( '_basement', 'Basement (full, 1/2, finished, unfinished):' ),
  41.         array( '_addtional_features', 'Additional Features:', 'textarea' ),
  42.     ),
  43.     'Property Photos' => array (
  44.         array( '_photo_1_large', 'Photo #1 large URL:' ),
  45.         array( '_photo_1_thumbnail', 'Photo #1 thumbnail URL:' ),
  46.         array( '_photo_2_large', 'Photo #2 large URL:' ),
  47.         array( '_photo_2_thumbnail', 'Photo #2 thumbnail URL:' ),
  48.         array( '_photo_3_large', 'Photo #3 large URL:' ),
  49.         array( '_photo_3_thumbnail', 'Photo #3 thumbnail URL:' ),
  50.         array( '_photo_4_large', 'Photo #4 large URL:' ),
  51.         array( '_photo_4_thumbnail', 'Photo #4 thumbnail URL:' ),
  52.         array( '_photo_5_large', 'Photo #5 large URL:' ),
  53.         array( '_photo_5_thumbnail', 'Photo #5 thumbnail URL:' ),
  54.         array( '_photo_6_large', 'Photo #6 large URL:' ),
  55.         array( '_photo_6_thumbnail', 'Photo #6 thumbnail URL:' ),
  56.     ),
  57. );
  58.  
  59. // Do not edit past this point.
  60.  
  61. // Use the admin_menu action to define the custom boxes
  62. add_action( 'admin_menu', 'sp_add_custom_box' );
  63.  
  64. // Use the save_post action to do something with the data entered
  65. // Save the custom fields
  66. add_action( 'save_post', 'sp_save_postdata', 1, 2 );
  67.  
  68. // Adds a custom section to the "advanced" Post and Page edit screens
  69. function sp_add_custom_box() {
  70.     global $sp_boxes;
  71.  
  72.     if ( function_exists( 'add_meta_box' ) ) {
  73.  
  74.         foreach ( array_keys( $sp_boxes ) as $box_name ) {
  75.             add_meta_box( $box_name, __( $box_name, 'sp' ), 'sp_post_custom_box', 'post', 'normal', 'high' );
  76.         }
  77.     }
  78. }
  79.  
  80. function sp_post_custom_box ( $obj, $box ) {
  81.     global $sp_boxes;
  82.     static $sp_nonce_flag = false;
  83.  
  84.     // Run once
  85.     if ( ! $sp_nonce_flag ) {
  86.         echo_sp_nonce();
  87.         $sp_nonce_flag = true;
  88.     }
  89.  
  90.     // Genrate box contents
  91.     foreach ( $sp_boxes[$box['id']] as $sp_box ) {
  92.         echo field_html( $sp_box );
  93.     }
  94. }
  95.  
  96. function field_html ( $args ) {
  97.  
  98.     switch ( $args[2] ) {
  99.  
  100.         case 'textarea':
  101.             return text_area( $args );
  102.  
  103.         case 'checkbox':
  104.             // To Do
  105.  
  106.         case 'radio':
  107.             // To Do
  108.  
  109.         case 'text':
  110.         default:
  111.             return text_field( $args );
  112.     }
  113. }
  114.  
  115. function text_field ( $args ) {
  116.     global $post;
  117.  
  118.     // adjust data
  119.     $args[2] = get_post_meta($post->ID, $args[0], true);
  120.     $args[1] = __($args[1], 'sp' );
  121.  
  122.     $label_format =
  123.           '<label for="%1$s">%2$s</label><br />'
  124.         . '<input style="width: 95%%;" type="text" name="%1$s" value="%3$s" /><br /><br />';
  125.  
  126.     return vsprintf( $label_format, $args );
  127. }
  128.  
  129. function text_area ( $args ) {
  130.     global $post;
  131.  
  132.     // adjust data
  133.     $args[2] = get_post_meta($post->ID, $args[0], true);
  134.     $args[1] = __($args[1], 'sp' );
  135.  
  136.     $label_format =
  137.           '<label for="%1$s">%2$s</label><br />'
  138.         . '<textarea style="width: 95%%;" name="%1$s">%3$s</textarea><br /><br />';
  139.  
  140.     return vsprintf( $label_format, $args );
  141. }
  142.  
  143. /* When the post is saved, saves our custom data */
  144. function sp_save_postdata($post_id, $post) {
  145.     global $sp_boxes;
  146.  
  147.     // verify this came from the our screen and with proper authorization,
  148.     // because save_post can be triggered at other times
  149.     if ( ! wp_verify_nonce( $_POST['sp_nonce_name'], plugin_basename(__FILE__) ) ) {
  150.         return $post->ID;
  151.     }
  152.  
  153.     // Is the user allowed to edit the post or page?
  154.     if ( 'page' == $_POST['post_type'] ) {
  155.         if ( ! current_user_can( 'edit_page', $post->ID ))
  156.             return $post->ID;
  157.  
  158.     } else {
  159.         if ( ! current_user_can( 'edit_post', $post->ID ))
  160.             return $post->ID;
  161.     }
  162.  
  163.     // OK, we're authenticated: we need to find and save the data
  164.     // We'll put it into an array to make it easier to loop though.
  165.  
  166.     // The data is already in $sp_boxes, but we need to flatten it out.
  167.     foreach ( $sp_boxes as $sp_box ) {
  168.         foreach ( $sp_box as $sp_fields ) {
  169.             $my_data[$sp_fields[0]]$_POST[$sp_fields[0]];
  170.         }
  171.     }
  172.  
  173.     // Add values of $my_data as custom fields
  174.     // Let's cycle through the $my_data array!
  175.     foreach ($my_data as $key => $value) {
  176.         if ( 'revision' == $post->post_type  ) {
  177.             // don't store custom data twice
  178.             return;
  179.         }
  180.  
  181.         // if $value is an array, make it a CSV (unlikely)
  182.         $value = implode(',', (array)$value);
  183.  
  184.         if ( get_post_meta($post->ID, $key, FALSE) ) {
  185.  
  186.             // Custom field has a value.
  187.             update_post_meta($post->ID, $key, $value);
  188.  
  189.  
  190.         } else {
  191.  
  192.             // Custom field does not have a value.
  193.             add_post_meta($post->ID, $key, $value);
  194.         }
  195.  
  196.         if (!$value) {
  197.  
  198.             // delete blanks
  199.             delete_post_meta($post->ID, $key);
  200.         }
  201.     }
  202. }
  203.  
  204. function echo_sp_nonce () {
  205.  
  206.     // Use nonce for verification ... ONLY USE ONCE!
  207.     echo sprintf(
  208.         '<input type="hidden" name="%1$s" id="%1$s" value="%2$s" />',
  209.         'sp_nonce_name',
  210.         wp_create_nonce( plugin_basename(__FILE__) )
  211.     );
  212. }
  213.  
  214. // A simple function to get data stored in a custom field
  215. if ( !function_exists('get_custom_field') ) {
  216.     function get_custom_field($field) {
  217.        global $post;
  218.        $custom_field = get_post_meta($post->ID, $field, true);
  219.        echo $custom_field;
  220.     }
  221. }
  222.  
  223. ?>

Digg!

No Responses to “ WordPress Plugin — Add Dynamic Meta Boxes ”

You must be logged in to post a comment.