Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Mastering WordPress Custom Post Types - WordCam...

Mastering WordPress Custom Post Types - WordCamp Atlanta 2012

Presentation of WordCamp Atlanta 2012 - Covers a collection of PHP-based techniques for using Custom Post Types to get the most out of WordPress.

Mike Schinkel

February 03, 2012
Tweet

Other Decks in Programming

Transcript

  1. /* Theme Name: Mike's Theme Description: Child Theme of Twenty

    Eleven Template: twentyeleven */ @import url("../twentyeleven/style.css");
  2. function mikes_theme_init() { register_post_type( 'comic', array( 'public' => true, 'label'

    => 'Comics', 'rewrite' => array( 'with_front' => false, ), )); } Better, but quite right:
  3. function mikes_theme_init() { register_post_type( 'comic', array( 'public' => true, 'label'

    => 'Comics', 'rewrite' => array( 'with_front' => false, 'slug' => 'comics', ), )); } Perfecto!
  4. 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', // $page, 'normal', // $context, 'high' ); // $priority }
  5. function mikes_theme_comic_meta_box( $post ) { $cartoonist = ''; $since= '';

    $website = ''; $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; }
  6. 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']); } } Note the leading underscores on the post meta 'key' names (2nd parameter)
  7. 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>
  8. <?php //Template for displaying single Comic Post Type. get_header(); if

    ( have_posts() ): the_post(); ?> <div id="content"> <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>> <h1 class="entry-title"><?php the_title(); ?></h1> Cartoonist: <?php echo get_post_meta( $post->ID, '_cartoonist', true); ?> <br/> Since: <?php echo get_post_meta( $post->ID, '_since', true ); ?> <br/> Website: <?php echo get_post_meta( $post->ID, '_website', true ); ?> <br/><br/> <?php the_content(); ?> </div> </div> <?php endif; get_footer(); ?>
  9. 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; } }
  10. 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; }
  11. function mikes_theme_init() { ... ... register_taxonomy( 'art-style', 'comic', array( 'hierarchical'

    => true, 'label' => 'Art Styles', 'rewrite' => array( 'slug' => 'art-styles', 'with_front' => false ), ));
  12. function mikes_theme_init() { ... ... register_post_type( 'episode', array( 'label' =>

    'Episodes', 'public' => true, 'rewrite' => array( 'slug' =>'episodes', 'with_front' => false ), 'supports' => array( 'title', 'thumbnail', 'excerpt' ), ));
  13. function mikes_theme_add_meta_boxes($post_type) { ... if ( 'episode' == $post_type )

    add_meta_box( 'episode_info_box', 'Episode Info', 'mikes_theme_episode_meta_box', 'episode','side','low' ); } function mikes_theme_episode_meta_box( $post ) { $html =<<<HTML <table><tr> <th><label for="parent_id">Comic:</label></th> <td><input type="text" name="parent_id" value="{$post->post_parent}" /></td> </tr></table> HTML; echo $html; }
  14. 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; }
  15. function mikes_theme_comic_dropdown( $selected_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="parent_id"> <option value="0">None selected</option> {$comics} </select> HTML; return $html; }
  16. 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; }
  17. add_action( 'request', 'mikes_theme_request' ); function mikes_theme_request( $query_vars ) { global

    $wp; if ( ! is_admin() && isset( $query_vars['post_type'] ) && 'episode' == $query_vars['post_type'] ) { $comic = get_page_by_path( $query_vars['comic_qv'], OBJECT, 'comic' ); $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 ( 0 == count( $episode_query->posts ) ) { $query_vars = array( 'error' => '404' ); } } return $query_vars; }
  18. <?php get_header(); if ( have_posts() ): the_post(); ?> <div id="content">

    <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>> <?php edit_post_link( 'Edit', '<div class="edit-link">', '</div>' ); ?> <?php previous_post_link( '%link', '&lt;&lt;&lt;Previous' ); ?> &nbsp;&nbsp;&nbsp; <?php next_post_link( '%link', 'Next&gt&gt&gt;' ); ?> <h2 class="entry-parent">Comic: <?php echo get_the_title( $post->post_parent ); ? ></h2> <h1 class="entry-title"><?php the_title(); ?></h1> <?php the_content(); ?> <?php if ( has_post_thumbnail( $post->ID ) ) $image_html = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'single-post-thumbnail' ); ?> <img src="<?php echo $image_html[0]; ?>"> </div> </div> <?php endif; get_footer(); ?>
  19. 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; }
  20. 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, $typenow, $wp_the_query; if ( 'edit.php' == $pagenow && 'episode' == $typenow && $query === $wp_the_query && ! empty( $_GET['comic_id'] ) ) { $query->set( 'post_parent', intval( $_GET['comic_id'] ) ); } }
  21. You can do practically anything you put your mind to

    with WordPress' CPTs and a little PHP!