Plug-in now available – Download: Genesis Post Teasers
The code below will add a box under Genesis > Theme Settings to enable or disable teaser boxes and after how many posts do you wish to be displayed in full before the teaser boxes.
* NOTE: I can’t promise this code will work for everyone or that it is perfect. Feel free to ask questions in the comments section below. I also encourage fixes/updates to the code as well.
Scroll to end of post for screen shots.
// add actions and filters to only the home page for the teasers. // if your blog isn't on the home page swap out "is_home()" to where your blog may be. // for example: is_page_template('blog.php') add_action('wp', 'enable_post_teaser_logic'); function enable_post_teaser_logic() { if( genesis_get_option('teasers_enable') == 1 ) { if (is_home() ) { remove_action('genesis_post_content','genesis_do_post_content'); add_action('genesis_post_content','genesis_do_teaser_content'); add_action('genesis_before_post','post_teaser_do_open', 10, 2); add_action('genesis_before_post','post_teaser_pertwo_wrap_open', 15, 2); add_action('genesis_after_post','post_teaser_pertwo_wrap_openclose'); add_action('genesis_after_endwhile','post_teaser_pertwo_wrap_close', 5, 2); add_action('genesis_after_endwhile','post_teaser_do_close', 6, 2); add_filter('genesis_options', 'define_content_archive_home_setting', 10, 2); add_filter('post_class', 'add_oddeven_class'); if( genesis_get_option('disable_teaser_meta') == 1 ) { remove_action('genesis_after_post_content', 'genesis_post_meta'); add_filter('genesis_after_post_content', 'genesis_post_meta_teaser_logic'); } } } } // adds a class of odd-post or even-post // to the post class depending on the count of the loop. function add_oddeven_class($classes){ global $post, $loop_counter; $oddeven = ($loop_counter&1) ? "odd-post" : "even-post"; $classes[] = $oddeven; return $classes; } // This makes sure the_content is shown as default on homepage. function define_content_archive_home_setting($options, $setting) { if($setting == GENESIS_SETTINGS_FIELD) { $options['content_archive'] = 'full'; } return $options; } // Makes the teaser use the excerpt. function genesis_do_teaser_content() { global $loop_counter; if( $loop_counter >= genesis_get_option('numof_full_posts') || is_paged() >= 2 ) { the_excerpt(); if ( genesis_get_option('readmore_on_teasers') == 1 ) { echo'<a class="more-link" href="'.get_permalink().'">[Read more...]</a>'; } } else { the_content(__('[Read more...]', 'genesis')); } } // This will remove post meta on teaser posts function genesis_post_meta_teaser_logic() { global $loop_counter; if ( is_page() || $loop_counter >= genesis_get_option('numof_full_posts') || is_paged() >= 2 ) return; // don't do post-meta on pages or teasers $post_meta = ' '; printf( ' <div class="post-meta">%s</div> ', apply_filters('genesis_post_meta', $post_meta) ); } // Wraps the post teaser area with its own div. function post_teaser_do_open() { global $loop_counter; if( !is_paged() && $loop_counter == genesis_get_option('numof_full_posts') || is_paged() >= 2 && $loop_counter == 0) { echo ' <div id="post-teasers">'; } } //Opens the div for the first pair of teasers. This helps to keep the area of two //the same height so can have a flexible height for the teasers. function post_teaser_pertwo_wrap_open() { global $loop_counter; if( !is_paged() && $loop_counter == genesis_get_option('numof_full_posts') || is_paged() >= 2 && $loop_counter == 0) { echo ' <div class="post-teasers-pair">'; } } // Wraps the a pair of teasers with their own div. This helps to keep the area of two //the same height so can have a flexible height for the teasers. function post_teaser_pertwo_wrap_openclose() { global $loop_counter, $posts; if( $loop_counter == get_option('posts_per_page' )-1 || $loop_counter == sizeof($posts)-1 ) return; if( !is_paged() && $loop_counter > genesis_get_option('numof_full_posts') && $loop_counter % 2 || is_paged() >= 2 && $loop_counter % 2) { echo '</div> <div class="post-teasers-pair">'; } } // Closing div to teaser pairs. function post_teaser_pertwo_wrap_close() { global $loop_counter; if( $loop_counter >= genesis_get_option('numof_full_posts') || is_paged() >= 2 ) { echo '</div> '; } } // Closing div to post teaser area. function post_teaser_do_close() { global $loop_counter; if( $loop_counter >= genesis_get_option('numof_full_posts') || is_paged() >= 2 ) { echo '</div> '; } } // Code below adds the setting box in Genesis Settings. // This box allows you to set how many full posts to display // and to use teaser or not. // If enable teasers is not checked none the previous code will run. add_action('admin_menu', 'teaser_settings_init'); function teaser_settings_init() { global $_genesis_theme_settings_pagehook; add_action('load-'.$_genesis_theme_settings_pagehook, 'teaser_settings_boxes'); } function teaser_settings_boxes() { global $_genesis_theme_settings_pagehook; add_meta_box('teaser_settings_box', 'Homepage Teasers', 'teaser_settings_box', $_genesis_theme_settings_pagehook, 'column2', 'high'); } function teaser_settings_box() { ?> <input id="<?php echo GENESIS_SETTINGS_FIELD; ?>[teasers_enable]" name="<?php echo GENESIS_SETTINGS_FIELD; ?>[teasers_enable]" type="checkbox" value="1" /> /> <label for="<?php echo GENESIS_SETTINGS_FIELD; ?>[teasers_enable]"><!--?php _e('Enable teasers on home page?', 'genesis'); ?--></label> <input id="<?php echo GENESIS_SETTINGS_FIELD; ?>[disable_teaser_meta]" name="<?php echo GENESIS_SETTINGS_FIELD; ?>[disable_teaser_meta]" type="checkbox" value="1" /> /> <label for="<?php echo GENESIS_SETTINGS_FIELD; ?>[disable_teaser_meta]"><!--?php _e('Disable post meta on teasers?', 'genesis'); ?--></label> <input id="<?php echo GENESIS_SETTINGS_FIELD; ?>[readmore_on_teasers]" name="<?php echo GENESIS_SETTINGS_FIELD; ?>[readmore_on_teasers]" type="checkbox" value="1" /> /> <label for="<?php echo GENESIS_SETTINGS_FIELD; ?>[readmore_on_teasers]"><!--?php _e('Display Read More link on teasers?', 'genesis'); ?--></label> <hr class="div" /> <!--?php echo "How many full posts before teaser?"; ?--> <input name="<?php echo GENESIS_SETTINGS_FIELD; ?>[numof_full_posts]" size="1" type="text" value="<?php echo esc_attr( genesis_get_option('numof_full_posts') ); ?>" /> <span class="description"><strong>NOTE:</strong> To change the number of posts displayed navigate to Settings > Reading. Default value is 10. </span> <!--?php<br /-->}
This CSS is just included as an example. Do note depending on how many full posts are displayed above the styles may need to be swapped for .odd-post and .even-post.
#post-teasers, .post-teasers-pair { clear:both; } #post-teasers .odd-post { float:left; width:300px; } #post-teasers .even-post { float:right; width:300px; }
Updates:
- Sept., 27, 2010: Added support to disable post meta on teasers. Bug Fix: Description may not append to title on homepage.
- Oct., 14, 2010: Added a div that wraps the teaser pairs. Added read more option to teasers. Naming of functions and divs changed. Updated CSS. Bug Fix: Page navigation was included in post teaser div.
- Oct., 18, 2010: Bug Fix: Empty post teaser div at end.
- Oct., 25, 2010: Bug Fix: Filed Under and tags didn’t display properly if disabled on teasers..
Plug-in now available – Download: Genesis Post Teasers
Marco says
Gotta check it this afternoon. Great Job!
Jacques says
Current bugs with the code shown above:
Navigation disappears.
Post pages show double sidebars, even if default genesis layout is one sidebar.
Other than that, really liking it. Going to try the code with the blog template selected rather than home.
Christopher says
Not really sure why the header would disappear and looking at your functions.php I don’t see anything wrong. I can’t reproduce the double sidebars either.
What genesis version are you running and have you modified any genesis parent theme files?
A bug I did find and now fixed:
On paged pages the sidebar will go underneath the content. Just pushed an update to the current code for that and sidebars should show correctly on the second and following pages.
Jacques says
Yeah, it’s definitely odd.
I’m running the latest version of Genesis (1.3.1 I think) without any modifications to the parent theme files at all.
Another thing I noticed was that the pagination was appearing near the topmost right block, as opposed to being at the bottom.
I’ll try out the new code and see how it works out.
Jacques says
The navigation appears to be fixed in the latest version and is working well.
Likewise, the sidebars are now working fine.
The only problem left is the pagination appearing near the top, presumably because it’s still being called after the standard post content, rather than after the teasers.
Christopher says
Make sure you also include the new css. The clears will fix that issue.
Jacques says
Still having the pagination issue with the new code.
Jacques says
And, something new:
“Warning: Cannot modify header information – headers already sent by (output started at /mounted-storage/home14c/sub001/sc65265-KSJP/www/wp-content/themes/child/functions.php:129) in /mounted-storage/home14c/sub001/sc65265-KSJP/www/wp-includes/pluggable.php on line 890”
I get this error when trying to access iamacyborg.com/blog ,strangely iamacyborg.com/blog/ works fine. I also can’t login to the admin cp.
GaryJ says
Nice work Chris!
How about the option to choose how many teasers go across horizontally? That way, 3 teasers could be used, say, for a full width layout, etc.
Have you pushed this on the Genesis Dev board as a potential inclusion into core?
Christopher says
Thanks Gary!
Those options are in a child theme I’m building ;). Someone asked via the tutorial submit box for code to do this so I thought I’d let it be available. However with the code above you can achieve three boxes on full width with a quick CSS change. Rid of the odd-post even-post CSS and replace with something below. ( I should have done something like below for the original CSS, allows more flexibility. Was tired though :p )
About the dev board I have not. I will take a look though.
GaryJ says
I reckon something like this would be core-worthy (if you’re happy to submit it), but in the meantime, there’s also enough there for it to be a plugin?