In a recent project, I needed the ability to create a custom post type with custom fields for an employee directory. Konstantin wrote an excellent post on how to use custom post types in WordPress. I used his podcast custom post type model as a base and built upon it to create a directory listing plugin. It has turned out very well so far. I have posted the plugin below and will post the templates I use to call the custom fields and display the directory listings in a future post.
Note that this plugin was intended for a directory listing of higher education employees, but can be adapted for other situations.
<?php
/*
Plugin Name: Directory Listing Plugin
Plugin URI: http://www.lmunet.edu
Description: Directory Listing Post Types for WordPress 3.0 and above.
Author: Joshua Dodson
Version: 1.0
Author URI: http://betterwebstrategy.net
*/
class directory_listing10 {
var $meta_fields = array('dl10-telephone','dl10-email','dl10-office','dl10-position');
function directory_listing10()
{
// Register custom post types
register_post_type('directory_listing', array(
'labels' => array(
'name' => __( 'Directory Listings' ),
'singular_name' => __( 'Directory Listing' ),
'add_new' => __( 'Add New' ),
'add_new_item' => __( 'Add New Directory Listing' ),
'edit' => __( 'Edit' ),
'edit_item' => __( 'Edit Directory Listing' ),
'new_item' => __( 'New Directory Listing' ),
'view' => __( 'View Directory Listing' ),
'view_item' => __( 'View Directory Listing' ),
'search_items' => __( 'Search Directory Listings' ),
'not_found' => __( 'No Directory Listings found' ),
'not_found_in_trash' => __( 'No Directory Listings found in Trash' ),
'parent' => __( 'Parent Directory Listing' ),
),
'singular_label' => __('Directory Listing'),
'public' => true,
'show_ui' => true, // UI in admin panel
'_builtin' => false, // It's a custom post type, not built in
'_edit_link' => 'post.php?post=%d',
'capability_type' => 'post',
'hierarchical' => false,
'rewrite' => array("slug" => "directory-listing"), // Permalinks
'query_var' => "directory_listing", // This goes to the WP_Query schema
'supports' => array('title','author', 'editor' /*,'custom-fields'*/) // Let's use custom fields for debugging purposes only
));
add_filter("manage_edit-directory_listing_columns", array(&$this, "edit_columns"));
add_action("manage_posts_custom_column", array(&$this, "custom_columns"));
// Register custom taxonomy
register_taxonomy("department", array("directory_listing"), array("hierarchical" => true, "label" => "Departments", "singular_label" => "Department", "rewrite" => true));
register_taxonomy("building", array("directory_listing"), array("hierarchical" => false, "label" => "Buildings", "singular_label" => "Building", "rewrite" => true));
// Admin interface init
add_action("admin_init", array(&$this, "admin_init"));
add_action("template_redirect", array(&$this, 'template_redirect'));
// Insert post hook
add_action("wp_insert_post", array(&$this, "wp_insert_post"), 10, 2);
}
function edit_columns($columns)
{
$columns = array(
"cb" => "<input type=\"checkbox\" />",
"title" => "Directory Listing Title",
"dl10_description" => "Description",
"dl10_position" => "Position",
"dl10_telephone" => "Telephone",
"dl10_email" => "Email",
"dl10_office" => "Office",
"dl10_departments" => "Departments",
"dl10_buildings" => "Buildings"
);
return $columns;
}
function custom_columns($column)
{
global $post;
switch ($column)
{
case "dl10_description":
the_excerpt();
break;
case "dl10_telephone":
$custom = get_post_custom();
echo $custom["dl10-telephone"][0];
break;
case "dl10_email":
$custom = get_post_custom();
echo $custom["dl10-email"][0];
break;
case "dl10_office":
$custom = get_post_custom();
echo $custom["dl10-office"][0];
break;
case "dl10_position":
$custom = get_post_custom();
echo $custom["dl10-position"][0];
break;
case "dl10_departments":
$departments = get_the_terms(0, "department");
$departments_html = array();
if ($departments) {foreach ($departments as $department)
array_push($departments_html, '<a href="' . get_term_link($department->slug, "department") . '">' . $department->name . '</a>');
echo implode($departments_html, ", ");}
break;
case "dl10_buildings":
$buildings = get_the_terms(0, "building");
$buildings_html = array();
if ($buildings) { foreach ($buildings as $building)
array_push($buildings_html, '<a href="' . get_term_link($building->slug, "building") . '">' . $building->name . '</a>');
echo implode($buildings_html, ", "); }
break;
}
}
// Template selection
function template_redirect()
{
global $wp;
if ($wp->query_vars["post_type"] == "directory_listing")
{
include(STYLESHEETPATH . "/directory-listing.php");
die();
}
}
// When a post is inserted or updated
function wp_insert_post($post_id, $post = null)
{
if ($post->post_type == "directory_listing")
{
// Loop through the POST data
foreach ($this->meta_fields as $key)
{
$value = @$_POST[$key];
if (empty($value))
{
delete_post_meta($post_id, $key);
continue;
}
// If value is a string it should be unique
if (!is_array($value))
{
// Update meta
if (!update_post_meta($post_id, $key, $value))
{
// Or add the meta data
add_post_meta($post_id, $key, $value);
}
}
else
{
// If passed along is an array, we should remove all previous data
delete_post_meta($post_id, $key);
// Loop through the array adding new values to the post meta as different entries with the same name
foreach ($value as $entry)
add_post_meta($post_id, $key, $entry);
}
}
}
}
function admin_init()
{
// Custom meta boxes for the edit directory_listing screen
add_meta_box("dl10-meta", "Directory Listing Options", array(&$this, "meta_options"), "directory_listing", "normal", "high");
add_meta_box("dl10-position", "Position", array(&$this, "meta_position_options"), "directory_listing", "normal", "high");
}
// Admin post meta contents
function meta_options()
{
global $post;
$custom = get_post_custom($post->ID);
$telephone = $custom["dl10-telephone"][0];
$email_address = $custom["dl10-email"][0];
$office = $custom["dl10-office"][0];
?>
<p>
<label>Telephone:</label>
<br />
<input name="dl10-telephone" value="<?php echo $telephone; ?>" />
</p>
<p>
<label>Email Address:</label>
<br />
<input name="dl10-email" value="<?php echo $email_address; ?>" />
</p>
<p>
<label>Office:</label>
<br />
<input name="dl10-office" value="<?php echo $office; ?>" />
</p>
<?php
}
function meta_position_options()
{
global $post;
$custom = get_post_custom($post->ID);
$position = $custom["dl10-position"][0];
?>
<p>
<label>Position:</label>
<br />
<input name="dl10-position" value="<?php echo $position; ?>" />
</p>
<?php
}
}
// Initiate the plugin
add_action("init", "directory_listing10Init");
function directory_listing10Init() { global $dl10; $dl10 = new directory_listing10(); } ?>