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 a freelance WordPress developer and a contributing developer to the Genesis framework. For the past 14 years he has worked with attorneys, publishers, corporations, and non-profits, building custom websites tailored to their needs and goals.

Ready to upgrade your website?

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

Let's Talk

Reader Interactions


  1. Craig Grella says


    you include “portfolio_category” in the section on template filter. Does that need to be replaced with specific categories, or is that the general slug for anything coming through that post type_category?

    • Bill Erickson says

      The plugin I used in this tutorial creates a taxonomy called “portfolio_category” and one called “portfolio_tag”. So if you’re using that plugin, you don’t need to change anything.

      If you created a different taxonomy, you’d use your new taxonomy’s slug instead.

  2. exelexys says

    How ironic. Just spent all day yesterday integrating StudioPress Executive Pro portfolio into Agency Pro!

    Your implementation seems cleaner and more straightforward than two others used as references.

    Tempted to rip it out and try yours. Let me go take a walk until the feeling subsides. =)

  3. Dave Young says

    Wow Bill, this is great addition. I get a few requests for portfolio type pages and this makes dropping them together a real cinch. Nice work, thanks!

  4. James Burgos says

    If this is out-of-scope please let me know and I’ll repost on the fb group page.

    Is there a way without creating additional markup using existing genesis filters and hooks to unhook the permalink from the post title and post thumbnail and rehook it so that it encloses those elements in a single <a>titlethumbnail</a>.

    • Bill Erickson says

      This might work:

      Instead of adding genesis_do_post_title() in the title area, I created a new function that listed an unlinked title.

      I then added an opening ‘a’ element to the very top (genesis_entry_header with priority of 1) and closed the ‘a’ at the bottom (genesis_entry_footer with a priority of 40).


  5. James Burgos says

    DOH again. Sorry
    If this is out-of-scope please let me know and I’ll repost on the fb group page.

    is there a way without creating additional markup using existing genesis filters and hooks to unhook the permalink from the post title and post thumbnail and rehook it so that it encloses those elements in a single wrapping “a” element.

  6. Katie Rosebraugh says

    I’m glad you posted this. I was going to ask you how to do this but now I don’t have to! Thank you!

  7. Hannah says

    This is a nice way of creating a portfolio. I spent all yesterday creating a portfolio with a different approach and it was a mess. I should have taken a walk as well… but no, I ripped it all out, took your approach and messed it up. Now it is pulling 2 images… 🙁 any idea where I went wrong?

  8. Julia Sydnor says

    Great post, Bill. Is there any benefit to using the Portfolio Post Type plugin vs adding a custom post type in functions.php?

  9. Niall Madhoo says

    Hi Bill

    Thanks a lot for this code. It’s much simpler than the code you posted a few months ago and I think it’s much better for conversion to have just the images or logos linking to a case study or more information rather than filtering by taxonomy like it was before.

  10. Sridhar Katakam (@srikat) says

    The column classes are being applied to entries output by Genesis Featured widgets as well (using the built-in ‘Genesis – Featured Page’ widget). Is there a way to restrict the filter to only posts inside the main content area?

  11. Phil Wragg says

    Hi Bill – VERY basic question I have followed the above – not sure where or if the portfolio page with thumbnails has been created. Added a couple of portfolio items – link to detail page of one included. Many thanks

    • Bill Erickson says

      Here it is. If you turn on pretty permalinks in Settings > Permalinks, the URL will be, and the individual portfolio items will be

  12. John says

    Thank you for the detailed tutorial. I always learn so much from your posts. You are helping me and I am sure a lot of others.

    I have previously read you recommend putting CPTs in a plugin so they are not theme depended. I am wondering what about the CSS associated with the CPTs. Would you include that in your theme CSS file or would you have a CSS file in the plugin?


    • Bill Erickson says

      Design-related aspects belong in the theme.

      So if you built an event calendar, the post type, metaboxes, and query customization (sorting events by event date) belongs in the plugin. Styling what your event listing looks like belongs in the theme.

      • Steve Wharton says

        I’m learning tons from your tutorials. I came to this post after studying your post, “How to Build a Genesis Child Theme.” Further question to your answer, re: “Styling what your event listing looks like belongs in the theme…”

        We’re using Genesis and Executive Pro child theme for our work/personal website. Your directions to create a child-theme and plug-ins to segregate customizations (so they don’t get over-written by changing themes or theme updates) make total sense.

        But, since there’s already a child theme, Executive Pro, where/how do recommend we reference our own custom.css file (in the existing stylesheet style.css?) in Executive Pro to tie them together, so our personal website tweaks and customizations do not get overwritten by developer updates to the premium child theme itself? Or maybe there is no best-practice (child to a child-theme?) altogether for this scenario? Thanks, Bill.

        • Bill Erickson says

          A child theme holds your site-specific design. So if you’re using an existing child theme as a starting point, the first step is to rename it. IE, instead of “Executive Pro” you’d name it “My Client’s Site”. Then make whatever changes you like to it.

          There will be no developer updates to the child theme. Child themes are not to be updated.

          • Soretire says

            I think the issue Steve is referring to is if there is a new version of /update to the ‘base’ child theme by the developer (StudioPress in this instance) which he will want his customisation to benefit from. There is a video by Katrinah which describe an approach that work. Basically she recommends creating a custom.css which is included in the wp_head(). All changes will then be done in the custom.css file which would not be changed whenever the child theme is updated.
            The video is at

            • Bill Erickson says

              WordPress doesn’t support grandfather themes for a reason – it unnecessarily increases the complexity of theme development. And StudioPress does a good job of not changing themes after they come out, so this shouldn’t be an issue.

              That said, if you absolutely must make your customizations in a way that doesn’t modify the child theme, create a plugin called “Site Customizations” and include all your customizations in there. Create a stylesheet that’s enqueued with ‘child-theme-css’ listed as a dependency (so it shows up after your child theme’s CSS). Also include all your functions that modify Genesis and the child theme. If you needed to create new template files, use the ‘template_include’ filter to load a template file from the plugin rather than theme.

              The only time I could see this being a possible solution is if you design a Genesis child theme that is to be used across dozens of sites, plan to continually make changes to this child theme, and each site might have some specific customizations required. I would try my best to build the child theme in a way that the changes could be made through the WP Customizer (ex: a logo upload for changing site’s logo, color selector for changing link colors…), but this “plugin as grandfather theme” approach would work.

  13. pitt says

    I have followed this tutorial and when i set the column >1, it will break the right slider and come to a mess… any solution for this ?

    btw, i could use the action “be_portfolio_image” and as duplicated image show up … i have removed this action but i do not know where i can set the image size to show on the portfolio page ….

    i am currently using news pro theme

  14. Robin says

    I encountered the same issue as Sridhar, but resolved it by wrapping lines 12-18 of your template in a conditional for is_main_query. Portfolio is displaying correctly and so are my widgets. Would this not be a better alternative than the CSS?

  15. Edee Lemonier says

    You just saved my neck so big it isn’t even funny – thank you so much!!! Client with a Woo Theme and a portfolio page that went belly up. Just added this bad boy to a Genesis theme and thank everything it’s awesome!!

  16. Jamie Mitchell says

    Hi Bill

    This is a great idea putting the portfolio post type into a plugin, as it is so commonly needed in websites.

    What if I wanted to show the portfolio post type on a custom page template, or even the home page (say on a portfolio site, where the portfolio would be on the actual home page)

    Should i create a custom loop in a front-page.php template

    What would be your recommendation?

    I want to make sure all the html5 structure and Schema is used, just like if it was an archive template.

    thansk so much

  17. James says

    Hi Bill,

    Thanks for the tutorial. It saved me a lot of time…Didn’t know moving things around in Genesis was as easy as changing the hook number (the last parameter in the remove and add action lines….not sure if I said that right?).

    • Bill Erickson says

      Yep, that’s the priority. Lower number means it runs sooner. If you don’t provide a number, it uses 10 as the default.

  18. Clara says

    Hi, great post!
    I’m following your tutorial and I need to change the portfolio url slug to ‘products’.
    I’m new in genesis and still don’t know all the hooks and funcions.
    Do you know how to do that?


  19. Cara says

    Hi there,
    I’m wondering if there is a way to create a page of items filtered by category. Say I had a category inside my portfolio titled ‘photos’ or something like that, is there a way to create a portfolio page of just the items in the photos category?


    • Bill Erickson says

      Yes, just go to the category’s archive page. If you’re using the plugin I linked to above, the URL would be

    • Bill Erickson says

      Look at Line 40 in the “Styling Your Portfolio” section. The img tag is being wrapped with a link to the individual project.

  20. Cara says

    Hi there,
    I’m wondering if there is a way to display category pages with a sidebar instead of as a full width page. Also is there a way to display the category title at the top of the category page? Any thoughts are welcome. Thanks

  21. Cara says

    Sorry, one more question. Is there a way to make the images link to an item on a category page?


  22. Henk van den Bor says

    Recently I found out that most of the portfolio archive pages that are created like this are not getting a nice search result in Google (e.g.

    I have tried to get a more relevant description by starting the portfolio with a bit of text, but Google just does not pick it up… also when using Yoast’s seo and adding a custom description to the page.
    I used a function to insert the text before the post_content, but it looks like Google wants it inside the content div… (The site is pre html 5)

    When I look at the google result for your /projects page I see a part of the text from the contact form wrapper … without a clear clue as to why this is considered to be the most relevant content for the description that Google uses..

    Does anyone have an idea as to how to insert a good description that will be used by Google?

    • Bill Erickson says

      I have my portfolio archive and individual projects set to noindex, so they don’t show up when someone searches for a client’s site. So I don’t care too much about what Google knows about the page.

      I would expect that setting the meta description would help, especially on a portfolio like mine that has no text.

      • Henk van den Bor says

        Thing is that i created the portfolio page a few years ago, with the method Genesis then used (and a few of your tips as extra’s 🙂 )
        I set it up to work under the term ‘massage-chairs’ now it turns out to be the highest ranking page when searching for ‘massage-chairs’. It displays the posts in the category “massage chairs’.
        I tried, setting the meta-description in categories, setting the seo description with Yoast, setting the archive-intro, setting all of those on the page that uses the ‘massage-chairs’ template….
        Still Google does not pick up any-one of those, and the nagging bit of it is that I do not understand why this is happening… 🙂

        • Jamie Mitchell says

          Did you try creating a site map? and making sure the post types are in it.

          I can’t seem to remember the exact details but i did have a similar issue on a project, and i created a site map and made sure those post type categories where it is then submitted the site map to google. At the time it seem to work.

  23. msa2301 says

    Hy there !
    i want to show specific portfolio on multiple pages. like there are 3 pages CLIENTS, Completed projects, current projects . so how can i do this can you plzz tell me ?

  24. Val Lynn says

    Thank you Bill for sharing this and for being present in the comments! Thank you also to Sridhar Katakam and Robin Cornett.

    [Using genesis] I created a custom page template to display my portfolio items and wanted to combine a normal “page” with the addition of the portfolio like Robin ( I was hoping to do this “natively” through a page template (so I could use that page template anywhere on my site) but could not get the portfolio to display in a grid beneath the page text (that flowed full width). I solved the problem in a roundabout way by reading Sridhar Katakam’s specifically this section //* [Dashboard] Add Archive Settings option to Books CPT
    add_post_type_support( ‘books’, ‘genesis-cpt-archives-settings’ );

    Is there a way to have the portfolio display in column format beneath *any* wordpress page through the creation of a custom page template without using the Archive Settings?

    • Bill Erickson says

      If you’re doing a custom query on a page template, you’ll need to handle the HTML markup yourself. You can’t use the post_class() function since it is for the main query. In other words, if you were to use the post_class filter to break your custom loop into columns, it would break the main page content at the top into columns as well.

      Your page template should look something like this:

      • Val says

        ACK! Oh boy, that certainly does exactly what I wanted. Now I can employ this custom page template and not have to have the same archive text on every page. The text an be pulled from the page itself.

        Brilliant. Thank you Bill.

    • Bill Erickson says

      My guess is you’re using a custom taxonomy like portfolio_category, not the built-in ‘category’ taxonomy that’s applied to posts. For custom taxonomies, use [post_terms taxonomy="portfolio_category"]

        • Bill Erickson says

          That goes in your post_meta filter, replacing [post_categories]

          I’m sorry but I don’t provide free support or consulting, so if you need help implementing it I recommend you hire someone on

  25. Phil says

    hi Bill

    thanks for the tutorial — i added the archive-portfolio.php and have the columns set to 3.

    i added 4 test Portfolio items to a category called Products and created a menu link to that category in the top menu. But the Category is displaying each item individually and not in a nice grid as you had it.

    I have the column classes in place in the CSS

    [in terms of other plugins i have running I have GENESIS GRID but deactivating that did not resolve the issue]

    any idea why the category is not displaying in a 3 column layout?

    • Bill Erickson says

      Did you include the code above under “Same template for taxonomies”? If so, make sure the taxonomy name in that code matches the taxonomy you’re using.

      Also, this code needs to go in functions.php, not the archive-portfolio.php file with the rest of the code mentioned in this post.

  26. Phil says

    Thanks Bill

    yes this is what i added to functions.php

    * 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’ );

    * 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’ );

  27. Phil says


    think i sorted it — i noticed that in the wordpress SETTINGS > READING the “Blog pages show at most” parameter was set to 1 POST [not sure why it was set at that value] but I amended that to 12 and it’s all working fine now

    • Bill Erickson says

      Use previous_post_link() and next_post_link() for the post navigation.

      Filter ‘genesis_post_meta’ and use [get_terms taxonomy=”portfolio_category”] to list the categories.

  28. Phil says

    Thanks Bill
    “Use previous_post_link() and next_post_link() for the post navigation.”
    does that go in the functions.php?


    • Bill Erickson says

      I would put it in archive-portfolio.php along with all the other portfolio related code, but you can place it wherever you like.

  29. Phil says

    trying this in both the archive-portfolio.php and functions.php but not showing the POST NAVIGATION links in either case.

    anything you spot that’s wrong with this Bill?

    function portfolio_post_nav_links() {
    if( ‘portfolio’ == get_post_type() && is_single() ) {?>

    } }
    add_action('genesis_entry_footer', 'portfolio_post_nav_links', 5 );

  30. Courtney A. says

    Hi Bill!

    I’ve set up a portfolio the way you have outlined here (super easy for a novice like me!), but my portfolio page displays with a sidebar. Is there any way I can get it to display full-width? Thanks.

  31. Chrissy says


    I just wanted to say thank you for this post. I’m using Parallax which has no built-in Portfolio option, and this tutorial worked beautifully. I’ve tried at least 5 different CPT Portfolio tutorials with no luck or lots of confusion,and this did the trick!

    • Bill Erickson says

      Yes. The post type remains ‘portfolio’, but that code changes the archive URL (/whats-on) and the single post URL (/whats-on/post-name)

      • Joseph says

        Hi Bill,

        That’s not what I’m getting. The code has been inserted into the functions.php at the bottom like so…

        * Portfolio Post Type Args
        function be_portfolio_post_type_args( $args ) {
        $args[‘rewrite’] = array( ‘slug’ => ‘whats-on’ );
        return $args;
        add_filter( ‘portfolioposttype_args’, ‘be_portfolio_post_type_args’ );

        but when going to the url

        it redirects to

        • Bill Erickson says

          Are you using the Portfolio Post Type plugin described above? That’s a filter inside that plugin, so if you created your own custom post type or are using a different plugin, it won’t work.

          To update the permalink structure, you go to Settings > Permalinks and click Save. You don’t have to change anything on the page.

          Do you already have a page called /whats-on or /what-on-2 ? It might be in your trash. Delete all pages that have these URL slugs, empty your trash, then update the permalinks again and see if that works.

          • Joseph says

            Great that sorted it. i was using the wrong plug in. one last thing do i use the plugin to change the name of the page that appears on the browser tab

          • Bill Erickson says

            You can use that filter to customize all the post type arguments, including the name of the post type which is what I think you’re referring to.

  32. Jamie Mitchell says

    no, you only need to visit the permalinks page and hit save, it acts like a refresh.

    but if that didn’t solve it then it is something else, i’ll let the master reply to this one 🙂

  33. Joseph says

    its the text on the tab. Also when going to one of the portfolio (whats-on) items it it still reverts back to
    I suppose I am trying to make the whats on a parent of one of the items

  34. Damien Carbery says

    Thanks for this. I was using a page template with a custom loop to get my CPTs but then I realised that I would have issues with paging. Using your code results in paging handled automatically (I assume – the site I am working on only has 4 CPT posts so not hitting the posts_per_page limit.

  35. Tim Squires says

    Hi Bill,
    I’m using Desktopserver and working locally on a test site while I figure this out.
    I am stuck in the very early stages of the tutorial. I have added three portfolio items, but when I try to navigate to I get an object not found error.
    This is probably something basic that I am not doing correctly, but I can’t figure it out.
    Thanks for your help.

  36. Angie says

    I am trying to add more than one portfolio page to my site. I would like to have two totally separate pages that contain two different portfolio categories. I have a followed a tutorial very similar to this one to get the original portfolio page set up, but whenever I try to add a second portfolio page, it just overwrites the first one. Is having two portfolio pages not possible?

    • Bill Erickson says

      You can’t have two content types with the same name (portfolio). And while you could go to the hassle of building two completely separate portfolios, a much better solution is to use categories.

      1. Register the portfolio post type (or use the plugin) and set ‘has_archive’ => false. This will make it so there’s no portfolio page that displays all items.
      2. Create a taxonomy called Portfolio Categories. Create a category for each different portfolio you want.
      3. Add portfolio items and specify which category they go in.
      4. Use the taxonomy archive pages as your separate portfolios (ex:
  37. Niki Payne says

    I knew there was a way to do this. Yours was the first post I could find that showed how to do what I have been trying to do for over a month. I followed the instructions, but I’m still having styling issues. I can’t really figure out what’s wrong here. Here is what I ended up:
    Here are my “Gists”:

    Archive-Portfolio.php –
    Style.css –
    Functions.php –

  38. Tony says

    Bill I am using your plugin, I don’t understand what you mean by this “Register the portfolio post type (or use the plugin) and set ‘has_archive’ => false. This will make it so there’s no portfolio page that displays all items.”
    Where do I find ‘has_archive’ => false


  39. Myrna Knode says

    THANK YOU! Just implemented this tutorial and working perfectly. Thank you so much Bill for the time you take putting these together. I especially appreciate how clearly and simply you explain the ‘why’ and ‘what’ behind your beautiful coding solutions. Really helps so much to have an excellent translator when you’re learning a new language 😉

  40. Hazel L says

    Thank you for this incredibly helpful post, Bill!

    I have it working on this website: but I want to extend it further and create a sort of album system or sub-categories for the portfolio.

    For example have it structured like this inside WordPress: so that clicking one project leads to an archive of sub-projects (or in my case, specific weddings). I’m assuming it’s possible to achieve this on Genesis but haven’t been able to find the resource.

    Any help is much appreciated! Thanks again.

    • Bill Erickson says

      Make sure the post type is hierarchical when you register it. That will make it looks like your screenshot rather than like posts.

      I’d then use ‘template_include’ to point top level pages to a separate template. Something like this:

      You’d then use portfolio-album.php to style the album pages (top level portfolio items), and single-portfolio.php to style the individual projects (subpages of portfolio items).

  41. AnitaC says

    Hi Bill, is there a way to set the default number of portfolio items to show up? I need my home page to stay set at 3 (via Settings > Reading>, but it changes the portfolio archive to 3. I need the portfolio set to 6. Thanks in advance for your help.

  42. Ivan says

    What approach you would recommend for displaying all the attached images on single.php
    Seams that genesis doesn’t have built in function.thanks for all the shared knowledge.

  43. Paul Oaten says

    Hi Bill,

    thank you for this brilliantly useful post. I have it up and running on a localhost install. I only have one question: is there an easy way to center align the portfolio post image and heading on the archive grid view?

  44. Noman says

    Hi Bill,
    Thanks for your useful tutorial.working fine on my blog.I will install your plugin asap! thanks again

  45. Hugh Anderson says

    Hi Bill,

    thanks for the excellent tutorial – I have been trying to apply it’s methods. (beginner)

    I wanted to ask, can I turn off the sidebar in the Portfolio page? I can turn it off globally, but then I can’t get it to be present in my blog. And since there isn’t a “Portfolio” page, I can’t target the sidebar. Wee, “I” can’t. 🙂

    Any pointers would be welcome.



    • Bill Erickson says

      In your archive-portfolio.php file, add this: add_filter( 'genesis_pre_get_option_site_layout', '__genesis_return_full_width_content' );

      • Hugh Anderson says


        that’s awesome! Thank you so much for your speedy and most helpful reply, it did exactly what I wanted. I really appreciate it.


  46. Pixelloop says

    Hi Bill,

    Cool tutorial, I would love to see a way you could setup this template in a way so it could be used by any custom post type. I guess that would involve some child theme settings to allow you to activate the template or specify the name of the post type you are using that you want to have the grid active for?

    I know from the past you were a proponent of Thesis also, and then moved. There are a few things I still believe Thesis handles better.

    1) It would be cool if on the edit taxonomy term screen you could specify what template you wanted to use there like you can on the edit page screen. You can do this in Thesis and is one loose end of Genesis.

    2) Genesis over reliance on widgetized areas for custom content areas. I like your approach using advanced custom fields but have a few ideas which I think would improve the ecosystem. WordPress Spots plugin is a good idea, albeit with some modifications to allow shortcode insertion or template insertion etc.

    Would love to hear your feedback.

    • Bill Erickson says

      You can use the template_include filter to specify which templates are used where on your site. For instance, if you had ‘portfolio’ and ‘product’ post types and wanted this template used on the archive page for the product one, you could do this:

      Alternatively you could just create an archive-product.php template and put the same code in there, but that would require duplicating the code.

      I’m sure you could build your #1 request with the above code and a metabox on the Edit Term screen

      For #2, Genesis does not rely on widgetized areas at all. You’re describing StudioPress’ child themes. I can’t stand widgetized areas being used for page content, like 5 widget areas for the front page. It belongs in a metabox when you edit the front page, not in widgets. But StudioPress chooses to do it that way since it takes less code (don’t have to create custom metaboxes, leverage built-in WP functionality instead) and it’s easier for their support to help customers if every theme works in a very similar way.

  47. Rani says

    I’m trying to pull the tags for each portfolio item, but I get none.
    get_the_tags is not working as well.

    • Bill Erickson says

      It’s probably because you’re using a custom taxonomy. get_the_tags() only works with the ‘post_tag’ taxonomy. You’ll want to use get_the_terms( get_the_ID(), ‘my_taxonomy_name’ );

  48. MarK Hemmingson says

    Thanks for this Bill. Is it possible to use this so that the grid only displays for the category called “Gallery”? I have a site where all the artisans are added to the “Gallery”. The link in the navigation is a category, so the posts display according to the Genesis Theme settings. I would like them to display as a grid for the “Gallery” category only.

    • Bill Erickson says

      Instead of naming the file archive-portfolio.php which would apply to a ‘portfolio’ post type, name it category-gallery.php which will apply to the category with a slug of ‘gallery’.

  49. Carissa Magras says

    Thank you so much for this!!! Quick question: Is there a way to add “next” and “previous” buttons? I love the display of the portfolio on my page, but would really like to be able to just click “next” when viewing (instead of going back to main page every time).

  50. Tim says

    Hi, I am just curious as to actions like this: remove_action( ‘genesis_entry_header’, ‘genesis_entry_header_markup_open’, 5 );

    Why do you need to add the number at the end? Isn’t this a number specifying priority? If so, is it needed when you are removing an item?

    • Bill Erickson says

      Yes, the priority is needed if you are removing a function that was added at a certain priority.

      In the example above, if you left off the 5 it would use the default priority (10). But genesis_entry_header_markup_open() uses the priority of 5, so it wouldn’t get removed.

  51. Nelson says

    Hey Bill,

    This is the layout I’d like to add on my blog page. However I have a hard time understanding the first section of code.

    I dont understand this first statement. What is main query function is that a post? what classes it will return if that statement is true?
    global $wp_query;
    if( !$wp_query->is_main_query() )
    return $classes;

    I understand the the array but i dont understand why there is a empty string and how that will connect to the variable $classs
    $column_classes = array( ”, ”, ‘one-half’, ‘one-third’, ‘one-fourth’, ‘one-fifth’, ‘one-sixth’ );
    $classes[] = $column_classes[$columns];

    how this last statement works?
    if( 0 == $wp_query->current_post || 0 == $wp_query->current_post % $columns )
    $classes[] = ‘first’;

    return $classes;

    • Bill Erickson says

      The is_main_query() method on the $wp_query object checks to see if this is the main query on the page. The “main query” is whatever WordPress things the content on the page should be. For instance, on a single page it would be the query for that page’s content. On a category archive it’s the query for the posts in that category.

      The function in question, be_portfolio_post_class(), runs on the ‘post_class’ hook. This lets you modify the classes that are applied to the post.

      The first chunk of code you mention can be read as “if this is not the main query, return the classes unmodified”. This is called “returning early” – the rest of the function only runs if the specific conditions under which we want to modify the classes is met (in this case, if this is the main query).

      The second chunk of code you mention is where we add the appropriate column class to the post. The number of columns will be 2, 3, 4, 5, or 6. So I created a $column_classes array where the key matches the value of the class we want applied. A 2 column listing would be $column_classses[2], which is ‘one-half’. The two empty strings in the array are for $column_classes[0] and $column_classes[1] which don’t require column classes.

      The third chunk of code adds a class of ‘first’ to the first post in each column. It can actually be simplified, so I’ve updated it to just say if( 0 == $wp_query->current_post % $columns ). We take the current post count in the loop (it starts at 0), divide it by the number of columns, and if the remainder is 0 we add a class of “first” to it. So on a 2 column grid with 4 posts, the first post (current_post = 0) and the 3rd post (current_post = 2 ) will get the ‘first’ class added because both of those numbers divided by 2 have a remainder of 0.

  52. Ericka Watson says

    Thank you for the tutorial; I am pleased with the results. Can you please tell me how to remove the post title from just the portfolio page? My images contain the title I want to use. I tried to look through all the comments and your answers, but I did not see another request for this modification.

    Thank you,
    Ericka Watson

    • Bill Erickson says

      At the bottom of the archive-portfolio.php page, there’s a section labeled “Move Title below Image”. The first three lines remove the post title, and the second three lines add the title below the image. If you don’t want a title, simply remove those three lines that begin with add_action()

    • Bill Erickson says

      You’ll need to set the number of posts per page you want in your portfolio by modifying the WP query. Add something like this to your functions.php file.

      To make it full width, add this to your archive-portfolio.php template file: add_filter( 'genesis_pre_get_option_site_layout', '__genesis_return_full_width_content' );

  53. Nick Gowman says

    Hi Bill,

    Many thanks for such an awesome tutorial – this has worked a treat for a relative Genesis beginner and has saved me so much head scratching!

    Sorry to be cheeky, but I was wondering if there is a way to automatically order the items added to the portfolio by their name/title and also where I could go about adding in custom classes for the title etc, just for some more control over the actual look/feel.

    Many thanks in advance


    • Bill Erickson says

      See this tutorial on customizing the WordPress query. The short answer though is use this code. It must go in the theme’s functions.php file or a plugin. Putting it in archive-portfolio.php is too late because by the time that template has loaded, the initial query has run (that’s how it knew which template to use).

      To add custom classes to the title you’d need to remove the genesis_do_post_title() function and add your own. But a simpler approach is to use the existing classes. The

      element includes post-type-specific classes. So you could use .entry.type-portfolio .entry-title to target all instances of portfolio titles (both single post and archive pages). To limit it to a specific context, look at the body classes (ex: .post-type-archive-portfolio and .single-portfolio).
  54. Nick Gowman says

    Thank you very much Bill – this has worked a treat. Just to be additionally cheeky, is there a way to crop the images so that regardless what dimensions the source image is, it will always maintain a consistent grid like ratio?

    Many thanks in advance


    • Bill Erickson says

      Yes, use add_image_size() to create a new image size in your child theme. Set the width and height to whatever you’d like, and specify true as the third parameter, which crops the image. If you set the third parameter to false it would only scale down the image.

  55. Nick Gowman says

    Hi Bill,

    Many thanks – so I’ve tried adding
    add_image_size( ‘custom-size’, 300, 300, true );

    To both my functions file and then also to my ‘archive-portfolio.php’ page, but obviously know that this won’t be enough to get it to work – how do I tally up this function to the thhumbnail images in the portfolio please?

    • Bill Erickson says

      Image sizes are only generated when the image is uploaded. If you want older posts to use the new image size, install and run Regenerate Thumbnails.

      Also make sure the function displaying the image in archive-portfolio.php is using the new size:
      genesis_get_image( array( 'size' => 'custom-size' ) )

  56. Nick Gowman says

    Hi Bill

    Ok I’ve added the following to my functions file:
    add_image_size( ‘artist-gallery-thumb’, 300, 300, true );

    and this to my archive-portfolio:
    genesis_get_image( array( ‘size’ => ‘300,300’ ) ). ‘‘ );

    Selected my new size (artist-gallery-thumb) within the genesis theme settings admin page and regenerated all my thumbnails, but still no resize/success – am I doing something else wrong?

    Apologies if this is a trivial question and really appreciate the help

    • Bill Erickson says

      For the size you need to specify the image size’s name. Change it to:

      genesis_get_image( array( 'size' => 'artist-gallery-thumb' ) );

  57. Nick Gowman says

    Hi Bill,

    Many thanks again for your assistance – this is all working very well for me.

    Just to ask one more cheeky question if I may – If I wanted to add a style to the ouput of the thumbnails, so I could add in some CSS transitions on hover (like an opacity change/overlay) etc, how would I go about adding a class to the thumbs please?

    My plan being that the thumbs could possibly fade to a semi-opaque black and then move the title of the portfolio item to sit in the centre of the thumbnail.

    Many thanks again, I really appreciate your advice and guidance


  58. 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”

  59. 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.

  60. 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

  61. 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

  62. 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.

  63. 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.

  64. 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.

  65. 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.

  66. 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


  67. Nicola says

    Hi Bill, thanks from Italy for your amazing tutorials! I was wandering if is possible, inside this query, to isolate the most recent portfolio item and query it, in full width, before the columns!

    Thank you!

  68. Daniel says

    This post helped me a LOT! I’ve been wracking my brain trying to figure out this weird Genesis way of doing things. My client has Agency Pro running and wants me to create an ensemble page – basically like a portfolio list. Created the CPT and some fields using ACF as I was used to, only to find out that Genesis and its child themes are not coded the way I normally code themes 🙂

    Anyhow … here’s my question: can you give me a point to start when I want create an archive that is grouped into categories? So that the output is sort of like
    Category title
    column item column item column item column item
    Category title
    column item column item column item column item column item column item
    Category title
    column item column item


    Much appreciated.

  69. Joyce Grace says

    Hi! Thank you very much for this. I tried it out, and noticed that the archive headline and intro text don’t come into play with the portfolio archive template. Is there an obvious thing I’m missing? Sorry if this is in plain sight!

  70. Michel says

    Interesting I copied the archive-portfolio.php as is, but the strange thing is that the removing of the title is only working for the first post. The other posts now have the title twice. One above and one below the image.

    • Michel says

      What I mean is that this line (line 48 in the example):
      remove_action( ‘genesis_entry_header’, ‘genesis_do_post_title’ );
      Is only working on the first post and not all entries.

Leave A Reply