Created
February 3, 2012 07:43
-
-
Save mikeschinkel/1728805 to your computer and use it in GitHub Desktop.
Master WordPress Custom Post Types - WordCamp Atlanta 2012
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 | |
/* | |
* Code Examples for Master WordPress Custom Post Types - WordCamp Atlanta 2012 | |
* | |
* Author: Mike Schinkel | |
* Author URI: http://about.me/mikeschinkel | |
* | |
*/ | |
add_action( 'init', 'mikes_theme_init' ); | |
function mikes_theme_init() { | |
register_post_type( 'comic', array( | |
'public' => true, | |
'label' => 'Comics', | |
'query_var' => 'comic_qv', | |
'rewrite' => array( | |
'slug' =>'comics', | |
'with_front' => false | |
), | |
)); | |
register_post_type( 'episode', array( | |
'label' => 'Episodes', | |
'public' => true, | |
'query_var' => 'episode_qv', | |
'rewrite' => false, | |
'supports' => array( | |
'title', | |
'thumbnail', | |
'excerpt', | |
), | |
)); | |
register_taxonomy( 'art-style', 'comic', array( | |
'hierarchical' => true, | |
'label' => 'Art Styles', | |
'rewrite' => array( | |
'slug' => 'art-styles', | |
'with_front' => false | |
), | |
)); | |
add_rewrite_rule( | |
'^comics/([^/]*)/([^/]*)/?', | |
'index.php?post_type=episode&comic_qv=$matches[1]&episode_qv=$matches[2]', | |
'top' | |
); | |
} | |
add_action( 'restrict_manage_posts', 'mikes_theme_restrict_manage_posts' ); | |
function mikes_theme_restrict_manage_posts() { | |
$comic_id = empty( $_GET['comic_id'] ) ? 0 : $_GET['comic_id']; | |
echo 'Comic: ' . mikes_theme_comic_dropdown( $comic_id, 'comic_id' ); | |
} | |
add_filter('pre_get_posts','mikes_theme_pre_get_posts'); | |
function mikes_theme_pre_get_posts( $query ) { | |
global $pagenow; | |
global $typenow; | |
global $wp_the_query; | |
if ( $query === $wp_the_query && | |
'edit.php' == $pagenow && | |
'episode' == $typenow && | |
! empty( $_GET['comic_id'] ) ) { | |
$query->set( 'post_parent', intval( $_GET['comic_id'] ) ); | |
} | |
} | |
add_action( 'post_type_link', 'mikes_theme_post_type_link', 10, 4 ); | |
function mikes_theme_post_type_link( $link, $post, $leavename, $sample ) { | |
if ( 'episode' == $post->post_type ) { | |
$parent = get_post( $post->post_parent ); | |
$comic_slug = isset( $parent->post_name ) ? $parent->post_name : '%comic%'; | |
$episode_slug = $sample ? '%postname%' : $post->post_name; | |
$link = preg_replace( '#^(https?://[^/]+/).*$#', "$1comics/{$comic_slug}/{$episode_slug}/", $link ); | |
} | |
return $link; | |
} | |
add_action( 'request', 'mikes_theme_request' ); | |
function mikes_theme_request( $query_vars ) { | |
global $wp; | |
/** | |
* Trigger this test if the match URL rewrite rule is the one added by this plugin | |
*/ | |
if ( ! is_admin() && isset( $query_vars['post_type'] ) && 'episode' == $query_vars['post_type'] ) { | |
/** | |
* Lookup the client's post | |
*/ | |
$comic = get_page_by_path( $query_vars['comic_qv'], OBJECT, 'comic' ); | |
/** | |
* Lookup the client project's post, scoped to the client | |
*/ | |
$episode_query = new WP_Query( array( | |
'name' => $query_vars['episode_qv'], | |
'post_type' => 'episode', | |
'fields' => 'ids', | |
'post_parent' => $comic->ID, | |
'posts_per_page' => 1, | |
'suppress_filters' => true, | |
)); | |
/** | |
* If the client project was not found for the client, trigger 404 error. | |
*/ | |
if ( 0 == count( $episode_query->posts ) ) { | |
$query_vars = array( 'error' => '404' ); | |
} | |
} | |
return $query_vars; | |
} | |
add_action( 'add_meta_boxes', 'mikes_theme_add_meta_boxes' ); | |
function mikes_theme_add_meta_boxes( $post_type ) { | |
if ( 'comic' == $post_type ) | |
add_meta_box( 'comic_info_box', // $id | |
'Comic Information', // $title | |
'mikes_theme_comic_meta_box', // $callback | |
'comic', // $post_type | |
'normal', // $context | |
'high' // $priority | |
); | |
if ( 'episode' == $post_type ) | |
add_meta_box( 'episode_info_box', // $id | |
'Episode Info', // $title | |
'mikes_theme_episode_meta_box', // $callback | |
'episode', // $post_type | |
'side', // $context | |
'low' // $priority | |
); | |
} | |
function mikes_theme_episode_meta_box( $post ) { | |
$select_html = mikes_theme_comic_dropdown( $post->post_parent ); | |
$html =<<<HTML | |
<table> | |
<tr> | |
<th><label for="parent_id">Comic:</label></th> | |
<td>{$select_html}</td> | |
</tr> | |
</table> | |
HTML; | |
echo $html; | |
} | |
function mikes_theme_comic_meta_box( $post ) { | |
$cartoonist = get_post_meta( $post->ID, '_cartoonist', true ); | |
$since = get_post_meta( $post->ID, '_since', true ); | |
$website = get_post_meta( $post->ID, '_website', true ); | |
$html =<<<HTML | |
<table> | |
<tr> | |
<th><label for="cartoonist">Cartoonist:</label></th> | |
<td><input type="text" name="cartoonist" value="{$cartoonist}" size="25" /></td> | |
</tr> | |
<tr> | |
<th><label for="since">Since:</label></th> | |
<td><input type="text" name="since" value="{$since}" size="15" /></td> | |
</tr> | |
<tr> | |
<th><label for="website">Website:</label></th> | |
<td><input type="text" name="website" value="{$website}" size="25" /></td> | |
</tr> | |
</table> | |
HTML; | |
echo $html; | |
} | |
add_action( 'save_post', 'mikes_theme_save_post' ); | |
function mikes_theme_save_post( $post_id ) { | |
if ( 'comic' == $post_type ) { | |
update_post_meta( $post_id, '_cartoonist', $_POST['cartoonist'] ); | |
update_post_meta( $post_id, '_since', $_POST['since'] ); | |
update_post_meta( $post_id, '_website', $_POST['website'] ); | |
} | |
} | |
add_filter( 'manage_edit-comic_columns', 'mikes_theme_manage_edit_comic_columns' ); | |
function mikes_theme_manage_edit_comic_columns( $columns ) { | |
$new_columns = array(); | |
foreach( $columns as $key => $value ) { | |
if ( 'date' == $key ) { | |
$new_columns['cartoonist'] = 'Cartoonist'; | |
$new_columns['website'] = 'Website'; | |
} | |
$new_columns[$key] = $value; | |
} | |
return $new_columns; | |
} | |
add_filter( 'manage_edit-episode_columns', 'mikes_theme_manage_edit_episode_columns' ); | |
function mikes_theme_manage_edit_episode_columns( $columns ) { | |
$new_columns = array(); | |
foreach( $columns as $key => $value ) { | |
if ( 'date' == $key ) { | |
$new_columns['comic'] = 'Comic'; | |
} | |
$new_columns[$key] = $value; | |
} | |
return $new_columns; | |
} | |
add_filter( 'manage_comic_posts_custom_column', 'mikes_theme_manage_comic_posts_custom_column', 10, 2 ); | |
function mikes_theme_manage_comic_posts_custom_column( $column_name, $post_id ) { | |
switch ( $column_name ) { | |
case 'cartoonist': | |
echo get_post_meta( $post_id, "_cartoonist", true ); | |
break; | |
case 'website': | |
$website = get_post_meta( $post_id, "_website", true ); | |
$domain = trim( str_replace( 'http://', '', $website ), '/' ); | |
echo "<a href=\"{$website}\">{$domain}</a>"; | |
break; | |
} | |
} | |
add_filter( 'manage_episode_posts_custom_column', 'mikes_theme_manage_episode_posts_custom_column', 10, 2 ); | |
function mikes_theme_manage_episode_posts_custom_column( $column_name, $post_id ) { | |
switch ( $column_name ) { | |
case 'comic': | |
$post = get_post( $post_id ); | |
if ( !empty( $post->post_parent ) ) { | |
$title = get_the_title( $post->post_parent ); | |
$link = admin_url( "post.php?post={$post->post_parent}&action=edit" ); | |
$html = <<<HTML | |
<a href="{$link}">{$title}</a> | |
HTML; | |
echo $html; | |
} | |
break; | |
} | |
} | |
function mikes_theme_comic_dropdown( $selected_id, $name = 'parent_id' ) { | |
$query = new WP_Query( 'post_type=comic&posts_per_page=-1' ); | |
$comics = array(); | |
foreach( $query->posts as $comic ) { | |
$title = get_the_title( $comic->ID ); | |
$selected = $comic->ID == intval( $selected_id ) ? ' selected' : ''; | |
$comics[ $comic->ID ] = <<<HTML | |
<option value="{$comic->ID}"{$selected}>{$title}</option> | |
HTML; | |
} | |
$comics = implode( '', $comics ); | |
$html =<<<HTML | |
<select name="{$name}"> | |
<option value="0">None selected</option> | |
{$comics} | |
</select> | |
HTML; | |
return $html; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
thanks @mikeschinkel, this really helped me get a 3 level hierarchy to work with custom permalinks