Adding a Portfolio to any Genesis child theme

This tutorial is designed for intermediate developers. It will get you started, but you’ll need to tweak the template files to your own needs.

A few of the StudioPress child themes include a portfolio page, like Modern Portfolio and Jane. But what if you’ve found a theme you want and it doesn’t include this feature?

It’s actually not that difficult to add to any theme. And even if your theme already includes it, this plugin-based approach will ensure your portfolio will keep working when it comes time to change themes.

An Integrated Approach

Just like Event Calendar Integration, this is a feature that should be built using a plugin and your theme.

The plugin contains the functionality: registering a “portfolio” post type, a “portfolio categories” taxonomy, any necessary metaboxes…all of the backend features that should be theme-independent and stay with you when you change themes in the future.

The theme is responsible for styling how the portfolio looks. If you don’t make any changes to your theme, the portfolio will look like another blog (because it will inherit the styling from that section). In the future if you change themes, you’ll want to update the design of that theme with regards to your portfolio.

Set up the backend

Portfolio in BackendInstall the Portfolio Post Type plugin. This will add a “Portfolio” post type below your “Posts”.

Add your portfolio items, making sure to add images for each one so the layout looks good in the next step.

If you go to, you’ll see all your portfolio items showing up but it looks like a blog – just title and post content.

Styling your Portfolio

Create a theme file called archive-portfolio.php and place it in your child theme. Place this code in it:

* Portfolio Archive
* Display as Columns
function be_portfolio_post_class( $classes ) {
global $wp_query;
if( !$wp_query->is_main_query() )
return $classes;
$columns = 3;
$column_classes = array( '', '', 'one-half', 'one-third', 'one-fourth', 'one-fifth', 'one-sixth' );
$classes[] = $column_classes[$columns];
if( 0 == $wp_query->current_post % $columns )
$classes[] = 'first';
return $classes;
add_filter( 'post_class', 'be_portfolio_post_class' );
// Remove items from loop
remove_action( 'genesis_entry_header', 'genesis_post_info', 12 );
remove_action( 'genesis_entry_content', 'genesis_do_post_content' );
remove_action( 'genesis_entry_footer', 'genesis_entry_footer_markup_open', 5 );
remove_action( 'genesis_entry_footer', 'genesis_post_meta' );
remove_action( 'genesis_entry_footer', 'genesis_entry_footer_markup_close', 15 );
* Add Portfolio Image
function be_portfolio_image() {
echo wpautop( '<a href="' . get_permalink() . '">' . genesis_get_image( array( 'size' => 'medium' ) ). '</a>' );
add_action( 'genesis_entry_content', 'be_portfolio_image' );
add_filter( 'genesis_pre_get_option_content_archive_thumbnail', '__return_false' );
// Move Title below Image
remove_action( 'genesis_entry_header', 'genesis_entry_header_markup_open', 5 );
remove_action( 'genesis_entry_header', 'genesis_entry_header_markup_close', 15 );
remove_action( 'genesis_entry_header', 'genesis_do_post_title' );
add_action( 'genesis_entry_footer', 'genesis_entry_header_markup_open', 5 );
add_action( 'genesis_entry_footer', 'genesis_entry_header_markup_close', 15 );
add_action( 'genesis_entry_footer', 'genesis_do_post_title' );

The first secton of code is breaking the portfolio into columns. Change the
$columns = 3 to however many columns you want (2-6). If your portfolio is not showing up in multiple columns, your theme might be missing the Column Classes CSS. Go to that link and copy/paste the CSS to your style.css file.

The second section is removing items we don’t want showing up in the loop. I’m removing the post info (date and author at top), post content, and post meta (categories at bottom). I’m also removing the markup for the entry’s footer since we no longer have a footer.

The third section is adding an image to replace the post content. I’m using the medium image size, which you can manage in Settings > Media. You might also consider creating your own image size in functions.php.

The fourth section moves the post title below the featured image.

With that in place, you should have a pretty good portfolio set up. You might want to do some additional styling or changes to the template file, but now you have a starting point. Here’s what it looks like on my demo site:

Screen Shot 2014-03-05 at 8.05.38 AM

Use same template for taxonomies

The plugin includes Portfolio Categories and Portfolio Tags taxonomies. You could duplicate the template file into taxonomy-portfolio_category.php and taxonomy-portfolio_tag.php, but that means if you make changes in the future you’ll need to update 3 files.

A cleaner approach is to put this in functions.php:

* Portfolio Template for Taxonomies
function be_portfolio_template( $template ) {
if( is_tax( array( 'portfolio_category', 'portfolio_tag' ) ) )
$template = get_query_template( 'archive-portfolio' );
return $template;
add_filter( 'template_include', 'be_portfolio_template' );
view raw functions.php hosted with ❤ by GitHub

That tells WordPress “if we’re on either the portfolio category or portfolio tag taxonomies, use the portfolio archive template file”.

Ordering projects

Right now the projects are showing up in reverse chronological order – the most recently published are at the top. But since this is a portfolio, you might want to put your most impressive projects at the top, regardless of post date.

Add this to your functions.php file:

* Add 'page-attributes' to Portfolio Post Type
* @param array $args, arguments passed to register_post_type
* @return array $args
function be_portfolio_post_type_args( $args ) {
$args['supports'][] = 'page-attributes';
return $args;
add_filter( 'portfolioposttype_args', 'be_portfolio_post_type_args' );
* Sort projects by menu order
function be_portfolio_query( $query ) {
if( $query->is_main_query() && !is_admin() && ( is_post_type_archive( 'portfolio' ) || is_tax( array( 'portfolio_category', 'portfolio_tag' ) ) ) ) {
$query->set( 'orderby', 'menu_order' );
$query->set( 'order', 'ASC' );
add_action( 'pre_get_posts', 'be_portfolio_query' );
view raw functions.php hosted with ❤ by GitHub

You can now use the “Page Attributes” box in the right column when editing a portfolio item to set the order, or install a plugin like Simple Page Ordering which will let you drag them around from the main portfolio edit screen.

Bill Erickson

Bill Erickson is the co-founder and lead developer at CultivateWP, a WordPress agency focusing on high performance sites for web publishers.

About Me
Ready to upgrade your website?

I build custom WordPress websites that look great and are easy to manage.

Let's Talk

Reader Interactions

Comments are closed. Continue the conversation with me on Twitter: @billerickson


  1. Nick Gowman says

    Hi Bill,

    Many thanks again for your help to date -things are progressing well, but am confused as the titles for each of my portfolio entries is showing as a H1 – where would I need to look to change this to h2 or similar please?

    Best regards


    • Bill Erickson says

      Go to Genesis > SEO Settings and uncheck ” Use semantic HTML5 page and section headings throughout site”

  2. Ellie Brassé says

    Hi Bill,

    this is very useful and works a treat. I’d really like to use this as a page template though – I’m using a Genesis theme, it doesn’t have a portfolio archive page, I’d like one.
    I’ve tried a few ways of tricking it into this but to no avail. Are you able to help?

    • Bill Erickson says

      If you’re using it as a page template you’ll have to build the loop yourself, because the ‘main query’ on the page is for the page itself. Do a custom query, then loop through that query and output the portfolio items however you’d like.

  3. Nick Gowman says

    Hi Bill,

    Is there any way to filter by category so that certain categories will use the portfolio functionality, but hide the thumbnail from the main ‘portfolio’ page – ie exist as a portfolio item, but the thumbnail is hidden

    Many thanks

  4. Nick Gowman says

    Hi Bill,

    Is there a way to add a ‘back’ button to just the portfolio pages – ie a way once you’re at the bottom of a page to take you back to the main portfolio archive?

    Many thanks

  5. Tyler says

    Hey Bill,
    I was wondering if you had any tips to accomplish what is seen on this page: . BAsically loops out images BUT when clicked the CPT content appears under a row. I was hoping to use this tutorial and make 2 query loops to make it work, the difficulty is separating the grid images and hidden content. Any tips on how to accomplish this neat effect? Would the more advanced genesis grid loop work better?

    • Damien Carbery says

      It looks like it generates a row of 4 images and then a row with their biographies.
      In it shows and hides the biographies.
      You could have a loop counter, store the bio info in a temp variable (appending it in each loop) and then, when the counter hits 4 (or 3 if zero based), you spit out the biographies and reset the counter and temp variable.

      Of course I expect that Bill will have an elegant solution in a gist shortly.

  6. sudhir shukla says

    Amaizing, I was thinking to change the portfolio. Thank God, I just landed on your blog and found this easy and clean way to do the same. Now going to follow your tutorial. Thanks for guiding us.

  7. Martin Ostachowski says

    Great, thanks Bill for writing this amazing instruction and answering patiently all these questions. My portfolio works now just how I wanted it to.

  8. Martin Ostachowski says

    Great, thank you for this description and for answering all these questions. Thanks to this documentation my portfolio looks now just as I wanted it to.

  9. Nick Gowman says

    HI Bill,

    Sorry to bother you, but I was wondering if there’s a way to display a latest ‘portfolio’ item on, for example, the homepage of the site that would automatically show the latest / a series of latest posts from the portfolio?

    Many thanks