Three Teasers Per Row Without Hacking Thesis

by Russell on July 14, 2010 · 15 comments

in how tos,thesis

Transforming Two Thesis Teasers Per Row To Three Teasers Per Row

As promised this is the non-hack solution to 3 teasers per row problem which involves only changes to custom_functions.php and custom.css- no changes to Thesis core code are required. This version should therefore survive upgrades to Thesis.

The solution uses jQuery and applies a simple algorithm. Firstly, remember that Thesis makes a ‘teaser box’ for each row and puts two teasers in each teaser box. My goal is to have 3 teasers in each teaser box.

Algorithm To Put Three Teasers in Each Teaser Box

The jQuery below processes every third teaser box starting at the second box and

  • copies the first teaser into the previous teaser box
  • copies the second teaser into the next teaser box
  • removes the teaser box

The PHP code below is set up to have 3 teasers per row on the home page and 1 teaser per row on archive pages. Where we have 3 teasers per row it also shortens the post titles at the last complete word in the title to avoid wrapping text across multiple lines.

Also CSS is used to set the width of each teaser and on the home page to suppress the teaser text to leave just the title and the thumbnail image.

function add_jquery_stuff () {
 if (is_front_page()) {
?>
<script type="text/javascript">
function shorten(sometext,maxlen) {
  if (sometext.length<=maxlen) return sometext;
  var s = sometext.substr(0,maxlen);
  return (s.lastIndexOf(" ")<1?s:s.substr(0,s.lastIndexOf(" ")))+"...";
}
</script>
<script type="text/javascript">
jQuery(document).ready( function () {
  jQuery('.teaser').each(function(index) {
     if ((index % 6) == 2) {
         jQuery(this).clone().appendTo(jQuery(this).parent().prev());
     }
     if ((index % 6) == 3) {
         jQuery(this).clone().prependTo(jQuery(this).parent().next());
     }
  });
  jQuery('.teasers_box').each(function(index) {
     if ((index % 3) == 1) {
         jQuery(this).empty().remove();
     }
  });
 jQuery('.teaser').each(function(index){
    jQuery(this).addClass('teaser3').removeClass("teaser_right"); //3 teasers per row on home page
  });
 //shorten titles
 jQuery('.teaser a[rel=bookmark]').each(function(index){
    var t = jQuery(this).text();
    jQuery(this).text(shorten(t,24));
  });
});
</script>
<?php
 }

if ( is_archive()) {
?>
<script type="text/javascript">
jQuery(document).ready( function () {
  jQuery('.teaser').each(function(index){
    jQuery(this).addClass('teaser1');  //one teaser per row on archive pages
  });
});
</script>
<php
  }
}
add_action('wp_head','add_jquery_stuff');

As with the earlier examples we tweak the CSS with classes teaser1 and teaser3 for where we want 1 and 3 teasers per row respectively. You need to set these widths according to the width of your page.

.custom .teaser1 { width: 55em; }
.custom .teaser3 { width: 193px; padding-right:6px; }
.custom .teaser3 .format_teaser p { display : none }

The last line in the CSS hides the text – the client just wanted to display an image as the teaser on the home page where we have 3 teasers per row.

Sample Home Page Teasers

Sample Archive Page Teasers

Potential Issue with thesis_hook_before_teasers_box Hook

I have not tested this solution where the ‘thesis_hook_before_teasers_box’ hook is being used. This badly named hook actually inserts content at the start of the teaser box before the first teaser rather than before the teaser box as its name suggests. I suspect that my solution will not work well if you use this hook.

If anyone has a problem with this jQuery solution please email me and will add a fix to handle this scenario – unless Chris Pearson decides to change the ‘thesis_hook_before_teasers_box’ hook to run before the teaser box first.

Google Buzz
Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks

{ 15 comments… read them below or add one }

Remko August 15, 2010 at 8:58 pm

Hi Russell,

I’m trying you’re code on my website (www.4000schoenen.nl) but I get the message:

Parse error: syntax error, unexpected ‘%’ in /home/uqtmzofh/domains/4000schoenen.nl/public_html/wp-content/themes/thesis_17/custom/custom_functions.php on line 90

My php skills are poor, so I hope you can give me some help on this?

p.s. Line 90 is line 03 from your code.

Thanks in advance!

Russell August 16, 2010 at 9:21 am

Hi Remko,

Thanks for your question.

I have my PHP.ini settings with asp_tags=”On” which allows me to use <% instead of <?php.

I will update the article right now to use the more standard notation.

Thanks

Russell

Remko August 16, 2010 at 2:34 pm

Hi Russell,

Sometimes things are so simple… :) Never thought of asp_tags=”On”

Thanks!

Remko August 17, 2010 at 4:24 pm

Hi Russell,

I’ve got the code working on http://www.4000schoenen.nl, but still have a problem.

First , the code in the article is missing a closing statement ?> after the last line. BUt I’ve got that fixed. :)

More important, if you look at the website you’ll see that it looks like the code is forcing 3 teasers per teaserbox. But I don’t have a clue why he don’t put the third one after the second teaser. I have set the maximum width to 125px (also tried 55px) and it seems there’s enough space after two teasers.

I would be great if you could find some time to help me solve this issue! Thanks in advance!

Remko

Russell August 17, 2010 at 5:37 pm

Hi Remko

Your site is giving the following message right now. Please let me know when I can take a look:

Warning: Cannot modify header information – headers already sent by (output started at /home/uqtmzofh/domains/4000schoenen.nl/public_html/wp-content/themes/thesis_17/custom/custom_functions.php:142) in /home/uqtmzofh/domains/4000schoenen.nl/public_html/wp-includes/pluggable.php on line 890

Russell August 17, 2010 at 6:09 pm

HI Remko,

Re: “The code in the article is missing a closing statement ?> after the last line”. Apologies for this and any problems it caused.

In my custom_functions.php file the code appears at the bottom of the file so in this special case missing off the last ?> is good practice.

Regards

Russell

Remko August 17, 2010 at 6:45 pm

Hi Russell,

Strange, I did get this message earlier today fixing the above problem, but now when I open the site in IE, FF or Chrome it seem to work. I’ve deleted the browser history and it seems to work.

Can you please look again?
Thanks,
Remko

Russell August 17, 2010 at 6:57 pm

Just looked in Firefox for the first time and got the same error.

It indicates you are writing output at line 142 of custom_functions.php.

Make sure that you have no characters at all after the last “?>”, not even a new line

Remko August 17, 2010 at 7:01 pm

Once again, you’re right. There were 2 enters at the end of custom_functions.php. I’ve deleted them and line 140 is now the last one… :)

Thanks!

Russell August 17, 2010 at 8:00 pm

I am seeing the Ugg boots now – My wife bought a pair of Ugg boots from QVC a few months back – she loves them.

I think the issue is down to the horizontal dotted lines which are paragraphs that are wrapping themselves around the divs.

<p style=”border-bottom: 1px dotted #cccccc;”>

Can you get rid of the dotted lines for now?

If we get the 3 teasers per row working we can look at putting them back in using CSS to specify the bottom-border of the teaser box

This is better than having a separate paragraph in any case.

Remko August 17, 2010 at 8:41 pm

I’ve removed the dotted line and that solves te problem, but not completly. If you now look at the homepage, you’ll see that the first two rows seem ok. But after the third row only contains two teasers.

I think that a part of the problem is that the images have a different heights, but why there’re two teasers in stead of three….

The best thing would be if every new row will start at the position of longest teaser in the previous row. This would probably result in ‘equal’ rows. The same goes for the ‘read more’ buttons that are now all on a different height in stead of on a straight line.

Any suggestions? And once again, thanks!!

Russell August 17, 2010 at 9:18 pm

Many Apologies Remko, you have identified a bug in my code.

Rather than


if ((index % 2) == 1) { jQuery(this).empty().remove(); }

It should be


if ((index % 3) == 1) { jQuery(this).empty().remove(); }

Please change the 2 to 3 and hopefully it will work correctly.

Remko August 17, 2010 at 10:45 pm

Don’t apologize, it’s your code/word that is helping me big time! Kudos to you!

The adjustment is doing his work. All the rows now contain 3 teasers! The only ‘problem’ that I now have is that because all images have a different height some rows (for example the 5th row on the homepage) is a little ‘messy’.

Can you think of any way where I can get AND the headlines (they are out of the box) AND the ‘read more links’ on the same height for each row? So when in 1 row there are 3 images with a height of, lets say, 100, 150 and 200, that the read more links will be positioned based on the height of the 200 image?

I’ve started a topic a couple of day ago on the thesis forum (http://diythemes.com/forums/showthread.php?36090-Alignment-of-the-read-more-links) and have given a ‘simple’ work around, but that will only work when the headline is above the image. I’ve moved the image above the headline in the thesis design menu, and now it looks like this solution won’t work any more…

THX!

Russell August 18, 2010 at 3:03 pm

Hi Remko

Sorry I don’t have time to look at this in detail – other than suggesting that you set all the image heights to 150 say.

This could be done by brute force using jQuery if necessary.

From what I have seen most of your images are 140 through to 200 so rescaling all to 150px would probably be acceptable.

Remko August 19, 2010 at 7:18 am

Hi Russel,

No problem at all. I will now start working on some other improvements and will look later on to the image issue. If I find anything useful I will let you know.

Thanks for the help!!

Leave a Comment

CommentLuv Enabled

Spam Protection by WP-SpamFree

Previous post:

Next post: