Skip to content

Instantly share code, notes, and snippets.

@mikeschinkel
Created February 3, 2012 07:43
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mikeschinkel/1728805 to your computer and use it in GitHub Desktop.
Save mikeschinkel/1728805 to your computer and use it in GitHub Desktop.
Master WordPress Custom Post Types - WordCamp Atlanta 2012
<?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;
}
@pdewouters
Copy link

thanks @mikeschinkel, this really helped me get a 3 level hierarchy to work with custom permalinks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment