Created
May 14, 2015 14:00
-
-
Save gschoppe/3ccc31b2e7f596bca08c to your computer and use it in GitHub Desktop.
Wordpress Board of Directors Custom Post Type, with custom profile pictures and meta information (http://www.gschoppe.com)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// archiveboard.php (companion to cpt-board.php) | |
// by Greg Schoppe (http://gschoppe.com) | |
// Licensed under GPL | |
// Renders archive page for board of directors custom post type | |
// Will need to be customized to match theme. This one is customized for the _TK bootstrap theme | |
get_header(); ?> | |
<?php // add the class "panel" below here to wrap the content-padder in Bootstrap style ;) ?> | |
<div class="content-padder"> | |
<?php if ( have_posts() ) : ?> | |
<header class="col-xs-12"> | |
<h1 class="page-title"> | |
Board of Directors | |
</h1> | |
<?php | |
// Show an optional term description. | |
$term_description = term_description(); | |
if ( ! empty( $term_description ) ) : | |
printf( '<div class="taxonomy-description">%s</div>', $term_description ); | |
endif; | |
?> | |
</header><!-- .page-header --> | |
<?php /* Start the Loop */ ?> | |
<div class="board-members col-xs-12"> | |
<?php while ( have_posts() ) : the_post(); ?> | |
<a name="<?=get_the_ID()?>"></a> | |
<div class="row"> | |
<div class="col-sm-2"> | |
<?php | |
if(get_post_meta(get_the_ID(), '_board_member_pic', true)) { | |
$imgID = get_post_meta(get_the_ID(), '_board_member_pic', true); | |
$imgDetails = wp_get_attachment_image_src( $imgID, "board-thumb" ); | |
$imgSrc = isset($imgDetails[0])?$imgDetails[0]:""; | |
if($imgSrc) { | |
?> | |
<div class="board-image-wrap"><img src="<?=$imgSrc?>" alt="<?php the_title(); ?>"/></div> | |
<?php | |
} | |
} | |
?> | |
</div> | |
<article id="board-<?php the_ID(); ?>" class="board-member col-sm-10"> | |
<header> | |
<h2 class="page-title"><?php the_title(); ?></h2> | |
<div class="board-meta"> | |
<?php | |
if(get_post_meta(get_the_ID(), '_board_member_title', true)) { | |
?> | |
<span class="board-position"><?=get_post_meta(get_the_ID(), '_board_member_title', true).", "?></span> | |
<?php | |
} | |
if(get_post_meta(get_the_ID(), '_board_member_company', true)) { | |
?> | |
<span class="board-company" ><?=get_post_meta(get_the_ID(), '_board_member_company', true)?></span> | |
<?php } ?> | |
</div> | |
</header><!-- .entry-header --> | |
<div class="entry-content"> | |
<?php the_content( __( 'Continue reading <span class="meta-nav">→</span>', '_tk' ) ); ?> | |
<?php | |
wp_link_pages( array( | |
'before' => '<div class="page-links">' . __( 'Pages:', '_tk' ), | |
'after' => '</div>', | |
) ); | |
?> | |
</div><!-- .entry-content --> | |
</article><!-- #post-## --> | |
</div> | |
<?php endwhile; ?> | |
<?php _tk_content_nav( 'nav-below' ); ?> | |
</div> | |
<?php else : ?> | |
<?php get_template_part( 'no-results', 'archive' ); ?> | |
<?php endif; ?> | |
</div><!-- .content-padder --> | |
<?php get_footer(); ?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// CPT Board | |
// by Greg Schoppe (http://gschoppe.com) | |
// Licensed under GPL | |
// creates board members post type, to render custom board of directors archive page | |
// usage: in functions.php, add require_once('cpt-board.php'); | |
// then add both files to theme root directory | |
// add custom image size for board member images | |
add_action( 'after_setup_theme', function() { | |
add_image_size( 'board-thumb', 350, 350, true ); | |
}); | |
// register custom 'board' post type | |
add_action('init', function() { | |
register_post_type('board', | |
array( | |
'labels' => array( | |
'name' => __( 'Board Members' ), | |
'singular_name' => __( 'Board Member' ), | |
'add_new_item' => __('Add New Board Member'), | |
'edit_item' => __('Edit Member'), | |
'new_item' => __('New Member'), | |
'view_item' => __('View Member') | |
), | |
'public' => true, | |
'has_archive' => true, | |
'show_in_nav_menus' => true | |
) | |
); | |
}); | |
// redirect single posts to the archive page, scrolled to current ID | |
add_action( 'template_redirect', function() { | |
if ( is_singular('board') ) { | |
global $post; | |
$redirectLink = get_post_type_archive_link( 'board' )."#".$post->ID; | |
wp_redirect( $redirectLink, 302 ); | |
exit; | |
} | |
}); | |
// turn off pagination for the archive page | |
add_action('parse_query', function($query) { | |
if (is_post_type_archive('board')) { | |
$query->set('nopaging', 1); | |
} | |
}); | |
// change the post title to request the name of the board member | |
add_filter( 'enter_title_here', function( $title ) { | |
$screen = get_current_screen(); | |
if ( 'board' == $screen->post_type ) { | |
$title = 'Enter Name Here'; | |
} | |
return $title; | |
}); | |
// add custom metabox for profile picture, name, title | |
add_action('add_meta_boxes', function() { | |
// Define the custom attachment for posts | |
add_meta_box( | |
'board_member_meta', | |
'Member Information', | |
'board_member_meta_box', | |
'board', | |
'normal', | |
'high' | |
); | |
}); | |
// render metabox | |
function board_member_meta_box($post) { | |
// create security nonce | |
wp_nonce_field('wp_board_member_nonce', 'wp_board_member_nonce'); | |
// get any existing values (if we're editing a board member) | |
$company = get_post_meta( $post->ID, '_board_member_company' , true ); | |
$title = get_post_meta( $post->ID, '_board_member_title' , true ); | |
$pic = get_post_meta( $post->ID, '_board_member_pic' , true ); | |
$picsrc = wp_get_attachment_image_src( $pic, "thumbnail" ); | |
?> | |
<table> | |
<tr> | |
<td><label for="board_member_company">Company: </label></td> | |
<td><input id="board_member_company" name="board_member_company" type="text" value="<?=$company?>"/></td> | |
</tr><tr> | |
<td><label for="board_member_title">Position: </label></td> | |
<td><input id="board_member_title" name="board_member_title" type="text" value="<?=$title?>"/></td> | |
</tr><tr> | |
<td><label for="board_member_pic">Picture: </label></td> | |
<td> | |
<input id="board_member_pic" name="board_member_pic" type="hidden" value="<?=$pic?>"/> | |
<img src="<?=$picsrc[0]?>" id="board_member_pic-vis" width="150" height="150" alt="preview" style="display: block; float: none;"/> | |
<input id="board_member_pic_button" class="button" name="board_member_pic_button" type="button" value="Choose Profile Image"/> | |
</td> | |
</tr> | |
</table> | |
<?php | |
// this is how we attach the media manager to the metabox | |
?> | |
<script type="text/javascript"> | |
jQuery(document).ready(function($){ | |
var _custom_media = true, | |
_orig_send_attachment = wp.media.editor.send.attachment; | |
$('#board_member_pic_button').click(function(e) { | |
var send_attachment_bkp = wp.media.editor.send.attachment; | |
var button = $(this); | |
// this is just my shorthand for the id for hidden field associated with the button. could be hard coded | |
var id = button.attr('id').replace('_button', ''); | |
_custom_media = true; | |
wp.media.editor.send.attachment = function(props, attachment){ | |
if ( _custom_media ) { | |
$("#"+id).val(attachment.id); | |
if(typeof attachment.sizes.thumbnail != "undefined" && typeof attachment.sizes.thumbnail.url != "undefined") { | |
var src = attachment.sizes.thumbnail.url; | |
} else { | |
var src = attachment.url; | |
// warning, in case the image is too small to generate a thumbnail | |
alert('WARNING: This image is below the recommended dimensions of 500x500 pixels.'); | |
} | |
// this one is my shorthand for the preview element id. could be hard coded instead | |
$("#"+id+"-vis").attr('src', src); | |
} else { | |
return _orig_send_attachment.apply( this, [props, attachment] ); | |
}; | |
} | |
wp.media.editor.open(button); | |
return false; | |
}); | |
$('.add_media').on('click', function(){ | |
_custom_media = false; | |
}); | |
}); | |
</script> | |
<?php | |
} | |
// save values entered into metabox | |
add_action( 'save_post', function($post_id) { | |
// verify nonce | |
if(!isset($_POST['wp_board_member_nonce']) || !wp_verify_nonce($_POST['wp_board_member_nonce'], 'wp_board_member_nonce')) { | |
return; | |
} | |
// ignore autosaves (this is up to you. it might be good for the metabox to autosave with drafts, but it adds complexity) | |
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { | |
return; | |
} | |
// check post type | |
if(!(isset($_POST['post_type']) && 'board' == $_POST['post_type'])) { | |
return; | |
} | |
// check user priviledges | |
if (!current_user_can('edit_page', $post_id)) { | |
return; | |
} | |
// get field values | |
$company = (isset($_POST['board_member_company']))?sanitize_text_field($_POST['board_member_company']):""; | |
$title = (isset($_POST['board_member_title']))?sanitize_text_field($_POST['board_member_title']):""; | |
$pic = (isset($_POST['board_member_pic']))?sanitize_text_field($_POST['board_member_pic']):""; | |
// update the meta values | |
update_post_meta( $post_id, '_board_member_company', $company ); | |
update_post_meta( $post_id, '_board_member_title', $title ); | |
update_post_meta( $post_id, '_board_member_pic', $pic ); | |
}); | |
// move the editor below the custom meta box (this is a nasty hack, but seems to work ok) | |
add_action('add_meta_boxes', function() { | |
global $_wp_post_type_features; | |
//move editor | |
if (isset($_wp_post_type_features['board']['editor']) && $_wp_post_type_features['board']['editor']) { | |
// remove the editor from it's normal position | |
unset($_wp_post_type_features['board']['editor']); | |
// create a clone of it in a custom metabox | |
add_meta_box( | |
'bio_section', | |
__('Biography'), | |
function($post) { | |
echo '<div class="wp-editor-wrap">'; | |
wp_editor($post->post_content, 'content', array('dfw' => true, 'tabindex' => 1) ); | |
echo '</div>'; | |
}, | |
'board', | |
'normal', | |
'high' | |
); | |
} | |
// add styles to make the editor look normal | |
add_action( 'admin_head', function(){ | |
?> | |
<style type="text/css"> | |
.wp-editor-container{background-color:#fff;} | |
</style> | |
<?php | |
}); | |
}); | |
// Add CPT Archives to menu list (works for all CPTs, so should only happen once, site-wide) | |
if(!defined("ADD-CPT-ARCHIVES-TO-WP-MENUS")) { | |
define("ADD-CPT-ARCHIVES-TO-WP-MENUS", true); | |
add_action( 'admin_head-nav-menus.php', function() { | |
add_meta_box( 'add-cpt', __( 'CPT Archives' ), function() { | |
// get custom post types with archive support | |
$post_types = get_post_types( array( 'show_in_nav_menus' => true, 'has_archive' => true ), 'object' ); | |
// hydrate the necessary properties for identification in the walker (read as: insert magic here) | |
foreach ( $post_types as &$post_type ) { | |
$post_type->classes = array(); | |
$post_type->type = $post_type->name; | |
$post_type->object_id = $post_type->name; | |
$post_type->title = $post_type->labels->name . ' ' . __( 'Archive', 'default' ); | |
$post_type->object = 'cpt-archive'; | |
$post_type->menu_item_parent = 0; | |
$post_type->url = 0; | |
$post_type->target = 0; | |
$post_type->attr_title = 0; | |
$post_type->xfn = 0; | |
$post_type->db_id = 0; | |
} | |
// the native menu checklist | |
$walker = new Walker_Nav_Menu_Checklist( array() ); | |
?> | |
<div id="cpt-archive" class="posttypediv"> | |
<div id="tabs-panel-cpt-archive" class="tabs-panel tabs-panel-active"> | |
<ul id="ctp-archive-checklist" class="categorychecklist form-no-clear"> | |
<?php | |
echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', $post_types), 0, (object) array( 'walker' => $walker) ); | |
?> | |
</ul> | |
</div><!-- /.tabs-panel --> | |
<p class="button-controls"> | |
<span class="add-to-menu"> | |
<input type="submit"<?php disabled( $nav_menu_selected_id, 0 ); ?> class="button-secondary right submit-add-to-menu" value="<?php esc_attr_e('Add to Menu'); ?>" name="add-ctp-archive-menu-item" id="submit-cpt-archive" /> | |
<span class="spinner"></span> | |
</span> | |
</p> | |
</div> | |
<?php | |
}, 'nav-menus', 'side', 'default' ); | |
}); | |
// take care of the URLs and active status for CPT Archives in menus | |
add_filter( 'wp_get_nav_menu_items', function( $items, $menu, $args ) { | |
// alter the URL for cpt-archive objects | |
foreach ( $items as &$item ) { | |
if ( $item->object != 'cpt-archive' ) continue; | |
$item->url = get_post_type_archive_link( $item->type ); | |
// set current | |
if ( get_query_var( 'post_type' ) == $item->type ) { | |
$item->classes []= 'current-menu-item'; | |
$item->current = true; | |
} | |
} | |
return $items; | |
}, 10, 3 ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment