Ask your WordPress questions! Pay money and get answers fast! (more info)

Custom Loop Needed WordPress

  • SOLVED

Hi,

I am building my first wordpress theme. I'm fairly new to wordpress, this is about my 6th site I am building.

I am in need of a custom loop for my gallery/portfolio page template. Here is an example of what the gallery items will look like. There will be three items across, and the total number of items will be determined by the user via a custom admin panel. [[LINK href="http://alaja.info/pandora/wordpress/portfolio/"]]Example here[[/LINK]]

So, the loop needs to first store two variables. One is the total number of items to be displayed, and the other is the category ID that it should pull posts from. I will handle all the back-end stuff and make those two numbers dynamic, but I need your help to build out the loop that will generate the items.

<strong>Here is what the static HTML looks like for a row of 3 items. Notice how the last column has a different id than the first two. Also notice how a <br class="clear" /> is added after each complete row.</strong>

<div class="threecol">
<div class="img_frame_port">
<div class="fade"><a href="#"><img src="i/x_temp_envato_port.jpg" alt="" /></a><div><img src="i/img_div_fade_ro.gif" alt="" /></div></div><!-- end load -->
</div><!-- end img_frame_port -->
<h3>Lorem Ipsum Dolor Sit</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse vitae nibh quis eros sodales dictum. Vivamus libero libero, accumsan sed imperdiet sed, tristique sit amet nibh. Pellentesque id eros eget sapien pretium semper et in libero. Lorem ipsum dolor sit amet, consectetur.</p>
</div><!-- end threecol -->



<div class="threecol">
<div class="img_frame_port">
<div class="fade"><a href="#"><img src="i/x_temp_envato_port.jpg" alt="" /></a><div><img src="i/img_div_fade_ro.gif" alt="" /></div></div><!-- end load -->
</div><!-- end img_frame_port -->
<h3>Lorem Ipsum Dolor Sit</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse vitae nibh quis eros sodales dictum. Vivamus libero libero, accumsan sed imperdiet sed, tristique sit amet nibh. Pellentesque id eros eget sapien pretium semper et in libero. Lorem ipsum dolor sit amet, consectetur.</p>
</div><!-- end threecol -->



<div class="threecol_last">
<div class="img_frame_port">
<div class="fade"><a href="#"><img src="i/x_temp_envato_port.jpg" alt="" /></a><div><img src="i/img_div_fade_ro.gif" alt="" /></div></div><!-- end load -->
</div><!-- end img_frame_port -->
<h3>Lorem Ipsum Dolor Sit</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse vitae nibh quis eros sodales dictum. Vivamus libero libero, accumsan sed imperdiet sed, tristique sit amet nibh. Pellentesque id eros eget sapien pretium semper et in libero. Lorem ipsum dolor sit amet, consectetur.</p>
</div><!-- end threecol_last -->
<br class="clear" />



Here is the loop that I have so far. I tried following some tutorials and pulling code from another source, but this loop I have spits out an error that says:
Fatal error: Call to undefined function add_new_line()


<strong>Feel free to use this code as your starting point.</strong>

<?php
$item_count = '9';
$category_id = '31';
$query_string ="posts_per_page=$item_count&cat=$category_id";

$empty_item = add_new_line(4) .'<div class="threecol"> &nbsp; </div>';
$clear_row = add_new_line(4) .'<br class="clear" />'. add_new_line(4) . add_new_line(0);

query_posts($query_string);

$count = 0;
if (have_posts()) : while (have_posts()) : the_post();
$count++;
$mod = ($count % 3 == 0) ? 0 : 3 - $count % 3;
$portfolio_thumb_image_url = get_post_meta($post->ID, "portfolio_thumb_image_url", true);
$portfolio_full_image_url = get_post_meta($post->ID, "portfolio_full_image_url", true);
?>


<div class="threecol">
<?php if ( has_post_thumbnail() ) : ?>
<div class="img_frame_port">
<div class="fade"><a href="#"><?php the_post_thumbnail(); ?></a></div><!-- end fade -->
</div><!-- end img_frame_port -->
<?php endif; ?>
<h3><?php echo strtoupper(get_the_title()); ?></h3>
<?php the_content(); ?>
</div><!-- end threecol -->


<?php
if ( $mod == 0 ) echo $clear_row;
endwhile; endif;

for ( $i = 0; $i < $mod; $i++ ) echo $empty_item;
if ( $count < 3 || $mod != 0) echo $clear_row;

?>

Answers (3)

2010-03-27

Buzu B answers:

If you get that error it means there is no function called add_new_line(). Where did you see that? what is that function supposed to do? what happens if you comment out that line?


WP Answers comments:

Hi,

I commented out those 2 lines, and the posts display properly. Thank you. The only problem now is that it does not add the <br class="clear" /> after there are 3 items added. I need the BR to get added every time a row of 3 is added.

Any ideas?

Here's the code again that's in working order:


<?php
$item_count = '9';
$category_id = '31';
$query_string ="posts_per_page=$item_count&cat=$category_id";

/* $empty_item = add_new_line(4) .'<div class="threecol"> &nbsp; </div>';
$clear_row = add_new_line(4) .'<br class="clear" />'. add_new_line(4) . add_new_line(0); */

query_posts($query_string);

$count = 0;
if (have_posts()) : while (have_posts()) : the_post();
$count++;
$mod = ($count % 3 == 0) ? 0 : 3 - $count % 3;
$portfolio_thumb_image_url = get_post_meta($post->ID, "portfolio_thumb_image_url", true);
$portfolio_full_image_url = get_post_meta($post->ID, "portfolio_full_image_url", true);
?>


<div class="threecol">
<?php if ( has_post_thumbnail() ) : ?>
<div class="img_frame_port">
<div class="fade"><a href="#"><?php the_post_thumbnail(); ?></a></div><!-- end fade -->
</div><!-- end img_frame_port -->
<?php endif; ?>
<h3><?php echo strtoupper(get_the_title()); ?></h3>
<?php the_content(); ?>
</div><!-- end threecol -->


<?php
if ( $mod == 0 ) echo $clear_row;
endwhile; endif;

for ( $i = 0; $i < $mod; $i++ ) echo $empty_item;
if ( $count < 3 || $mod != 0) echo $clear_row;




Buzu B comments:

try changing this

<?php

if ( $mod == 0 ) echo $clear_row;

endwhile; endif;


to this:


<?php

if ( $mod == 0 ){
echo '<br class="clear" />';
}

endwhile; endif;


WP Answers comments:

Thank you for this. The loop is functioning properly.

My only problem now is that with the way my HTML/CSS is currently written, every 3rd row needs to have a different class name. So, column 1 and column 2 have a class of "threecol", and column 3 needs a class of "threecol_last". Is there any easy way to modify the loop so that the 3rd column gets this new class? If not, I suppose I can modify my CSS/HTML structure so all 3 columns use the same class name.

<strong>Here is the working code so far:</strong>

<?php
$item_count = '9';
$category_id = '31';
$query_string ="posts_per_page=$item_count&cat=$category_id";

query_posts($query_string);

$count = 0;
if (have_posts()) : while (have_posts()) : the_post();
$count++;
$mod = ($count % 3 == 0) ? 0 : 3 - $count % 3;
$portfolio_thumb_image_url = get_post_meta($post->ID, "portfolio_thumb_image_url", true);
$portfolio_full_image_url = get_post_meta($post->ID, "portfolio_full_image_url", true);
?>


<div class="threecol">
<?php if ( has_post_thumbnail() ) : ?>
<div class="img_frame_port">
<div class="fade"><a href="#"><?php the_post_thumbnail(); ?></a></div><!-- end fade -->
</div><!-- end img_frame_port -->
<?php endif; ?>
<h3><?php echo strtoupper(get_the_title()); ?></h3>
<?php the_content(); ?>
</div><!-- end threecol -->


<?php
if ( $mod == 0 ){
echo '<br class="clear" />';
}
endwhile; endif;
?>


Buzu B comments:

change this:


$count = 0;

if (have_posts()) : while (have_posts()) : the_post();

$count++;

$mod = ($count % 3 == 0) ? 0 : 3 - $count % 3;

$portfolio_thumb_image_url = get_post_meta($post->ID, "portfolio_thumb_image_url", true);

$portfolio_full_image_url = get_post_meta($post->ID, "portfolio_full_image_url", true);

?>





<div class="threecol">


to this:


$count = 0;
$col = 0;

if (have_posts()) : while (have_posts()) : the_post();

$count++;

//$mod = ($count % 3 == 0) ? 0 : 3 - $count % 3;

if($count % 3 == 0){
$mod = 0;
$col ++;
}else{
$mod = 3 - $count % 3;
}

$portfolio_thumb_image_url = get_post_meta($post->ID, "portfolio_thumb_image_url", true);

$portfolio_full_image_url = get_post_meta($post->ID, "portfolio_full_image_url", true);

?>





<div class="threecol<?php if($col == 3){ echo '_last'; $col = 0; } ?>">


I think that'd do it.


WP Answers comments:

Hi,

I added that code, but it does not add the different class to the 3rd item. If you can look at it again that'd be great, but if not, I will try to modify mt HTML/CSS and see how that works out.

Thank you very much for all your help.

Here is the code as of now (it works but doesn't add unique class to 3rd item):

<?php
$item_count = '9';
$category_id = '31';
$query_string ="posts_per_page=$item_count&cat=$category_id";

query_posts($query_string);

$count = 0;
$col = 0;
if (have_posts()) : while (have_posts()) : the_post();
$count++;
//$mod = ($count % 3 == 0) ? 0 : 3 - $count % 3;
if($count % 3 == 0){
$mod = 0;
$col ++;
}else{
$mod = 3 - $count % 3;
}
?>



<div class="threecol<?php if($col == 3){ echo '_last'; $col = 0; } ?>">
<?php if ( has_post_thumbnail() ) : ?>
<div class="img_frame_port">
<div class="fade"><a href="#"><?php the_post_thumbnail(); ?></a></div><!-- end fade -->
</div><!-- end img_frame_port -->
<?php endif; ?>
<h3><?php echo strtoupper(get_the_title()); ?></h3>
<?php the_content(); ?>
</div><!-- end threecol -->



<?php
if ( $mod == 0 ){
echo '<br class="clear" />';
}
endwhile; endif;
?>


Buzu B comments:

Try changing
class="threecol<?php if($col == 3){
to
class="threecol<?php if($col == 2){


WP Answers comments:

Getting closer! Currently I have 6 posts being pulled in (so two rows of 3 items)

When I changed the code, the second row of items behaves correctly (the 3rd item gets the unique class), but the first row of items still doesn't behave correctly (the 3rd item does not get the unique class)

Any ideas?


Buzu B comments:

Ah, ok. I think I misunderstood what you were trying to do.

Take the $col ++ out of the if and place it just below the $count++ then reverse the 2 you just changed the 3 we had before.


<?php

$item_count = '9';

$category_id = '31';

$query_string ="posts_per_page=$item_count&cat=$category_id";



query_posts($query_string);



$count = 0;

$col = 0;

if (have_posts()) : while (have_posts()) : the_post();

$count++;
$col ++;

$mod = ($count % 3 == 0) ? 0 : 3 - $count % 3;

?>







<div class="threecol<?php if($col == 3){ echo '_last'; $col = 0; } ?>">

<?php if ( has_post_thumbnail() ) : ?>

<div class="img_frame_port">

<div class="fade"><a href="#"><?php the_post_thumbnail(); ?></a></div><!-- end fade -->

</div><!-- end img_frame_port -->

<?php endif; ?>

<h3><?php echo strtoupper(get_the_title()); ?></h3>

<?php the_content(); ?>

</div><!-- end threecol -->







<?php

if ( $mod == 0 ){

echo '<br class="clear" />';

}

endwhile; endif;

?>


I also deleted the if() and uncommented the conditional you had before. This should work, that is if I understood this time what it is you are trying to do.

2010-03-27

Brian Richards answers:

I can't confirm your math for the count and mod portions, but here's a working query for you. The $category_id and $item_count variabels are passed through as custom fields for the page. If neither are set then the query defaults to all categories and the count defaults to 9.

<?php
$temp = $wp_query;
$category_id = get_post_meta($post->ID, 'category_id', true);
$item_count = (get_post_meta($post->ID, 'item_count', true)) ? get_post_meta($post->ID, 'item_count', true) : 9;
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$count = 0;
$wp_query = new WP_query('cat='.$category_id.'&showposts='.$item_count.'&paged='.$paged); while ( have_posts() ) : the_post();
?>
<div class="threecol">
<?php if ( has_post_thumbnail() ) : ?>
<div class="img_frame_port">
<div class="fade"><a href="#"><?php the_post_thumbnail(); ?></a></div><!-- end fade -->
</div><!-- end img_frame_port -->
<?php endif; ?>
<h3><?php echo strtoupper(get_the_title()); ?></h3>
<?php the_content(); ?>
</div><!-- end threecol -->
<?php
$count++;
$mod = ($count % 3 == 0) ? 0 : 3 - $count % 3;
if ( $mod == 0 ) echo '<br class="clear" />';
for ( $i = 0; $i < $mod; $i++ ) echo '<div class="threecol"> &nbsp; </div>';
if ( $count < 3 || $mod != 0) echo $clear_row;
endwhile; endif;
$wp_query = $temp;
?>


Brian Richards comments:

And if you wanted to include the default prev/next posts links you could do this:


<?php
$temp = $wp_query;
$category_id = get_post_meta($post->ID, 'category_id', true);
$item_count = (get_post_meta($post->ID, 'showposts', true)) ? get_post_meta($post->ID, 'item_count', true) : 9;
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$count = 0;
$wp_query = new WP_query('cat='.$category_id.'&showposts='.$item_count.'&paged='.$paged); while ( have_posts() ) : the_post();
?>
<div class="threecol">
<?php if ( has_post_thumbnail() ) : ?>
<div class="img_frame_port">
<div class="fade"><a href="#"><?php the_post_thumbnail(); ?></a></div><!-- end fade -->
</div><!-- end img_frame_port -->
<?php endif; ?>
<h3><?php echo strtoupper(get_the_title()); ?></h3>
<?php the_content(); ?>
</div><!-- end threecol -->
<?php
$count++;
$mod = ($count % 3 == 0) ? 0 : 3 - $count % 3;
if ( $mod == 0 ) echo '<br class="clear" />';
for ( $i = 0; $i < $mod; $i++ ) echo '<div class="threecol"> &nbsp; </div>';
if ( $count < 3 || $mod != 0) echo $clear_row;
endwhile; endif;
?>

<div id="nav-below" class="navigation">
<div class="nav-previous"><?php next_posts_link(__('<span class="meta-nav">&laquo;</span> Older posts', 'sandbox')) ?></div>
<div class="nav-next"><?php previous_posts_link(__('Newer posts <span class="meta-nav">&raquo;</span>', 'sandbox')) ?></div>
</div>

<?php $wp_query = $temp; ?>


WP Answers comments:

Thank you very much for this. I tried both snippets of code you sent over, but I get the following error:

Parse error: syntax error, unexpected T_ENDIF in mywebsitedirectory/template-gallery.php on line 80


Brian Richards comments:

Oops! I squeezed an extra endif in there. Try this:

<?php
$temp = $wp_query;
$category_id = get_post_meta($post->ID, 'category_id', true);
$item_count = (get_post_meta($post->ID, 'showposts', true)) ? get_post_meta($post->ID, 'item_count', true) : 9;
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$count = 0;
$wp_query = new WP_query('cat='.$category_id.'&showposts='.$item_count.'&paged='.$paged); while ( have_posts() ) : the_post();
?>
<div class="threecol">
<?php if ( has_post_thumbnail() ) : ?>
<div class="img_frame_port">
<div class="fade"><a href="#"><?php the_post_thumbnail(); ?></a></div><!-- end fade -->
</div><!-- end img_frame_port -->
<?php endif; ?>
<h3><?php echo strtoupper(get_the_title()); ?></h3>
<?php the_content(); ?>
</div><!-- end threecol -->
<?php
$count++;
$mod = ($count % 3 == 0) ? 0 : 3 - $count % 3;
if ( $mod == 0 ) echo '<br class="clear" />';
for ( $i = 0; $i < $mod; $i++ ) echo '<div class="threecol"> &nbsp; </div>';
if ( $count < 3 || $mod != 0) echo $clear_row;
endwhile;
?>

<div id="nav-below" class="navigation">
<div class="nav-previous"><?php next_posts_link(__('<span class="meta-nav">&laquo;</span> Older posts', 'sandbox')) ?></div>
<div class="nav-next"><?php previous_posts_link(__('Newer posts <span class="meta-nav">&raquo;</span>', 'sandbox')) ?></div>
</div>

<?php $wp_query = $temp; ?>


WP Answers comments:

Thank you for this code. I am going to use the loop I have, but I will be using some items from the loop you sent over. I will be splitting up the prize money. Thank you very much for your help.

2010-03-27

Mathieu Hallé answers:

i have done such thing a lot of time and i find it easer to use pages insted of post.
start by making a page wich will serve as parent. in thie case portfolio. apply to this parent page the template for this custom page

then for each new project you want to put in your portfolio, you make a new page that is a child of the portfolio page.

then you can make a nice and simple query like this:



<?php
// this is the a simple query, but you could add much more option to make it as you need
// you can lookup the query_posts page in the WP codex to get the full list of option available
// there are parm for the paging as well in the option available

$args = array(
'posts_per_page' => 9, // number of item you want to list in the page
'post_type' => 'page',
'post_parent' => $post->ID // this will list all the child page (your project in this case)
);
query_posts($args);


?>

<?php if (have_posts()) :
//let put in a ticker to count each 3 project
$tick = 0;
?>
<?php while (have_posts()) : the_post();
$tick ++;
if ( $tick % 3 ) echo '<br class="clear" />';

?>

<h2><?php the_title(); ?></h1>
<?php the_content(); ?>
here, your in a simple loop, so you can use pretty much any template tag you want to get your content layour as you want.


<?php endwhile; ?>
<?php endif; ?>
<?php wp_reset_query(); ?>





it's pretty raw, but i find this method to be very simple and quite effective.
also, i did not test the code, but it should work.

hope it helps