Fancy WordPress loop with main posts and then grid of post in rows

Here’s how I managed to get this loop to work for the custom WordPress theme I whacked off for my friend and erstwhile colleague Phil Morse AKA Digital DJ Tips

The challenge I set myself was to get the loop to display posts in two formats: first a certain number of posts with large excerpts and any images via the_content then a grid of 3 rows of mini-posts showing just the title… it may not sound tricky but the devil is in the detail: stepping in and out of the loop to open and close container divs is not widely documented (well not that I could find)…

Couple of catches

  • using multiple loop solutions causes the pagination to fail: link to older posts would reload the same content. To get proper pagination you need to stick with one loop.
  • I needed to inject some HTML in and around the mini posts to keep formatting and layout controllable:
    • need to add a class of “last” on the last item in a row to make use of the full width available with margin right on all except the last element of the row
    • beware the dreaded...

      each row of x mini-posts had to be wrapped in a div as these mini-posts are of unequal height (a design decision). With uneven heights floating them all within a single div causes the dreaded float-stack-horror.
  • As we’re injecting extra HTML markup every x items we also need to be able to close this markup prematurely if we run out of posts before the row is finished. Therefore we need to know the total number of posts in the loop so this thing can close itself early if need be.

In the end I also decided that I wanted the logic to be easily adaptable to allow changes to the number of full excerpt posts and the number of columns in the following rows. Thats easily changed with the variable set at the outset here and by varying the denominator in the integer test bit (simplerer than it sounds).

Cut-n-paste to the chase already…

</span>
<pre><?php

get_header(); ?>

	<div id="content">

	<?php if (have_posts()) : ?>
	<?php
		/* Custom loop to show n main posts (title + excerpt) then
		   finish with remainder as small posts (just title) in markup that allows
		   columns of unequal mini-posts in rows.

		   Here one main post then subsequent mini-posts in rows of 3.
		   Total number per page defined in WP options

		*/
 		$count = 0; //start the counter
		$main_posts = 1; //set the number of main posts
	?>

	<?php // find out how many posts so we can close this thing properly at the last post
	$totalposts = sizeof($posts); ?>

	<?php while (have_posts()) : the_post(); ?>
	<?php $count++; //increment counter by 1 ?>
	<?php $small_posts_count = ($count - $main_posts) ; // calculate the number of small posts ?>
	  <?php if ($count < ($main_posts + 1)) : // if within the range of main post set above then...  ?>
				<div <?php post_class('sheet') ?> id="post-<?php the_ID(); ?>">
					<h2><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
					<div class="entry">
						<?php the_content('Read more') ; ?>
					</div>
				</div>
		<?php else : // if loop is at small_posts start a wrapper div.loop2 for next row of posts ?>
			<?php // if (count-1)/3 is an integer then it's first in the row: open the wrapper
				if (($small_posts_count - 1) % 3 == 0 ) { echo '<div class="loop2 clearfix">';} ?>
				<div class="sheet<?php if ((isset($small_posts_count)) && ($small_posts_count % 3 == 0 )) { echo ' last';} // same logic to add class of last to last item in row of three ?>" id="post-<?php the_ID(); ?>">
					<h4><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?></a></h4>
				</div>
			<?php //close the row if multiple of three (using same logic as above) or if it's the last post
				if (($count == $totalposts) || ($small_posts_count % 3 == 0 )) { echo '</div><!-- .loop2 -->';} // if is multiple of three ?>

	  <?php endif; ?>

		<?php endwhile; ?>

		<?php if (!is_page()) { // get older and/or newer posts links (not for single posts) ?>
		<?php include( TEMPLATEPATH . '/tpl.nav.posts.php' );  ?>
		<?php ; } ?>

		<?php else : ?>
		<?php include( TEMPLATEPATH . '/tpl.search.404.php' ); // get 404 error message ?>
	<?php endif; ?>

	</div>

<?php get_sidebar(); ?>

<?php get_footer(); ?>

,

No Comments

Long/short headings (or title tags) using WordPress Custom Fields

Problem: WP titles are too long to fit in your navigation.

Solution:

Make the title short enough to fit in the navigation and then add a Custom Field into your post (in the example bellow it is set as “heading”) then edit your template file to render the longer version (“heading”) on the page.

Example:

In the Loop of  your template swap out

<h1><?php the_title(); ?></h1>
<?php the_content(); ?>

for:

<h1><?php// If has a custom field of heading ; then use that:
$customField = get_post_custom_values("heading");
if (isset($customField[0])) {
echo $customField[0];
} else {
the_title();
} ; ?></h1>
<?php the_content(); ?>

Hat-tip: Smashing Magazine

,

No Comments

Mac’s Apache web server crashing out

Spent a few hours yesterday try to fix my localhost web sharing. After a restart none of my local sites were responding, neither from my user account nor the back-up admin account.

This error message kept showing up in my Console:
com.apple.launchd[1] (org.apache.httpd[790]) Exited with exit code: 1

Followed a lengthy process to discount disk errors – (finding and fixing some serious ones) then a clean install and update of the system. Yeuch.

In the end it turns out to have been an error in the latest addition to my virtualhosts in /etc/apache2/virtualhosts. No error in the contents (created by the excellent virtualhost.sh script) – but something wrong with the file or its permissions or gawd knows what.

Obscure, strange and particularly annoying when a deadline is looming. Nevermind – next time I know to temporarily disable any virtualhosts when trying to find out what has killed my Apache server.

, , ,

No Comments

How to show just sticky posts in a WordPress template

Want to just show just your sticky posts in a WordPress template? This guide tells you how (and much more) – but you’re hacking a theme and are stuck when it says “add this code before the loop” – well the loop is the bit that starts  if (have_posts()). In the below example – how to when hackingh the soon-to-be-defunct default Kubric theme.

Add the following

< ?php

// this line just get the sticky posts:
query_posts(array('post__in'=>get_option('sticky_posts')));

// The Loop:
if (have_posts()) : ?>
<?php while (have_posts()) : the_post(); ?>

No Comments

Include an HTML file in a PHP variable

I couldn’t get PHP to accept an HTML file include as the definition of a variable without throwing my templated page into disarray.  An answer came from the venerable desilva then checked with the php folk; use output  buffering (see example six in that last link):

<?php
$string = get_include_contents('somefile.php');

function get_include_contents($filename) {
 if (is_file($filename)) {
 ob_start();
 include $filename;
 $contents = ob_get_contents();
 ob_end_clean();
 return $contents;
 }
 return false;
}

?>

Also worth a look: file_get_contents

Why? Because Coda, my favourite Macintosh text editor+,  doesn’t do syntax highlighting of HTML for a PHP string. The site I’ve just finished for a high-end luxury villa in Marbella I had a big block of HTML to include (and work on) for the images page…

,

No Comments

Neurologist

“MND research is not so different from the Apollo Program and our ‘one small step’ will be taken too.”

Dr Martin Turner, Neurologist. By Patrick Joyce.

No Comments

Product marketing pep talk for Google by Seth Godin

Lovely video – couple of years old now – but still relevant.

No Comments