If you want custom fields in your single portfolio pages, but want different field types, download the Custom Metaboxes and Fields for WordPress files from github and read the instructions on the same page.
The zip file contains an example-functions.php file that has every kind of field you can think of; for example, you can create date picker fields, text fields, image upload fields; and or color picker fields.
- Download the the Custom Metaboxes and Fields for WordPress files from github.
- Unzip the Custom-Metaboxes-and-Fields-for-WordPress-master.zip file.
- In your Genesis child theme folder, create a folder called lib
- In the lib folder, create a folder called metabox
- Copy all the files from Custom-Metaboxes-and-Fields-for-WordPress-master.zip
to /wp-content/themes/your_theme/lib/metabox
- Add the following custom field code to your Genesis child theme functions.php file:
Note: This example is from my custom fields. You can modify it to suit your needs./** * Include and setup custom metaboxes and fields. * Contributors: * Andrew Norcross ( @norcross / andrewnorcross.com ) * Jared Atchison ( @jaredatch / jaredatchison.com ) * Bill Erickson ( @billerickson / billerickson.net ) * Justin Sternberg ( @jtsternberg / dsgnwrks.pro ) * * @category YourThemeOrPlugin * @package Metaboxes * @license http://www.opensource.org/licenses/gpl-license.php GPL v2.0 (or later) * @link https://github.com/jaredatch/Custom-Metaboxes-and-Fields-for-WordPress */ add_filter( 'cmb_meta_boxes', 'cmb_create_metaboxes' ); /** * Define the metabox and field configurations. * * @param array $meta_boxes * @return array * Start with an underscore to hide fields from custom fields list; eg, _port_wordpress */ function cmb_create_metaboxes( $meta_boxes ) { $meta_boxes[] = array( 'id' => 'rotator-options', 'title' => 'Portfolio Custom Fields', 'pages' => array('portfolio'), 'context' => 'normal', 'priority' => 'high', 'show_names' => true, 'fields' => array( array( 'name' => 'Site URL', 'desc' => '', 'id' => '_url', 'type' => 'text' ), array( 'name' => 'WordPress', 'desc' => '', 'id' => $prefix . '_port_wordpress', 'type' => 'checkbox', ), array( 'name' => 'Genesis', 'desc' => '', 'id' => $prefix . '_port_genesis', 'type' => 'checkbox', ), array( 'name' => 'Joomla', 'desc' => '', 'id' => $prefix . '_port_joomla', 'type' => 'checkbox', ), array( 'name' => 'YooTheme', 'desc' => '', 'id' => $prefix . '_port_yootheme', 'type' => 'checkbox', ), array( 'name' => 'CS-Cart', 'desc' => '', 'id' => $prefix . '_port_cscart', 'type' => 'checkbox', ), array( 'name' => 'X-Cart', 'desc' => '', 'id' => $prefix . '_port_xcart', 'type' => 'checkbox', ), ), ); return $meta_boxes; } add_action( 'init', 'cmb_initialize_cmb_meta_boxes', 9999 ); /** * Initialize the metabox class. */ function cmb_initialize_cmb_meta_boxes() { if ( ! class_exists( 'cmb_Meta_Box' ) ) require_once( CHILD_DIR . '/lib/metabox/init.php' ); } /** * From Nick the Geek: http://designsbynickthegeek.com/tutorials/how-i-make-custom-fields-easier * Gets the custom field value if available and places it in a defined pattern. * Place %value% where the custom field value should be if custom field is returned. * * @uses genesis_get_custom_field() * @param string $field the id of the custom field to check/retrieve. * @param string $wrap HTML to return if custom field is returned. * @param boolean $echo default false. echo wraped field value if available and set to true. * @returns string/boolean the custom field/wrap output or false if nothing * */ function min_custom_field( $field, $wrap = '%value%', $echo = false ){ $custom_wrap = false; if( $value = genesis_get_custom_field( $field ) ) $custom_wrap = str_replace( '%value%', $value, $wrap ); if( $echo && $custom_wrap ) echo $custom_wrap; return $custom_wrap; } add_action( 'genesis_entry_content', 'min_port_fields', 10 ); function min_port_fields() { if( ! is_singular('portfolio') ) return; ?> <div class="custom-fields"> <?php min_custom_field( '_url', '<h3>URL: <a href="%value%" rel="nofollow" target="_blank">%value%</a></h3>', true ); ?> <div class="built-with"><h3>Built with...</h3> <p> <?php min_custom_field( '_port_wordpress', '<a href="http://wordpress.org" rel="nofollow" target="_blank"><img src="'. get_stylesheet_directory_uri() . '/images/wordpress.png" width="150" height="90" /></a>', true ); min_custom_field( '_port_genesis', '<a href="http://studiopress.com" rel="nofollow" target="_blank"><img src="'. get_stylesheet_directory_uri() . '/images/genesis.png" width="150" height="90" /></a>', true ); min_custom_field( '_port_joomla', '<a href="http://joomla.org" rel="nofollow" target="_blank"><img src="'. get_stylesheet_directory_uri() . '/images/joomla.png" width="150" height="90" /></a>', true ); min_custom_field( '_port_yootheme', '<a href="http://yootheme.com" rel="nofollow" target="_blank"><img src="'. get_stylesheet_directory_uri() . '/images/yootheme.png" width="150" height="90" /></a>', true ); min_custom_field( '_port_cscart', '<a href="http://cs-cart.com" rel="nofollow" target="_blank"><img src="'. get_stylesheet_directory_uri() . '/images/cscart.png" width="150" height="90" /></a>', true ); min_custom_field( '_port_xcart', '<a href="http://x-cart.com" rel="nofollow" target="_blank"><img src="'. get_stylesheet_directory_uri() . '/images/xcart.png" width="150" height="90" /></a></p></div>', true ); ?> </div> <?php } // add previous next links to single portfolio pages function wpsites_npp_navigation_links() { if( 'portfolio' == get_post_type() && is_single() ) {?> <div class="portnav"> <?php next_post_link( '« %link', 'Previous in Portfolio' ); ?> | <?php previous_post_link('%link »', 'Next in Portfolio'); ?> </div> <?php } } /** * @author Brad Dalton * @learn more http://wp.me/p1lTu0-9YH * Note: I modified code because next_post and previous_post * have been depricated to next_post_link and previous_post_link */ /** * Add previous and next post links above the content; if you want it below the content, use genesis_entry_footer */ add_action('genesis_entry_header', 'wpsites_npp_navigation_links', 10 );
Configure the Genesis Portfolio Archive
From the WordPress admin menu select Portfolio > Archive Settings.
Here you can specify the following settings for the Portfolio Archive Page:
- Archive Title
- Archive Intro Text
- SEO Settings
- Layout Settings
Note: The Portfolio archive is already set to full width but you can change it here if you want.
Update Your Permalinks
Go to Settings > Permalinks and click Save. This is required because you added a custom post type.
That’s it. You’re done. You can now start adding portfolio pages.
Renee says
I very much appreciate you posting this code. I recently upgraded to WordPress 3.6 with Genesis 2.0.
Nathan Schmidt says
Thank you for this tutorial. I had been trying to do this using a portfolio custom post type from another Studiopress theme I have and it wouldn’t work. Looks like some of the hooks have changed in the new Genesis 2.0 framework, which seemed to be the issue. My portfolio is working well, now.
Would you have a recommendation on what to use to get the archive page to display the posts in a particular order based on the ‘order’ field in the custom post type? I originally used a custom field for ‘order’, but then I noticed that in WP, the ‘order’ field is already built in to the ‘attributes’ panel on the new post admin page. I used WP_query w/ an array in my archive-portfolio.php page to try to populate the posts by the ‘order’ I had designated, but I’m not having any luck.
Any help would be appreciated… even a link to some documentation. I find a lot of posts on utilizing WP_Query, but nothing recent enough or along the lines of incorporating into a Genesis (2.0) theme.
Pat Fortino says
Not sure how to sort by order field. There are plenty of plugins that do that; seems like that would be easiest.
Nathan Schmidt says
I found a way to do it after breaking it a lot. I tried w/ WP_Query kind of unsuccessfully, but eventually, adding this in after the function that outputs the page header and before the function that plots out the posts got it to do what I wanted:
query_posts( array( 'post_type'=>'product-categories' , 'orderby' => 'menu_order' , 'order' => 'ASC' ));
Also, I saw on another post from Carrie Dils that activated the archive-page settings if you wish to add in content prior to the post output on the archive post page.
I found this useful, as well. Basically, in the function registering the custom-post-type, you add in:
‘genesis-cpt-archives-settings’ into the register_post_type function’s array where ‘supports’ are listed.
I found this to be a pretty cool baked in feature for Genesis 2.0
Pat Fortino says
Hi Nathan. Thanks for the update. I forgot about the genesis-cpt-archives-settings. I’m going to update my portfolio tutorial to include it since it makes adding a title or description to the ctp archive much easier.
Regarding your comment:
Not sure I understand what you mean. I don’t see any order field or option for it in the posts screen? Is this something you added using a plugin?
Nathan Schmidt says
I have to correct that earlier statement. The page attributes panel is only located in the ‘page’ screen when making or editing a page, not post (located in panel to the right of the description field). I hadn’t realized that the tutorial made the custom post type more of a page layout rather than post, but it looks like by adding the ‘page_attributes’ in the ‘supports’ array in the registering function (in function.php), it adds this behavior.
I suppose if you wanted to order posts in this manner, you could use a custom field and then integrate that into the query. This is likely why it wasn’t working before—I was trying to query posts rather than perhaps using something w/ page attributes. I hadn’t noticed this behavior until you brought this up. Now, I realize why it takes on the page attributes.
Pat Fortino says
Nathan. Thanks for that clarification.
WriteNoWrong says
Awesome tutorial! I know this wasn’t really covered, but how would you suggest going about adding custom taxonomies to said Custom Post Types and then presenting them?
Pat Fortino says
The current code has taxonomies for tags. If you want categories, add category to taxonimies. See below.
‘taxonomies’ => array( ‘category’, ‘post_tag’ ),
WriteNoWrong says
So say if I registered a custom taxonomy called “location.” I could theoretically just add that into the taxonomies line and it would present that data on the custom post type posting?
‘taxonomies’ => array( ‘location’, ‘category’, ‘post_tag’ ),
Pat Fortino says
In order to create a custom taxonomy, you need to register it. See this url for explanation: http://codex.wordpress.org/Taxonomies