1
votes

I have a wordpress project that will be primarily used as a CMS. Thanks to this wonderful community, I've gone from knowing nothing about WordPress to being able to create custom post types (for my Product list), categorize them using hierarchical taxonomies, and create custom fields for this Product Post Type.

Now, my Products are pretty simple. They have a ProductName, a ProductType, a ProductCategory, DocumentName, and DocumentURL. The last two are related because DocumentURL is a link to a PDF on the web, and DocumentName is a label for the DocumentURL. I've created custom fields for my DocumentName and DocumentURL and can add 1 of each to each Product custom post. However, my Product could have MANY Document URL's and Document Names, or it could have 1, or even 0. Is there a way to make it dynamic so it doesn't matter how many I have? Or do I need to come up with a max number and create that many custom fields for the Product custom post?

If this was just straight PHP or ASP.NET I would just create a seperate db table for the Document elements and throw together a nice form with some jQuery that started with 2 or 3 document fields, and if they needed more they could click the + symbol to add another row of document fields (like this http://deepliquid.com/projects/appendo/demos.php). Then loop through them and add them to the database. Would something like this be possible with WordPress?

The only other idea I had was creating a new custom post type for documents and creating a relationship to their products, but I can't wrap my head around how that would work.

Any advice will be greatly appreciated! Thank you!

1

1 Answers

4
votes

I'm gonna assume you are comfortable with PHP given what you've said here. The good news is your PHP knowledge will come in handy here. It's time you learn a new feature of the register_post_type function; that is, the register_meta_box_cb parameter. This allows you to define a function to called to add a metabox on the cpt add and edit pages. For instance, here is a cpt (taken straight from the codex) with the added parameter:

add_action('init', 'codex_custom_init');
function codex_custom_init() 
{
  $labels = array(
    'name' => _x('Books', 'post type general name'),
    'singular_name' => _x('Book', 'post type singular name'),
    'add_new' => _x('Add New', 'book'),
    'add_new_item' => __('Add New Book'),
    'edit_item' => __('Edit Book'),
    'new_item' => __('New Book'),
    'view_item' => __('View Book'),
    'search_items' => __('Search Books'),
    'not_found' =>  __('No books found'),
    'not_found_in_trash' => __('No books found in Trash'), 
    'parent_item_colon' => '',
    'menu_name' => 'Books'

  );
  $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,
    'register_meta_box_cb' => 'my_meta_box_function',
    'supports' => array('title','editor','author','thumbnail','excerpt','comments')
  ); 
  register_post_type('book',$args);
}}

Now that you have the meta box cb function defined, use it like:

function my_beta_box_function(){
    add_meta_box(
        'myplugin_sectionid',
        __( 'My Post Section Title', 'myplugin_textdomain' ), 
        'myplugin_inner_custom_box',
        'book'
    );
}

The add_meta_box defines a meta box for you and provides a function that creates the content within the metabox. In this case, our code is referring to the function myplugin_inner_custom_box. Take a look at http://codex.wordpress.org/Function_Reference/add_meta_box for more on adding meta boxes. So, we now need to add our content by defining the function:

function myplugin_inner_custom_box()
{
   // Everything here would appear in the meta box
}

At this point, you can utilize your PHP knowledge to create an HTML form that can be processed on post submit. You can add your + button and use your PHP just like you would in any other PHP application. I won't go into how to do this because I'll assume you can do it. I've actually create a few metaboxes like this and after knowing the functions I posted, I could just rely on my PHP knowledge. The last piece of this is saving the input. By using a function that defines your save routine and the save_post action, you can use your PHP knowledge to save the data:

/* Do something with the data entered */
add_action('save_post', 'myplugin_save_postdata');

/* When the post is saved, saves our custom data */
function myplugin_save_postdata( $post_id ) {
  // verify if this is an auto save routine. 
  // If it is our form has not been submitted, so we dont want to do anything
  if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) 
      return $post_id;

  // verify this came from the our screen and with proper authorization,
  // because save_post can be triggered at other times

  if ( !wp_verify_nonce( $_POST['myplugin_noncename'], plugin_basename(__FILE__) ) )
      return $post_id;


  // Check permissions
  if ( 'page' == $_POST['post_type'] ) 
  {
    if ( !current_user_can( 'edit_page', $post_id ) )
        return $post_id;
  }
  else
  {
    if ( !current_user_can( 'edit_post', $post_id ) )
        return $post_id;
  }

  // OK, we're authenticated: we need to find and save the data

  $mydata = $_POST['myplugin_new_field'];

  update_post_meta('my_field', $mydata);

   return $mydata;
}

Finally, a note on the save function. If you name your input fields with an array value (e.g., docs[]), the $_POST['docs'] value will be an array. Fortunately, WP's update_post_meta function is all setup to handle array inputs. It will serialize it and input it. Using the compatible get_post_meta function will unserialize the array for use ready the data out.

Good luck!