So in Genesis 1.8, you will be able to designate layouts for various parts of the site, including various post types. While in Genesis 1.8, this is a bit more convoluted than necessary, it is an appropriate small step towards the right direction to expanding and improving site layouts. To do this you will need to follow these steps:
- Register your layouts for that post type
- Adjust builtin layouts for that post type
- Re-Create the Meta Box for the custom post type
Now, in future versions of Genesis re-creating the metabox won't be necessary (hopefully) and there will be other extensions and features as well.
Register your layouts for that post type
So we first need to register the layout. In this example, we are going to assume that our post type is registered correctly to support, genesis-layouts. If layouts do not appear, you can simply add this line to your functions.php: add_post_type_support( 'my-services', 'genesis-layouts' );
.
[php]
add_action( 'init' , 'wps_create_initial_layouts' );
/**
* Registers Genesis custom post type default layouts.
*
*/
function wps_create_initial_layouts() {
genesis_register_layout( 'top-sidebar', array(
'label' => __( 'Top Sidebar', CHILD_DOMAIN ),
'img' => WPS_LAYOUTS . '/top-sidebar.PNG',
'type' => 'wps_employee',
) );
genesis_register_layout( 'bottom-sidebar', array(
'label' => __( 'Bottom Sidebar', CHILD_DOMAIN ),
'img' => WPS_LAYOUTS . '/bottom-sidebar.PNG',
'type' => 'wps_employee',
) );
}
[/php]
Adjust builtin layouts for that post type
If you want to include the standard types, you will need to add the following:
[php]
add_action( 'admin_init', 'genesis_fix_initial_layouts' );
/**
* Fixes registered initial layouts to be added to a specific post type.
* Genesis comes with 6 layouts registered by default. These are:
* - content-sidebar (default)
* - sidebar-content
* - content-sidebar-sidebar
* - sidebar-sidebar-content
* - sidebar-content-sidebar
* - full-width-content
*
* @uses global $_genesis_layouts
* @author Travis Smith
*/
function genesis_fix_initial_layouts () {
global $_genesis_layouts;
$post_type = isset ( $_GET['post_type'] ) ? $_GET['post_type'] : 'post';
if ( $post_type == 'wps_employee' ) {
// remove from the array as you see appropriate
$_builtin_layouts = array (
'content-sidebar',
'sidebar-content',
'content-sidebar-sidebar',
//'sidebar-sidebar-content',
'sidebar-content-sidebar',
'full-width-content'
);
foreach ( $_builtin_layouts as $layout) {
$_genesis_layouts[$layout]['type'] = 'wps_employee';
}
}
}
[/php]
The code above only changes the builtin layouts to the appropriate custom post type if on that page. If you have multiple custom post types you could do something like this:
[php]
add_action( 'admin_init', 'genesis_fix_initial_layouts' );
/**
* Fixes registered initial layouts to be added to a specific post type.
*
* @uses global $_genesis_layouts
* @author Travis Smith
*/
function genesis_fix_initial_layouts () {
global $_genesis_layouts;
$post_type = isset ( $_GET['post_type'] ) ? $_GET['post_type'] : 'post';
switch ( $post_type ) {
case ( 'wps_employee' ) :
// remove from the array as you see appropriate
$_builtin_layouts = array (
'content-sidebar',
'sidebar-content',
'content-sidebar-sidebar',
//'sidebar-sidebar-content',
'sidebar-content-sidebar',
'full-width-content'
);
break;
case ( 'my-services' ) :
// remove from the array as you see appropriate
$_builtin_layouts = array (
'content-sidebar',
'sidebar-content',
//'content-sidebar-sidebar',
//'sidebar-sidebar-content',
//'sidebar-content-sidebar',
//'full-width-content'
);
break;
default:
$_builtin_layouts = array ();
break;
}
foreach ( $_builtin_layouts as $layout) {
$_genesis_layouts[$layout]['type'] = $post_type;
}
}[/php]
Re-Create the Meta Box for the custom post type
Since there are plans to extend the use of type in genesis_layout_selector()
, adding a filter, while a great idea and dramatically reduces this code, will most likely deprecate after only one version. So, please bear with me.
[php]
add_action( 'admin_menu', 'genesis_customize_inpost_layout_box' );
/**
* Remove the builtin meta box for specific post types & Register a new meta box to the
* post / page edit screen, so that the user can
* set layout options on a per-post or per-page basis with custom genesis_inpost_layout_box().
*
* @see genesis_inpost_layout_box() Generates the content in the boxes
* @author Travis Smith
* @return null Returns null if Genesis layouts are not supported
*/
function genesis_customize_inpost_layout_box() {
if ( ! current_theme_supports( 'genesis-inpost-layouts' ) )
return;
foreach ( (array) get_post_types( array( 'public' => true ) ) as $type ) {
if ( post_type_supports( $type, 'genesis-layouts' ) ) {
if ( $type == 'wps_employee' ) {
// Remove builtin metabox
remove_meta_box( 'genesis_inpost_layout_box', $type, 'normal' );
// Add custom metabox
add_meta_box( 'genesis_inpost_layout_box', __( 'Layout Settings', 'genesis' ), 'wps_inpost_layout_box', $type, 'normal', 'high' );
}
}
}
}
/**
* Callback for custom in-post layout meta box.
*
* Echoes out HTML.
*
* @author Travis Smith
*/
function wps_inpost_layout_box() {
$post_type = isset ( $_GET['post_type'] ) ? $_GET['post_type'] : 'post';
wp_nonce_field( plugin_basename( __FILE__ ), 'genesis_inpost_layout_nonce' );
$layout = genesis_get_custom_field( '_genesis_layout' );
?>
<div class="genesis-layout-selector">
<p><input type="radio" name="_genesis_layout" id="default-layout" value="" <?php checked( $layout, '' ); ?> /> <label class="default" for="default-layout"><?php printf( __( 'Default Layout set in <a href="%s">Theme Settings</a>', 'genesis' ), menu_page_url( 'genesis', 0 ) ); ?></label></p>
<p><?php genesis_layout_selector( array( 'name' => '_genesis_layout', 'selected' => $layout, 'type' => $post_type ) ); ?></p>
</div>
<br class="clear" />
<p><label for="genesis_custom_body_class"><b><?php _e( 'Custom Body Class', 'genesis' ); ?></b></label></p>
<p><input class="large-text" type="text" name="_genesis_custom_body_class" id="genesis_custom_body_class" value="<?php echo esc_attr( sanitize_html_class( genesis_get_custom_field( '_genesis_custom_body_class' ) ) ); ?>" /></p>
<p><label for="genesis_custom_post_class"><b><?php _e( 'Custom Post Class', 'genesis' ); ?></b></label></p>
<p><input class="large-text" type="text" name="_genesis_custom_post_class" id="genesis_custom_post_class" value="<?php echo esc_attr( sanitize_html_class( genesis_get_custom_field( '_genesis_custom_post_class' ) ) ); ?>" /></p>
<?php
}
[/php]
Now you have specific layouts only available for specific post types!! Enjoy!
Adam W. Warner says
Hi Travis, if I understand the outcome correctly, this is indeed a great step toward customizing the layouts of different post types for sections of Genesis powered sites.
It would be great to see some examples, a few screenshots perhaps?
I THINK I’m accomplishing something similar with the Views plugin I just purchased. It’s a partner plugin to the free Types plugin. Types allows a user to easily create CPTs and Views allows you to query and display CPTs.
(p.s. I am not affiliated with these plugins, I just purchased and started experimenting with Views to fill a need I had to display the Simple URLs CPT in a certain way.)
With Simple URLs I manage all the affiliate links on our site and with Views, I was able to create a “Recommended Products” page that outputs the Simple URLs CPT (surls) into a page in three columns. You can see here.
This is still a work in progress, here’s why…I have also added a function that adds the Excerpt and Featured Image to the Simple URL edit page…I then can choose to display those two things in my Views output on that page. In testing, it looks pretty nice and allows us to have recommended products, in a three (or two, etc.) column layout complete with a description and image.
The one thing I haven’t figured out just yet is getting the featured image set to a size that works for my layout. I /,a href=”http://www.studiopress.com/support/showthread.php?t=87780″>posted on the StudioPress forums and Nick the Geek answered that I would need to “write a custom image function and call for the other image size in that function”…
I’m not quite sure how to do that…and…not sure how I would incorporate that into my existing function that adds the featured image to my surls. I’ll be trying though;)
Anyway, your post got me thinking and I thought I’d share how I am currently solving this CPT custom layout issue for our site.
Bharat Chowdary says
Thanks smith for this code, have been searching for a while and finally here it is.
Tho Huynh says
Thank you so much 🙂 The post tell exactly what I have to do for my new project with custom post types