Try Tuts+ Premium, Get Cash Back!
Using Custom Post Types to Create a Killer Portfolio

Using Custom Post Types to Create a Killer Portfolio

Tutorial Details
  • Program: WordPress
  • Version (if applicable): 3.0+
  • Difficulty: Intermediate
  • Estimated Completion Time: 30-45 mins

Quite possibly the best addition to WordPress 3.0 was that of Custom Post Types. This took WordPress from being a CMS that can manage posts and pages to being able to manage anything the user can think of rather easily. You no longer have to add custom fields to posts- you can add high level support to your own types, creating their own theme page files and admin areas. One of the first things I did using custom post types was revamp my portfolio and today I’m going to show you how I did it!

We recently showed you a few neat tools for creating “Instant” Custom Post Types. Today is all about actually building a project using CPT’s from scratch… We’ll be doing everything from creating the custom type – to styling it for use in the theme. The CSS (and CSS3!) I use should be generic enough for most themes, but in case it isn’t, feel free to change it! This is intended to be used as a launchpoint for everyone, so feel free to get creative!


Getting Started A Few Thoughts

The first thing to note is that when creating a Custom Post Type, we have a couple of options as to how we want to approach them; The two main implementations you might consider are:

  1. As part of the current theme (usually through the functions.php file)
  2. As it’s own stand-along plugin.

There are pros and cons to each. In this tutorial, since we are integrating with our theme, we’ll make it part of the theme, calling everything we need through the functions.php file.

Developer’s Note: Because we’ll be building this directly into our theme, that doesn’t mean that this is the right way for you though… consider the end-use of your theme. If there’s a good chance that your users are going to be switching themes in the future, or you’re releasing your theme as a public or premium product for lots of people to use, you’ll probably want to build in your custom post type as a standalone file that people can take with them without too much digging through your code.

Just think of it this way, if your theme is the only thing that’s loading your Custom Post Types and you change themes, the Custom Post Type data won’t be usable; It’ll still exist on the database, but it won’t show up in new themes in any meaningful way. Sometimes this isn’t possible if you’re really overhauling a theme to use a CPT by including lots of customizations and templates, but at least consider what users might need to do to preserve the use of their data in the long run.

Let’s get started then!


What we’ll be creating

Step 1 Set-Up

As I stated above, we’ll be adding this to our current theme (I’m using my own custom theme), so the first thing we need to do is go to our theme and open up the functions.php file. We’re going to put our custom post type code in a different file (just so it’s easier to read/manage), so we’ll call that file at the top of our functions file:

require_once('portfolio-type.php'); 

Now we’re going to add two files to our theme: portfolio-type.php and portfolio.css. As you can probably guess, all of our CSS for the new type will go in the latter file.


Step 2 Registering the New Type

Thumbnail & Featured Image Support

Before we register the new type, we need to add support for an integral part of the portfolio presentation- featured images. After adding the opening and closing php tags to portfolio-type.php, add the following code:

if ( function_exists( 'add_theme_support' ) ) { 
	add_theme_support( 'post-thumbnails' );
	set_post_thumbnail_size( 280, 210, true ); // Normal post thumbnails
	add_image_size( 'screen-shot', 720, 540 ); // Full size screen
}

These lines, after checking to make sure your particular install supports post thumbnails, will add them to your current theme, then set a couple of default sizes. set_post_thumbnail_size() will, as the name suggests, set the default size for the thumbnail. The next line (add_image_size() will create another image that we can call named ‘screen-shot’, which will be 720×540. We will be using these images when displaying our portfolio.

Creating a New Post Type

Right here is where the magic happens- we will now tell WordPress about our new post type. Add the following code to portfolio-type.php:

add_action('init', 'portfolio_register');  
  
function portfolio_register() {  
    $args = array(  
        'label' => __('Portfolio'),  
        'singular_label' => __('Project'),  
        'public' => true,  
        'show_ui' => true,  
        'capability_type' => 'post',  
        'hierarchical' => false,  
        'rewrite' => true,  
        'supports' => array('title', 'editor', 'thumbnail')  
       );  
  
    register_post_type( 'portfolio' , $args );  
}  

The first line here is a hook in WordPress that will call our function, portfolio_register() on initialization. The function itself sets up an array of arguments to send with our custom post type. Most notably, we’re setting our admin labels, giving this type all of the capabilities of a standard WordPress post, allowing URL rewrites (for pretty permalinks), and adding support for the title, editor, and featured image fields. You can read more about all of the arguments for register_post_type() here.

After setting up the arguments array ($args), we pass that along with the type name to the function register_post_type().

Adding a Custom Taxonomy

The last thing we’ll do in this section is create a custom taxonomy for our new type. Add the following line of code to your portfolio-type.php file:

register_taxonomy("project-type", array("portfolio"), array("hierarchical" => true, "label" => "Project Types", "singular_label" => "Project Type", "rewrite" => true));

This will create the new taxonomy ‘project-type’ and apply it to the post type ‘portfolio’. You can read more about register_taxonomy() here.


Step 3 Adding Custom Fields

Creating the Custom Field Box

We wouldn’t have much of a custom type without having some extra info to add to the post. We’ll add that info in the form of custom fields. Specifically, we’ll be adding one extra field for a link to more info about the project, or to the project itself. Add the following code to your portfolio-type.php file:

add_action("admin_init", "portfolio_meta_box");
function portfolio_meta_box(){  
    add_meta_box("projInfo-meta", "Project Options", "portfolio_meta_options", "portfolio", "side", "low");  
}  
  

function portfolio_meta_options(){  
        global $post;  
        if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return $post_id;
        $custom = get_post_custom($post->ID);  
        $link = $custom["projLink"][0];  
?>  
    <label>Link:</label><input name="projLink" value="<?php echo $link; ?>" />  
<?php  
    }  

This code will create the “Project Options” box we see here.

First we use the WordPress hook admin_init to call our function portfolio_meta_box() when the WordPress admin is created. Our function will add another box to our portfolio type, which can be populated with anything. What the box is populated with is covered by the 3rd argument, which is a callback function. In this case, our function is named portfolio_meta_options().

In portfolio_meta_options() we’ll create a form field that will be used to capture the project’s link. The first thing we do is grab the global $post array so we can get the custom fields for whatever post we’re editing. In our next line, we’re checking to make sure WordPress isn’t currently saving the post or custom fields; if it is, we may see inaccurate results when we do grab the custom data.

If WordPress is not doing a save, we grab the custom fields for the current post and create a form field using that info. $custom (what’s returned from get_post_custom() is a 2D array where the key is whatever we name the form field for our custom in. Take a look at our text box for the link. You’ll notice that the name matches the index we call in our $custom array. You’ll also notice that we don’t have a separate form or submit button. This field is added to the form used to edit the entire post.

While we only create one here, you can obviously create as many as you’d like.

Saving the Custom Data

Now that we’ve created our custom meta box, it’s time to create a function that will save the information. Add the following lines of code to your portfolio-type.php file:

add_action('save_post', 'save_project_link'); 
  
function save_project_link(){  
    global $post;  
    
    if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ){ 
		return $post_id;
	}else{
    	update_post_meta($post->ID, "projLink", $_POST["projLink"]); 
    } 
}  

First, as usual, we have our hook- this time to call our function when the post is saved. In the function itself, we again grab the $post array so we can get the post ID and check to see if the post is autosaving. If we don’t include this line, we will lose our data, so it’s important we keep that in.

If the post is not updating, we save our custom fields using update_post_meta(), sending the post id, the name of the custom field, and the new value.


Here’s what the whole kit and caboodle looks like!

Step 4 Customizing Admin Columns

Here we’re going to customize the list displaying all of our projects. Add the following code to your portfolio-type.php file:

add_filter("manage_edit-portfolio_columns", "project_edit_columns");   
  
function project_edit_columns($columns){  
        $columns = array(  
            "cb" => "<input type=\"checkbox\" />",  
            "title" => "Project",  
            "description" => "Description",  
            "link" => "Link",  
            "type" => "Type of Project",  
        );  
  
        return $columns;  
}  

add_action("manage_posts_custom_column",  "project_custom_columns"); 
  
function project_custom_columns($column){  
        global $post;  
        switch ($column)  
        {  
            case "description":  
                the_excerpt();  
                break;  
            case "link":  
                $custom = get_post_custom();  
                echo $custom["projLink"][0];  
                break;  
            case "type":  
                echo get_the_term_list($post->ID, 'project-type', '', ', ','');  
                break;  
        }  
}  


Here’s our newly modified Project list.

After our hook for the first function (project_edit_columns()), we do something pretty interesting in terms of editing the columns. WordPress places the columns for a post type’s display list into an array with a key and a value. We create those key-value pairs in this function. In the next function (project_custom_columns()), we use a switch statement to grab the key and then display the information we want based on it. As you can see, just like in the previous section, we get the global $post array so we can get the post’s ID to properly display any custom information, like our link and taxonomy.

You’ve probably noticed that the number of cases does not match the number of columns in our $columns array. That’s because for certain keys, like cb and title, WordPress has default values that we don’t want to overwrite.


Step 5 Adding Some Display Functions

Before we get to creating a template page, I want to give you some functions I included to get displaying the projects just right. Open up your functions.php file and add the following three components:

add_filter('excerpt_length', 'my_excerpt_length');

function my_excerpt_length($length) {

	return 25; 

}

add_filter('excerpt_more', 'new_excerpt_more');  

function new_excerpt_more($text){  

	return ' ';  

}  

function portfolio_thumbnail_url($pid){
	$image_id = get_post_thumbnail_id($pid);  
	$image_url = wp_get_attachment_image_src($image_id,'screen-shot');  
	return  $image_url[0];  
}

The first two hook/function pairs are common to WordPress- they simply change the length of the excerpt and the “more text” indicator, which I’ve replaced with just a space. Please note that this will happen to all posts, not just the portfolio post, and that if you’re using a child theme, this may not work.

The custom function, portfolio_thumbnail_url() takes in a post’s ID as the argument and grabs the screen-shot version of the image we uploaded. We’ll be calling it in our template page, so keep an eye out for it!


Step 6 Create a Template Page

Now that we have our custom post type all set up in the admin, it’s time to create a theme page so we can display them. To accomplish this, we’re going to create a template with the name, “Portfolio” and then assign the template to a page in WordPress. While we can also create archives-portfolio.php to accomplish the same thing, we won’t be able to add that page to a menu from the WordPress admin, so this route is best. Keeping with WordPress naming conventions, create a new file called page-portfolio.php and add the following code:

<?php
/* Template Name: Portfolio */
get_header(); 

query_posts('post_type=portfolio&posts_per_page=9');
?>

This will create the ‘Portfolio’ template.

These few lines establish the most important parts of the page. The first line lets WordPress know that this is a page template that should go by the name “Portfolio.” Then, after calling the theme’s header, we set up the query to grab the last 9 posts of type portfolio. The next thing to do is display them. Add this code to your page-portfolio.php file:

<div id="portfolio" class="group"> 

<h2>Portfolio of Work</h2>

<div class="group">

<?php if (have_posts()) : while (have_posts()) : the_post(); ?>

	<?php
		$title= str_ireplace('"', '', trim(get_the_title()));
		$desc= str_ireplace('"', '', trim(get_the_content()));
	?>	

	<div class="item">
				<div class="img"><a title="<?=$title?>: <?=$desc?>" rel="lightbox[work]" href="<?php print  portfolio_thumbnail_url($post->ID) ?>"><?php the_post_thumbnail(); ?></a></div>
				<p><strong><?=$title?>:</strong> <?php print get_the_excerpt(); ?> <a title="<?=$title?>: <?=$desc?>" rel="lightbox[work]" href="<?php print  portfolio_thumbnail_url($post->ID) ?>">(more)</a></p>
				<?php $site= get_post_custom_values('projLink'); 
					if($site[0] != ""){
				
				?>
					<p><a href="<?=$site[0]?>">Visit the Site</a></p>
					
				<?php }else{ ?>
					<p><em>Live Link Unavailable</em></p>
				<?php } ?>
			</div>

		
<?php endwhile; endif; ?>

</div>

</div>

<?php get_footer(); ?>

You’ll notice a few things here: first, after we’re in the loop, we need to trim extraneous ‘”‘ characters from our title and content using str_ireplace(). I’m not exactly sure why they appear here, but from what I can tell this is a necessary step. You should also notice that we’re using lightbox. While we could add it ourselves (which I’d probably recommend if this were a plugin), since we are modifying our own theme, we could download one of the many lightbox plugins available in the WordPress repository. Just pick your favorite!

Aside from that, this should look familiar to anyway who’s worked with the WordPress loop. What we’re doing here is creating blocks with our thumbnails and descriptions, which link to (using lightbox) the screen shot for each of the 9 projects. I didn’t include links to other pages (in case you have more than 9 projects) because I only want my users to see latest 9 projects. You can allow users to get to other posts using posts_nav_link(), if you so choose.

I should also note that I removed WordPress’s default more link because it linked to a single post page, and I wanted to use lightbox, so I constructed my own.


Step 7 Styling our Portfolio Type

Here’s the fun part: making our portfolio type look pretty. Here’s some CSS that I’ve included- you can add it to the bottom of your style.css sheet, or into our newly created portfolio.css file. Just be sure to use @import to call portfolio.css at the top your theme’s style.css (it will not work anywhere else):

.item{
float: left; 
margin: 5px;
width: 310px;
background: #EFEFEF;
-moz-border-radius: 7px; 
-webkit-border-radius: 7px; 
border-radius: 7px; 
text-align: center;
-moz-box-shadow: 0px 0px 6px #999; 
-webkit-box-shadow: 0px 0px 6px #999; 
box-shadow: 0px 0px 6px #999; 
}

.item p{ text-align: left; }
.item p a{ text-align: left; font-weight: bold; }
.item img{ margin-top: 5px; text-align: center; border: 1px solid #000000; max-width: 280px;}

/* self-clear floats */

.group:after {
	content: "."; 
    display: block; 
    height: 0; 
    clear: both; 
    visibility: hidden;
}

If you’ll reference our template page, you’ll see that each project is wrapped in a div called “item,” which we now apply CSS to. Since no two themes are the same, you may have to tweak your own CSS a bit, but here is a nice starting point for you. I’ve also included a class for self-clearing floats. This is a technique I got from Dan Cederholm, and I think it’s a bit more elegant that the standard “clearfix” method of clearing content after floating divs.


Conclusion

That’s it! You now have a simple portfolio using custom post types. While this was built to serve my needs, and I wanted to keep things simple, the possibilities for this are endless as you can tailor it to fit whatever kind of portfolio you have (writing/articles, photography, graphic design, etc.). If you don’t want to use lightbox to display the single project, you can also create a theme page with the name single-portfolio.php, which will then apply the code within to each individual project, much like single.php does for blog posts.

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://deepakrajpal.com Deepak Rajpal

    custom post type is magic

  • http://gashone.com gashone

    exactly what I need.. thanks for the nice tutorial..

  • Andrew

    Hi. Is there any chance, please, of a tutorial n adding an image uploader custom metabox?

    Thanks.

  • http://tutspress.com TutsPress

    Nice a tuts again. Thanks for the tutorial,

  • http://thisismyurl.com Christopher Ross

    Joseph, fantastic tutorial! Thanks, I love Custom Post Types. This is a great tutorial and the files will make my life a lot easier!

  • http://www.derby-webdesign.co.uk Kevin

    Brilliant tutorial, I’ll definitely be using it for my new design =) Thanks

  • http://www.casabona.org Joe Casabona
    Author

    Thanks guys! Glad you like it!

    • http://8gramgorilla.com/ 8 Gram Gorilla

      Great stuff, Joe – very useful! :)

  • Jeff

    Great tutorial! What’s the easiest way to display the portfolio in columns?

    • http://www.casabona.org Joe Casabona
      Author

      Hmm well the easiest way would be tables, but that’s not recommended :)

      I’d say divs with a set width that float left would your best bet.

      • http://samuelmburu.com/ Samuel Mburu

        Very nice comment about the floats with widths — I read your styles utilizing the :after psuedo class and was thinking this doesn’t work in IE6-7.

        There is this great article for those who don’t know on a list apart that explains floats in great detail:
        http://www.alistapart.com/articles/css-floats-101/

        Thanks for the tutorial on the custom posts… keep the good stuff coming

  • http://www.wpyag.com Ravi

    Great Tutorial…
    Thank you Joseph :)

  • Matt

    custom post types are very useful, but they would be even better if it wasn’t for one thing: one can’t set a parent page for newly created CPT! (Like you can set it for regular posts in Settings->Reading and every time a post is displayed that selected page will be highlighted in the navigation menu with for example current_page_parent class).

    So if for instance I set up CPT for my portfolio projects, but I also want to have a blog on my website- so I set up 2 pages in the navigation menu: blog and portfolio. How to make the 1st highlight only for blog posts/categories and the 2nd only for portfolio projects/categories? Is there any way of doing that?

    • Reading Rocks

      Matt,

      Step 6 and 7…reading instructions step by step helps.

      Sincerely,
      Educated

      • Lance Monotone

        There’s no cause to be mean.

  • http://www.rssbeta.com/ sam

    Nice tutorial, thanks

  • http://kopepasah.com Kopepasah

    I completely disagree with number 6. Although the API should be better, having to create a page each time a custom post type is registered is not a good practice. Espically for developers.

    A better solution is to flush the rewrites (fixes archive-[post-type].php) and hooking the post type archive into the Menu area. This will help in the future when WordPress improves the Custom Post Type API.

    • http://www.casabona.org Joe Casabona
      Author

      I agree the API should be better and it gets a little tough when you’re trying to do a general plugin, but aside from a full list of customizable short codes, you’ll need to create a custom template page in order to integrate properly with whatever theme the user is using, especially if they are using their own custom one, as they’ll have custom CSS and markup.

  • fringer

    Great tutorial. However, I do have some problems – the styling is not applied. I’ve done everything as instructed, but the styling doesn’t apply – no matter if I use it in style.css or if I call for portfolio.css. Also, the thumbnails are 55*55, instead of the values that were supposed to be. And “more” links to the full size image not to the post.

    Can anyone throw a hint? I’ve used all the source files and only added the functions bits to my file.

  • Slavisa Petrovic

    Instead of this:

    $custom = get_post_custom();
    echo $custom["projLink"][0];

    you can use better:

    echo get_post_meta($post->ID, ‘projLink’, true);

    • Luis

      hi,

      if i use echo get_post_meta($post->ID, ‘projLink’, true); in the portfolio type when i tell the loop to get the link its like ID, ‘projLink’, true); ?>

      right?

  • http://scotttolinski.com Scott

    I’m getting a
    Fatal error: Call to undefined function portfolio_thumbnail_url()
    while using this on WordPress 3.2.1.
    Any Ideas?
    When I remove that line of code in anchor, it’s working just fine.

    • http://scotttolinski.com Scott

      Never mind. Maybe I should have read Step 5 a little better!

    • Slavisa Petrovic

      You need to check the function definition in portfolio-type.php.

      function portfolio_thumbnail_url($pid){

      //Retrieve Post Thumbnail ID.
      $image_id = get_post_thumbnail_id($pid);
      //Returns an array with the image attributes “url”, “width” and “height”, of an image attachment file.
      $image_url = wp_get_attachment_image_src($image_id, ‘screen-shot’, $icon=false);
      return $image_url[0];

      }

  • Pingback: Custom Post Type | Kiubmen Portfolio | Kiubmen Portfolio

  • Pingback: Custom Post Types | Yuguo Blog

  • http://www.cineindya.com Kumar

    Hello My Name is Kumar, Well I really thanx for this tutorial, But Can you help me for this:

    i have created a Custom Post type Movie, and Also created a page Movies and Showed all the movies on that page. Great….

    “But the Problem is”, When I click on that movie, Its’ going on the same single.php page, and that’s what I don’t want, I want a Saprate Single.php file for this movie section and seprate others like news, videos, so tell what i’ll do for this

    Thanx
    Kumar

  • Pingback: Publikační systémy – WordPress 3.2 | Phire Base - Graphic, Webdesign, Inspiration. Adobe & WP

  • http://colorfultones.com Damon

    If one sets define(‘WP_DEBUG’, true); in their wp-config.php then one sees there are errors in this code. Not sure how to fix though :(

    • http://colorfultones.com Damon

      Should have been more specific… the error in code appears to be approximately line 69: “Trying to get property of non-object in portfolio-type.php on line 69″ AND “Undefined index: projLink in portfolio-type.php on line 69″

      • dcolumbus

        Damon, did you ever find out what was causing these error? I’m getting them too and I’m not quite understand how it’s happening.

      • http://www.lucasdelrio.com.ar Lucas del Río

        I’m also getting that error and can’t fix it. My post thumbnails and the “see more” link don’t work well.

      • http://www.webdesignlift.com Windo

        Hi Damon,

        I’ve been encountered that error too, however found the solution by adding quote for $_POST["projLink"] .

        /* SAVING THE CUSTOM POST DATA */
        add_action (‘save_post’, ‘save_project_link’);

        function save_project_link() {
        global $post;

        if( defined(‘DOING_AUTOSAVE’) && DOING_AUTOSAVE ){
        return $post_id;
        } else {
        update_post_meta( $post->ID, “projLink”, ‘$_POST["projLink"]‘ );
        }
        }

  • http://www.designerlab.dk Dennis Johansen

    Thank you a great tutorial!!

    I was though wondering why the project type “categories / tags” aren’t used and echo’ed out? Or am I just missing something?

  • Pingback: A Free wordpress newsletter » WordPress Custom Post Types Tutorials, Tools & Advice

  • Pingback: WordPress Custom Post Types Tutorials, Tools & Advice | Customize WordPress Blog

  • Pingback: Create a Responsive Slider Plugin With FlexSlider | Wptuts+

  • Pingback: wp-coder.net » WordPress Custom Post Types Tutorials, Tools & Advice

  • http://www.joshbosworth.com bosworth99

    Damn. Wish this tut had come out just a couple months earlier. I had to hack together a number of other unrelated tutorials (and codex refs, of course) to accomplish almost exactly the same project back in july. Only real difference was that my plugin was class based and my front end is delivered via ajax. I was still unclear how to modify the admin edit list to add my new attributes, and you’ve detailed how to do that. So thanks! Wp-tuts+ win!

  • http://www.lucasdelrio.com.ar Lucas del Río

    I’ve give a try to it but it didn’t work.
    I’m creating my first WordPress theme from scratch, and I had my files displaying posts as the “regular” posts from a blog.
    After that I followed this tutorial step by step adding everything, even a Portfolio button in the admin panel under Posts button.
    But when I create a new Portfolio post it doesn’t appear anywhere. I really don’t understand why or how to solve this.
    Posts can be used as regular posts and as portfolio posts at the same time in the same theme?
    What should I do to get this working correctly?

    Thanks for the help in advance, and for this great tutorial.

    • http://www.lucasdelrio.com.ar Lucas del Río

      OMG! I could solve it, the problem was I never created a Page with a page attribute of template as “Portfolio” using the page-portfolio.php file.
      I can’t believe it! now I have posts for bloggin and posts for portfolio!!
      Thanks so much for this tutorial once more, so useful!

  • http://www.indezoo.com/ Idris

    this is rocking tutorial..exactly what i was searching for…thank you for sharing!!!

  • http://SIX15.com Jeff Mackey

    Great tutorial.

    These steps are almost exactly what I use for my CPT implementations for client work.

    One thing to note about associated template files for your Custom Post Type–WordPress follows a naming convention making life much easier when setting up templates to display CPT results and corresponding detail (single) pages.

    For instance, if my CPT is “project”, I set up a template file named “page-projects.php” (note the plural). No need to use the “Template Name: …” syntax. Although that method works just fine.

    Then for the detail page, duplicate your single.php template file and name it “single-project.php”. WordPress will then know it’s associated with that CPT and not try to use the default single.php template.

    Cheers!

  • http://jonnyholroyd.freehostingcloud.com Jonathan Holroyd

    Perfect! I’ve been trying to get a details page for my portfolio for ages, thanks a ton!

  • eyever

    How would you hide a project type from showing up with everything else?

  • suascat

    Greatest ! of them all.

  • Zygfryd

    Hi
    How can I retrieve ‘Type of’ value on template page?

    Regards!

  • Pingback: Как в WordPress создать свой слайдер с изображениями | Wordpresso

  • EDELLELI Nizar

    Wooow; u’v done great job; clear nd useful thx

  • http://www.designerlab.dk Dennis Johansen

    Hi

    Thanks for another great toturial…very useful!!

    Is there a way to add pagination to this?

    Best regards!

  • http://hexagoncircle.com Ryan

    This was an amazing tutorial, thank you! However, I’m having a permalink problem. When I try to switch from the default permalink structure (to month/post-title) and go to my portfolio page on hexagoncircle.com, the portfolio will not load. Anybody know why?

    • http://hexagoncircle.com Ryan

      After trying some of my own custom permalink structures, I found one that made the thumbnails load and this now works just fine. I used page-id/postname. How about that?

  • Cmez

    Hi there,

    I have used this method for a portfolio page, but the pagination is not working with WP-PageNavi plugin. Can somebody help me out with this problem? Thanks in advance.

  • Robert

    Great tutorial! Thank you for this. I have some issues when adding additional custom inputs to Project Options, I’m not able to figure out how to save the data for the additional inputs. Any advice would be greatly appreciated.

    I’ve added this:

    function portfolio_meta_options(){
    global $post;
    if ( defined(‘DOING_AUTOSAVE’) && DOING_AUTOSAVE ) return $post_id;
    $custom = get_post_custom($post->ID);
    $link = $custom["projLink"][0];
    $des = $custom["projDes"][0];
    ?>
    Link:<input name="projLink" value="” />
    About:<textarea name="projDes" value="” />

    But don’t know how to include “projDes” properly in add_action save post:

    add_action(‘save_post’, ‘save_project_link’);

    function save_project_link(){
    global $post;

    if ( defined(‘DOING_AUTOSAVE’) && DOING_AUTOSAVE ){
    return $post_id;
    }else{
    update_post_meta($post->ID, “projLink”, $_POST["projLink"]);
    }
    }

  • http://www.webprimacy.com jeremy

    Great arcticle. I am just getting started with the CPTS. How would you set up a page template that shows custom post types within a specific category or display all custom post types but organized by category with category headers between each?

    Thanks!

  • Tiikaay

    Awesome tutorial, thank you Joseph! It works like a charm!
    Gave me an idea though, and I can’t really figure out the how-to.
    So Let’s say, I create a category with a name portfolio. I assign child categories (like webdesign, webdevelopment etc..) And I would like all these posts, with these child categories to have a template of their own.
    It’s kinda like the page template, – where you are able to choose a template when creating the page – only it’s a category template…. I guess…..
    Now, I’m aware, that creating category.php would give me this, but then all my categories would look the same.
    I also know, that I can make template a specific category, like category-6.php for the category id=6, and so on….
    But I would like to be able to choose a category template file when creating the category…
    Is it possible?
    PS: English is not my native language, as you probably figured, so I’m sorry for mistakes

  • Harold

    Great tutorial!

    But got 1 question; Can I link an image to the featured image? So if I click the featured image I get an larger (other) image than I set in the featured image?

    Thanks in forward.

  • http://www.pixelgeek.me PixelGeek

    Thanks for sharing another great tutorial. Easy to understand and implement. Already used it for my online portfolio. ;-)

  • http://www.streamingwords.com.ar Gonzalo

    Hi. Fancy Box Doesn’t Work with this. :(

  • http://glenn@gfwebsoft.com FeralReason

    Awesome post !

    Was only confused by one line in Step 4:

    “You’ve probably noticed that the number of cases does not match the number of columns …”

    Actually each of the 3 cases does match a column. There did not seem to be any extra cases.
    Can you explain what you meant by this comment ?

    (Sorry I’m so late discovering / commenting on this post — great job !)

  • http://www.gfwebsoft.com FeralReason

    One more thing – the Codex says:

    “If you must use query_posts(), make sure you call wp_reset_query() after you’re done.”

    Shouldn’t we be doing that ? Thx !

  • Pingback: jQuery Image caption hover | Webdale - Digital designer and Mercenary for hire

  • Jordan

    Great post! I had an issue where it would save blank values for all page types. Editing the save_post function fixed it for me:

    if (isset($_POST["project_name"])) {
    update_post_meta($post->ID, “project_name”, $_POST["project_name"]);
    }

  • Ciaran

    Hey this is a great tutorial, thank you. What’s the best way to add pagination to this though?

  • Przemek

    The article could be great but lack of pagination possibility makes this approach unusable.
    Or it is possible?

  • Frank

    Hey that sounds like a high quality tut for that topic! Will try it asap. Since I’m not that familiar with PHP sp far, may I ask what’s the reason for mixed usage of ” and ‘ ? Does this depend on something in this Code?

  • asraf

    hi
    how can i add page attribute meta box in this custom post type?
    THE TUTORIAL YOU PROVIDED DOES NOT CREATE ANY METABOX LIKE PAGE ATTRIBUTE….

    thanks
    angon

  • http://www.eluxuryshopjp.com/ john

    Using Custom Post Types to Create a Killer Portfolio seem well, Also Will try it asap. Since I’m not that familiar with PHP sp far, may I ask what’s the reason for mixed usage of ” and ‘ ? Does this depend on something in this Code?

  • fabio

    as always, love your work!!!

  • xntwx

    great one, thanks Jo :)

  • http://www.DesignLoud.com Derek

    Excellent Work Joe!!

    I have a question, I have followed your steps and when I check it out from the front end I am not getting the title to show up, it is just ” : then description ” also the the “Visit Site Link” is not working for me it takes me to http://localhost/testsite/%3C?=$site0?%3E..

    Grant it I am running locally on WAMP and I just upgraded to WordPress 3.4.2, is there anything that sticks out that you can see to where I may have went wrong?

    Thanks again for the understanding of CPT

  • Pingback: Tweet-Parade (No.35 Aug-Sep 2011) | gonzoblog.nl

  • Jeremy

    So I copied the code for the custom post type and the custom template and I am not getting the results stted in the tutorial. What puzzles me is that page-attributes is not set as a supported feature for the type but yet it shows it being used… Not to mention, this is set as a post type not a page.

    I am trying to get custom template pages to work but this seems to be not possible (I want a drop down like pages has) I have been using the sinlge-post_type.php method but there are sub-pages I need to be able to control as well.

    Is this possible? Doesn’t look that way thus far. Also, how are you showing a custom template when the supports is not set to show page-attributes?

    • http://www.gomo.pt Luis Godinho

      Hi Jeremy,

      I am dealing with the same issue of “not having the template selector in the page-attributes metabox”. It seems the current wordpress version doesn’t support it. But I found a workaround here: http://wpquestions.com/question/show/id/2775.

    • http://www.facebook.com/mia.kliuieva Mia Kliuieva

      The template file is being assigned to a page, not a custom post type that is being created, which is why there is a “page attributes” option available. Basically, you create a page named “Portfolio” trough admin and then assign to it a template file which pulls all posts that have “portfolio” as their post type.

  • Ciaran

    Hi there,
    This is a really great tutorial and it has taught me a lot about how custom post types work. I’ve used this set up for a few sites of mine in fact…
    I’ve recently come across an issue though. I upgraded from PHP 5.2.13 to PHP 5.3.16 and now the custom field box is not working. In your above tutorial where normally the Project Link would be outputted on the front end it is now just outputting Visit the Site
    Can you please advise on how to fix?
    Thanks

  • http://www.robertbrodziak.com/ Robert | RBdsgn

    Brilliant! I honestly thought, that building portfolio section with admin panel modifications would be huge project with a lot of coding. But with Your explanations it is really nice and pretty easy to understand. I wish You could explain that second type of portfolio – where thumbnail links to single-portfolio.php instead of lightbox. Anyone got some tips on making that? Thanks

  • http://twitter.com/richeleanderson Richelle Anderson

    Just got through adding this to my custom theme… Thank you so much. For those looking for navigation you can use wp nav similar to what is used for posts…

    include (TEMPLATEPATH . ‘/inc/nav.php’ );