August 30th, 2006

How to Use WordPress for a Portfolio Site – Part 2

Part of the Using WordPress as CMS SeriesIn Part 1, we looked at how to setup a simple (mainly graphic-type) portfolio site using nothing other than WordPress (WP). Modifying the WordPress loop to display thumbnails of your projects, individual project pages that displayed a larger image, and categorical listings that also displayed project thumbnails – all in an organised manner – were the key concepts offered then.

Today, we’ll look at slightly more specific (though still pretty simple) needs which not every WP-powered portfolio site may need:

One thing to note before we proceed: Read Part 1 first if you want to completely understand some of the references in this part. Also remember that we’ll be using WordPress’ default theme for standardisation purposes, so you might have to adapt these steps for your own themes.

Most Recent Project(s)

If you followed Part 1, your index page would be a thumbnail listing of your projects, with no particular emphasis placed on your most recent project. What if you wanted to distinguish your most recent project from the rest – just like how I distinguish my first two posts (fully listed) on blogHelper with the remaining ones (only titles) on the front page?

Here’s one way to do it:

  • Method Overview: We’ll give each post displayed on the front page numerical order (i.e. 1 for first post, 2 for second post, etc.) by declaring a variable and advancing its value by 1 at the end of each iteration of the Loop. Then, we use conditional statements to execute Layout A (special layout for your most recent post) for post No. 1, and Layout B (the original thumbnail listing layout) for the rest. Steps are also taken to ensure that this emphasis on your most recent post is only displayed on your very first page and not on Page 2, Page 3, etc. since that would be rather illogical (optional though).

Step-by-step instructions:

  1. Edit your Main Index Template via Presentation >> Theme Editor.
  2. Above your <?php if (have_posts()) : ?> statement, insert this: <?php $postnum = 1; ?>. This declares the variable postnum and gives it an initial value of 1.
  3. Right after the <?php while (have_posts()) : the_post(); ?> statement, insert this:

     <?php if ($postnum == 1)
        { ?>
           Insert your layout for your Most Recent Project here!
           For example:
                   
    <div id="mostrecentproj">
                    <div class="post" id="post-<?php the_ID(); ?>">
                    <h2><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to     <?php the_title(); ?>"><?php the_title(); ?></a></h2>
                   
                    <a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title(); ?>">
                    <?php echo '<img class="thumb" src="'.get_post_meta($post->ID, 'big_image', TRUE).'" />';
    ?>
                    </a>           
                    </div>   
                    </div>
    <?php } ?>

    The layout above will execute only when $postnum is 1, i.e. for the first post. And the only things different between the layout example I gave above and the original thumbnail layout is the mostrecentproj div wrapping the original code (which we’ll use later if we need to style the elements), and the call for big_image rather than thumbnail (so that your big image rather than your thumbnail is shown for your most recent project).

  4. And right below what you just added, insert this: <?php else { ?>
  5. And right before <?php endwhile; ?>, insert this:

    <?php  }
     $postnum++; ?>

    Everything placed within the code inserted by this and the previous instruction (i.e. your original layout) will then execute for everything else other than the first/most recent post. The $postnum++ statement increments the $postnum counter so that the next post will no longer have $postnum = 1, and thus, your special layout won’t execute for it.

  6. Optional: If you only want this emphasis on your most recent project to be shown on your first page, then you’ll have to modify one line of the code you’ve inserted so far. In Instruction No. 3, replace if ($postnum == 1) with if ( ($postnum == 1) AND (!is_paged()) ). Read more on the is_paged() conditional tag at the WP Codex.

Yep, that’s it. The only reason it looks daunting is because I’ve written so verbosely for the benefit of less experienced WP users. It really takes less than a couple of minutes to do everything on the list. Check out the demo site I’ve setup to see how this works.

Featured project(s)

Now, instead of differentiating your latest project, you might want to feature/emphasise selected projects instead. Let’s assume you want to show one featured project on your sidebar (you can put as many as you want later).

Here’s one way to do it:

  • Optional Introductory Reading: We’ll be modifying the WP Loop via query_posts() later, so you just might want to read up on it before or after reading this post.
  • Method Overview: By using categories, we mark selected posts to be “featured”. Then, we place a WP Loop, customised to show only posts/projects marked with the “featured” category via query_posts(), wherever we want to show the featured projects. Alternatively, we can mark “featured” posts using a custom field. However, as I’m currently exploring the development of a plugin to simplify this custom field method, I’ll not be providing step-by-step instructions for it just yet.

Step-by-step instructions:

  1. Under the Manage >> Categories tab, create a new category. Name it something like Featured.
  2. And on posts that you’d like to feature, assign them to this Featured category.
  3. Now for the behind the scenes stuff. First up, assuming you want to put your Featured section on your sidebar, edit your Sidebar template file via the Presentation >> Theme Editor tab.
  4. Wherever you want to place your Featured Projects, insert this code:

    <li><h2>Featured</h2>
        <?php query_posts('cat=3&posts_per_page=1'); ?>
        <?php if (have_posts()) : while (have_posts()) : the_post(); ?>
            <div style="padding: 7px 0 0 7px;">
            <a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title(); ?>">
            <?php echo '<img class="thumb" src="'.get_post_meta($post->ID, 'thumbnail', TRUE).'" />';
    ?>
            </a>
            </div>
        <?php endwhile; endif; ?>
    </li>

    The cat=3 passed to query_posts() tells our custom WP Loop to show only posts in the category with ID=3 (in my case, that’s my Featured category’s ID), while the posts_per_page=1 tells it to show only 1 post per page. Increase this value if you want to show more than one.

That’s pretty much it if you go with the categories method. I think you would have noticed that this method assumes that each addition to your Featured Projects will be more recent than the previous one, since the Loop will show projects in your Featured category in reverse chronological order. If instead you want to mark older posts as featured, all you have to do is do one little tweak: Pass p=XXX (where XXX is the particular post’s ID) instead of cat=3 to query_posts(). Instead of our featured Loop now showing projects in the featured category, this tells it to zoom into one particular post. Admittedly, this is a little messier than before.

Note: You might want to exclude your Featured category from your category listings. You will want to use the exclude parameter in the wp_list_pages() template tag for that.

Project “Tagging”

There will often be situations where being able to tag your projects in a flashier manner than merely a hyperlink to your project category is desirable. If you’re a web designer, you might want to point out that you did coding, designing and testing on a particular project, but just information architecture on another – but using images instead.

You could probably do it yourself, and I’m sure many of you already know how. So, forgive me for explaining the (simple) process for the sake of completeness anyway.

  • Method Overview: We use standard tagging approaches, such as categories and custom fields, to tag our projects. Then, using conditionals, we tell WordPress to show a certain image for each tag our project is assigned to.
  1. Choose between at least 3 tagging approaches. Either assign conventional WP categories to your projects (i.e. posts), assign tags using the Ultimate Tag Warrior plugin, or use custom fields for each project.
  2. Like previously, I’ll assume the use of categories. So, ynder the Manage >> Categories tab, create a new category. Perhaps name it something like Tags.
  3. Create subcategories of the Tags parent category for each tag you want to assign to your projects, e.g. Coding, Design, Architecture, etc.
  4. Assuming you want to display your graphical tags only on your individual post pages, edit your Single Post template via Presentation >> Theme Editor.
  5. Where you want to place your graphical tags, insert this for each tag you might place in your posts.

    <?php if (in_category(XX))    {
           <img src="path/to/your/image" alt="tagname" />
        }
       

    Just replace XX with your category IDs, and insert the path to the image you want to show for each tag.

That’s it. If you want to use custom fields instead, then replace in_category(XX) with get_post_meta($post->ID, 'tagnamehere', TRUE), and create a custom field for each tag you want to show, and set its value to 1 in posts where you want it to show up.

Optional: Portfolio-Blog Integration

This, like project tagging, is here only for the sake of completeness. I said this for project tagging because it was a process too simple for most WordPress tweakers out there, but for portfolio-blog integration, it’s because most people (okay, maybe just me) will prefer using separate subdomains for their blog and portfolio.

  • Optional Introductory Reading: We’ll be playing around a bit with your permalink structure. Nothing special, but you might want to read an introductory article I wrote on this just in case.
  • Method Overview: Integration is a big word since all we’ll be doing is to put some creativity into our permalink structure and category structure, plus some more query_posts() usage. We’ll be creating two categories with the lowest IDs (important!), i.e. blog and portfolio, and assigning one of those categories to every post. Then, by using /%category%/%postname%/ as our permalink structure, blog posts will end up under /blog/post-name/ while portfolio projects will end up under /portfolio/project-name/.

    We’ll also use subcategories under two parent categories to simulate two separate category trees, i.e. /category/blog/category-name/ and /category/portfolio/category-name/. And since we’ll want our blog index to be at /blog/ and portfolio index to be at /porfolio/, we’ll have to create two pages with their own custom page templates at those locations. Last but not least, we use query_posts() to ensure that the blog index only shows posts from the “blog” category while the portfolio index only shows posts from the “portfolio” category. >

Step-by-step instructions:

  1. Under Manage >> Categories, create two main categories named “Blog” and “Portfolio”. Ensure that these two categories have the lowest of all IDs (hijack existing categories if you have to). Under “Blog”, create subcategories for all the categories you would normally use in your blog, while under “Porfolio”, create subcategories for all the categories you would normally use in your portfolio. This way, two separate category trees are simulated.
  2. Make sure all your posts are assigned to either “Blog” or “Portfolio – but not both.
  3. Under Options >> Permalinks, change your Custom Structure to “/%category%/%postname%/” (without the quotes). Even if you have multiple categories on each post, only the category with the lowest ID will be chosen for your permalink (yep, the “Blog” and “Portfolio” categories).
  4. Create two new page templates, one for your blog and one for your portfolio. Use the instructions available at the WP Codex for this.
  5. Create two new pages named Blog and Portfolio for our blog and portfolio index, respectively, and assign one of your custom page templates to each of them.
  6. Under Presentation >> Theme Editor, edit the page template you assigned to your blog index and stuff in the contents of your original Main Index Template (yep, before you made it into a portfolio index).
  7. However, right above <?php if (have_posts()) : while (have_posts()) : the_post(); ?>, insert <?php query_posts('cat=YY'); ?> – where YY is the category ID of your “Blog” category.
  8. Now, edit the page template you assigned to your portfolio index, and stuff in the contents of the Main Index Template you modified after Part 1 and 2 of this guide. If you recall, it should have been modified to be a thumbnail listing.
  9. In this template, you’ll also have to insert <?php query_posts('cat=ZZ'); ?> right before <?php if (have_posts()) : while (have_posts()) : the_post(); ?> – but ZZ is now the category ID of your “Portfolio” category.

Note: Like me, you might think the additional /category/ prefix placed on all your categories is redundant. And normally, you can’t not put a prefix for your categories. But it seems that if you use /%category%/ within your overall permalink structure as we did above, you can access your categories even without the prefix (hat tip to MacStansbury). Just try accessing your categories via http://yourblog.com/category-name/, you’ll find that it does work. The problem is that wp_list_cats() will still list your categories with the prefix, so you’ll have to manually list your categories if you want to take advantage of this workaround. Update: Please read update at the bottom of this post.

Conclusion

For now, I believe Part 2 will be the final part of this mini-series (we’ll go on to another type of website after this, so stay tuned via the Using WordPress as a CMS series index). If you have any suggestions (and there are enough of them) though, then there might be a Part 3. :) Oh yes, feel free to clarify any points, suggest alternative methods, and/or point out any mistakes I might have made. Thanks.

Update: It seems that clean URLs for further pages (/page/2/ and beyond) breaks when you remove the /category/ prefix as described above. You can still access page 2 and beyond via the default query though (i.e. ?paged=2).

If you found this post useful, keep updated with future posts by subscribing to blogHelper (for free) through RSS or email.

Remember to share this post as well (if you liked it, of course): These icons link to social bookmarking sites where readers can share and discover new web pages.
  • del.icio.us
  • digg
  • Fark
  • Furl
  • Ma.gnolia
  • NewsVine
  • Reddit
  • YahooMyWeb

33 Comments

Leave a Reply