Create Multiple Portfolio Style Category Archive Pages in Crystal Theme

Duplicating a portfolio page in Genesis requires a fair amount of coding. Depending on which theme you are using, you may also be able to use a portfolio page to display your category archives.

In this tutorial, you’ll learn how to create multiple portfolio pages which you can use to display the posts assigned to any or all category archives, in a portfolio layout.

Update: Not using the Crystal theme? Here’s a post where you can use the same method to convert category archives to portfolio style archive pages using any child theme built on the best theme framework for WordPress.

We’ll be using the Crystal child theme by StudioPress as it uses a portfolio page template that displays posts in a specific category.

The name i will be using for the second portfolio is portsecond which is also used for the name of the category and slug posts are assigned to for this portfolio style archive.

The process involves duplicating and renaming these functions & classes:

  • Add Crystal theme settings to Genesis default theme settings
  • Add Portfolio Settings box to Genesis Theme Settings
  • Template Name: Portfolio
  • CSS code for the portfolio classes

Multiple Portfolio Category Pages

Here’s the actual screenshots showing you what the result is after creating 2 portfolio style category archive pages.

single portfolio

And the duplicate portfolio category page

second portfolio

Add Crystal theme settings to Genesis default theme settings

This is the code which has been copied from the portfolio functions and gets pasted at the end of the Crystal themes functions.php file.

// Add Crystal theme settings to Genesis default theme settings
add_filter( 'genesis_theme_settings_defaults', 'crystal_portsecond_settings' );
function crystal_portsecond_settings( $defaults ) {
    $defaults['crystal_portsecond_content'] = 'excerpts';
    return $defaults;
}

add_action( 'admin_menu', 'crystal_portsecond_settings_init', 25 ); 
/** 
 * This is a necessary go-between to get our scripts and boxes loaded 
 * on the theme settings page only, and not the rest of the admin 
 */ 
function crystal_portsecond_settings_init() { 
    global $_genesis_admin_settings; 
     
    add_action( 'load-' . $_genesis_admin_settings->pagehook, 'crystal_add_portsecond_settings_box', 20 ); 
} 

// Add portsecond Settings box to Genesis Theme Settings 
function crystal_add_portsecond_settings_box() { 
    global $_genesis_admin_settings; 
     
    add_meta_box( 'genesis-theme-settings-crystal-portsecond', __( 'Portsecond Page Settings', 'crystal' ), 'crystal_theme_settings_portsecond',     $_genesis_admin_settings->pagehook, 'main' ); 
} 
    
function crystal_theme_settings_portsecond() {
?>
    <p><?php _e( "Display which category:", 'genesis' ); ?>
    <?php wp_dropdown_categories( array( 'selected' => genesis_get_option( 'crystal_portsecond_cat' ), 'name' => GENESIS_SETTINGS_FIELD.'[crystal_portsecond_cat]', 'orderby' => 'Name' , 'hierarchical' => 1, 'show_option_all' => __( "All Categories", 'genesis' ), 'hide_empty' => '0' )); ?></p>
    
    <p><?php _e( "Exclude the following Category IDs:", 'genesis' ); ?><br />
    <input type="text" name="<?php echo GENESIS_SETTINGS_FIELD; ?>[crystal_portsecond_cat_exclude]" value="<?php echo esc_attr( genesis_get_option( 'crystal_portsecond_cat_exclude' ) ); ?>" size="40" /><br />
    <small><strong><?php _e( "Comma separated - 1,2,3 for example", 'genesis' ); ?></strong></small></p>
    
    <p><?php _e( 'Number of Posts to Show', 'genesis' ); ?>:
    <input type="text" name="<?php echo GENESIS_SETTINGS_FIELD; ?>[crystal_portsecond_cat_num]" value="<?php echo esc_attr( genesis_option('crystal_portsecond_cat_num') ); ?>" size="2" /></p>
    
    <p><span class="description"><?php _e( '<b>NOTE:</b> The portsecond Page displays the "portsecond Page" image size plus the excerpt or full content as selected below.', 'crystal' ); ?></span></p>
    
    <p><?php _e( "Select one of the following:", 'genesis' ); ?>
    <select name="<?php echo GENESIS_SETTINGS_FIELD; ?>[crystal_portsecond_content]">
        <option style="padding-right:10px;" value="full" <?php selected('full', genesis_get_option('crystal_portsecond_content')); ?>><?php _e("Display post content", 'genesis'); ?></option>
        <option style="padding-right:10px;" value="excerpts" <?php selected('excerpts', genesis_get_option('crystal_portsecond_content')); ?>><?php _e("Display post excerpts", 'genesis'); ?></option>
    </select></p>
    
    <p><label for="<?php echo GENESIS_SETTINGS_FIELD; ?>[crystal_portsecond_content_archive_limit]"><?php _e( 'Limit content to', 'genesis' ); ?></label> <input type="text" name="<?php echo GENESIS_SETTINGS_FIELD; ?>[crystal_portsecond_content_archive_limit]" id="<?php echo GENESIS_SETTINGS_FIELD; ?>[crystal_portsecond_content_archive_limit]" value="<?php echo esc_attr( genesis_option( 'crystal_portsecond_content_archive_limit' ) ); ?>" size="3" /> <label for="<?php echo GENESIS_SETTINGS_FIELD; ?>[crystal_portsecond_content_archive_limit]"><?php _e( 'characters', 'genesis' ); ?></label></p>
    
    <p><span class="description"><?php _e( '<b>NOTE:</b> Using this option will limit the text and strip all formatting from the text displayed. To use this option, choose "Display post content" in the select box above.', 'genesis' ); ?></span></p>
<?php
} 
[/code]

<h3>New Template Page</h3>

This is the PHP code which needs to be pasted into a new file using a <a href="http://wpsites.net/tools/windows-text-editor-notepad/">text editor</a> like Notepad++ and named page_portsecond.php

[code]
<?php

// Template Name: Portsecond

// Force layout to full-width-content
add_filter('genesis_pre_get_option_site_layout', 'crystal_portsecond_layout');
function crystal_portsecond_layout($layout) {
    $layout = 'full-width-content';
    return $layout;
}

// Add .teaser class to every post, except first 2
add_filter('post_class', 'portsecond_post_class');
function portsecond_post_class( $classes ) {
    $classes[] = 'portsecond';
    return $classes;
}

// Modify length of post excerpts
add_filter('excerpt_length', 'custom_excerpt_length');
function custom_excerpt_length($length) {
    return 15; // pull first 15 words
}

// Add "View project" link
add_filter('the_excerpt', 'child_homepage_excerpt_filter');
function child_homepage_excerpt_filter( $text ) {
    return sprintf( '%s<a href="%s" class="more-link">%s</a>', $text, get_permalink(), __('View Project', 'crystal') );
}

// Remove post info and meta info
remove_action('genesis_after_post_content', 'genesis_post_meta');
remove_action('genesis_before_post_content', 'genesis_post_info');

// Move title above post image
remove_action('genesis_post_title', 'genesis_do_post_title');
add_action('genesis_post_content', 'genesis_do_post_title', 9);

// Remove default content for this Page Template
remove_action('genesis_post_content', 'genesis_do_post_image');
remove_action('genesis_post_content', 'genesis_do_post_content');

// Add Featured Image for the portsecond posts in this Page Template
add_action('genesis_post_content', 'crystal_portsecond_do_post_image');
function crystal_portsecond_do_post_image() {
    $img = genesis_get_image( array( 'format' => 'html', 'size' => 'Portsecond Thumbnail', 'attr' => array( 'class' => 'alignnone post-image' ) ) );
    printf( '<a href="%s" title="%s">%s</a>', get_permalink(), the_title_attribute('echo=0'), $img );
}

// Add Content for the portsecond posts in this Page Template
add_action('genesis_post_content', 'crystal_portsecond_do_post_content');
function crystal_portsecond_do_post_content() {
    
    if ( genesis_get_option('crystal_portsecond_content') == 'excerpts' ) {
        the_excerpt();
    
    } else {
        if ( genesis_get_option('crystal_portsecond_content_archive_limit') )
            the_content_limit( (int)genesis_get_option('crystal_portsecond_content_archive_limit'), __('View Project', 'crystal') );
        else
            the_content(__('View Project', 'crystal'));
    }
} 

// Clear float using genesis_custom_loop() $loop_counter variable
// Outputs clearing div after every 4 posts
// $loop_counter is incremented after this function is run
add_action('genesis_after_post', 'portsecond_after_post');
function portsecond_after_post() {
    global $loop_counter;
    
    if ( $loop_counter == 3 ) {
        $loop_counter = -1;
        echo '<div class="clear"></div>';
    }
}

// Remove standard loop
remove_action('genesis_loop', 'genesis_do_loop');

// Add custom loop
add_action('genesis_loop', 'portsecond_loop');
function portsecond_loop() {
    $paged = get_query_var('paged') ? get_query_var('paged') : 1;
    
    $include = genesis_get_option('crystal_portsecond_cat');
    $exclude = genesis_get_option('crystal_portsecond_cat_exclude') ? explode(',', str_replace(' ', '', genesis_get_option('crystal_portsecond_cat_exclude'))) : '';
        
    $cf = genesis_get_custom_field('query_args'); // Easter Egg
    $args = array('cat' => $include, 'category__not_in' => $exclude, 'showposts' => genesis_get_option('crystal_portsecond_cat_num'), 'paged' => $paged);
    $query_args = wp_parse_args($cf, $args);
    
    genesis_custom_loop( $query_args );
}

genesis();

CSS code

This is the CSS code which needs to be added at the end of the Crystal themes style.css file.

/***** Portsecond ********************/

#content .portsecond {
	width: 210px;
	margin: 0 15px 20px 15px !important;
	float: left;
	overflow: hidden;
	}
	
.page-template-pageportsecond-php #content .portsecond p {
	margin: 0;
	padding: 0;
	}
	
#content .portsecond .entry-title {
	font-size: 18px;
	margin: 10px 0 0 0;
	line-height: 22px;
	}

#content .portsecond .more-link {
	background: url(images/btn-more-bg.png) repeat-x top;
	width: 100px;
	display: block;
	padding: 5px 0 5px 0;
	margin: 10px 0 0 0;
	text-align: center;
	text-decoration: none;
	border-left: 1px solid #D4DBE1;
	border-right: 1px solid #D4DBE1;
	text-shadow: #FFFFFF 1px 1px;
	}
	
#content .portsecond .more-link:hover {
	background: url(images/btn-more-bg.png) repeat-x 0px -30px;
	border-left: 1px solid #D0D9E0;
	border-right: 1px solid #D0D9E0;
	}
	
#content .portsecond img {
	float: none;
	margin: 10px auto 10px;
	}

Code Not Displaying Correctly?

Grab all 3 code blocks from the view raw link on Github.

Note: There’s a lot of coding involved in creating portfolio style category archive pages, especially if you want to do this for all your categories. This code does work as you can see in the short screen cast at the top of the post so you will need to make sure you follow all the instructions precisely. More instructions on setting up the portfolio page are available on the StudioPress download page you’ll have access to once you own the Crystal child theme.

Comments

7 responses to “Create Multiple Portfolio Style Category Archive Pages in Crystal Theme”

  1. Can this be used for an artists group? There would be approximately 20 artist – and it would be possible that the artists would change over time. It seems like there would be too much code to add doing it this way, so is there another way?

    Thanks for your help.

    1. Brad Dalton Avatar
      Brad Dalton

      Hello Kris

      I suggest you use the portfolio page template and code from the Executive Pro theme as that code enables you to create multiple taxonomies.

  2. It works great too. Good work Brad!

    1. Brad Dalton Avatar
      Brad Dalton

      Thanks Corey.

      So much easier doing this with the Balance theme.

  3. Carolyn Yalin Avatar
    Carolyn Yalin

    This is great, and even more so since I’m using the Crystal theme and want additional portfolio pages!

    1. Brad Dalton Avatar
      Brad Dalton

      Took me a few hours to get this right as there’s so much coding involved its easy to miss renaming 1 function.

Leave a Reply

Join 5000+ Followers

Get The Latest Free & Premium Tutorials Delivered The Second They’re Published.