WordPress.org

Ready to get started?Download WordPress

Forums

[resolved] Sticky/Featured Post/Avoiding Duplicates (13 posts)

  1. jvinch
    Member
    Posted 6 years ago #

    I've been wrecking my brain over this - but it may not be as complicated for someone with more programming skill.

    Here's what I have..

    1. A category page with 2 columns. The left column holds 2 featured posts, the right column holds "other posts" in this category.

    2. 2 categories - one being the regular topic, the other one for featured posts within this topic (ie. Category A, Category A-Featured)

    3. Posts in the left column are assigned to both the regular topic as well as the featured category (Category A, Category A-Featured), posts in the right column just to the topic (Category A)

    4. Featured posts are not necessarily the most recent ones, but rather a hand-picked selection of cornerstone content within the specific topic.

    The challenge I have is to present the content in both left and right columns and primary to prevent posts to show up twice on this page.

    Here's what I have...

    Left Featured Column - pulling in the first featured post and making sure it's not replicated elsewhere.

    Loop 1:

    <?php $recent = new WP_Query("cat=A-Featured&showposts=1");
    while($recent->have_posts()) : $recent->the_post();
    $do_not_duplicate = $post->ID; ?>
    <h2><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></h2>
    <?php the_content(__('more &raquo;'));?>
    <?php endwhile; ?>

    Then, we grab the second featured article, making sure it's not the same as the first post and making sure it's not replicated elsewhere on the page:

    Loop 2:

    <?php $recent = new WP_Query("cat=A-Featured&showposts=2");
    while($recent->have_posts()) : $recent->the_post();
    if ( $post->ID == $do_not_duplicate ) continue;
    update_post_caches($posts);
    $do_not_duplicate = $post->ID; ?>
    <h2><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></h2>
    <?php the_content(__('more &raquo;'));?>
    <?php endwhile; ?>

    And lastly, we take the the right column and start our third loop - making sure the posts have not been printed elsewhere on the page already.

    Loop 3:

    <?php $recent = new WP_Query("cat=A&showposts=9");
    while($recent->have_posts()) : $recent->the_post();
    if( $post->ID == $do_not_duplicate) continue;
    update_post_caches($posts); ?>
    <b><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></b>
    <?php the_content_limit(130, ""); ?>
    <?php endwhile; ?>

    This works great - with one problem; the first featured posts still appears in the list of "rest posts" in the right column.

    Any ideas on how I can fix this? I have a feeling it's relatively simple, but I can't seem to come up with an answer.

    Thanks in advance,

    John

  2. gmcdonough
    Member
    Posted 6 years ago #

    I have been wrestling with a similar problem. In my setup (also 2 columns) the left column holds the newest post in this category that is also a featured (category) post. The right column holds the 5 newest posts of this category (some of which may be old featured posts). I also have duplicate posts showing up because the featured post is usually one of the 5 newest posts in this category. The solution i have come up with (which seems overly involved for this problem) is as follows:

    at the top of each page, a code header is used to instanciate an array to hold post ID's for the page. Maybe name the array by calling getting the category name. Using a custom filter or plugin, the syntax "AND post_id NOT IN ($IdArray[1],$IdArray[2],...)" is added to the SQL query called from wp_query. As each post is displayed, the post's id(which has already been determined not to exist on the current page) is added to the array. At the end of the page, a code footer performs unset() on $IdArray[].

    Aside from having diverged from the KISS principle, i'm having trouble with how to pass $IdArray[] to the plugin or filter that will handle the 'posts_where' hook in order to concatanate onto the WHERE part of the SQL query.

    Has anybody solved this in a simpler way, or have any input that could shine some light on the subject? Thanks in advance.

  3. Alex Cragg
    Member
    Posted 6 years ago #

    @jvinch - I realise you posted that a long time ago, but maybe you are still following this thread.
    @gmcdonough - I think I understand what you are saying, and I think I have a simpler way.

    Jvinch, why are you running two separate loops for you featured content? If you use your first loop to call two posts, then store their IDs in an array under do_not_duplicate, you can later call that array of IDs to exclude them from your second loop in the right column.

    This is how I do it:

    <?php $recent= new WP_Query('category_name=A-Feature&showposts=2');
    while ($recent->have_posts()) : $recent->the_post();
    $do_not_duplicate[] = get_the_ID();?>
    stuff
    <?php endwhile; ?>

    Then when you run your second loop, you search this array to find the IDs in it, and then the !== false makes sure that they are not used.

    <?php query_posts('category_name=A&showposts=9'); ?>
    <?php while (have_posts()) : the_post();
    if (array_search(get_the_ID(), $do_not_duplicate) !== false)
    continue; update_post_caches($posts); ?>
    stuff
    <?php endwhile; ?>

    Hope that works for you, let me know.
    Alex

  4. bradstinyworld
    Member
    Posted 6 years ago #

    here is how I do something very similar. I use 2 full posts so people can see the latest digg numbers then I use excerpted of another 5 posts so I can end up pretty much even with my the bottom of my sidebar the same kind of codding should work for you, the results can be seen on http://www.bradstinyworld.com

    <?php $my_query = new WP_Query('showposts=1');
    while ($my_query->have_posts()) : $my_query->the_post();
    $do_not_duplicate = $post->ID;?>
    (normal post code)
    <?php endwhile; ?>

    The second post is coded

    <?php $my_query = new WP_Query('showposts=1&offset=1');
      while ($my_query->have_posts()) : $my_query->the_post();
      $do_not_duplicate = $post->ID;?>
    (normal post code)
    <?php endwhile; ?>

    You can keep this up any number of times but to mix it with excerpts later on and avoid duplicates you need to adjust your offsets

    <?php query_posts("showposts5&offset=2");?>
    <?php while (have_posts()) : the_post(); ?>
    <div class="post" id="post-<?php the_ID(); ?>">
    (post code)
    <?php endwhile;?>

    for my excerpts I like using the excerpt editor plugin.

  5. ewcost
    Member
    Posted 5 years ago #

    @bradstinyworld

    This code is a life saver! I've been trying to find something like this for awhile now and your code worked great. Thanks for sharing!!

    Elliott

  6. mores
    Member
    Posted 5 years ago #

    Hmmmm, I must check out how you guys to this, since I have a page with 5 or 6 loops and I just know there is something I can optimize :)

  7. mores
    Member
    Posted 5 years ago #

    Okay, epicalex' post helped me remove the duplicate post.
    But, if I want X number of posts, that bit of code will "waste" one post and I get X-1 posts displayed.

    Help ?

  8. Alex Cragg
    Member
    Posted 5 years ago #

    Check this post out:
    http://weblogtoolscollection.com/archives/2008/05/17/how-to-avoid-duplicate-posts/

    You'll see that your point about my method was raised there too!

    Hope this works better for you

    A

  9. mores
    Member
    Posted 5 years ago #

    That didn't work so well on my theme ... I guess it's not compatible with specifying a category for the querypost.

  10. mores
    Member
    Posted 5 years ago #

    Okay, different tack:
    First, in the featured article, I remember the CATEGORIES that this featured article is in:

    <?php $dup_cat[] = get_the_category();?>

    Then, when I'm looping the rest of the categories and associated posts, I want to offset the category by one.

    <?php if (in_array($category->name, $dup_cat->cat_name)) {
    	query_posts('category_name='.$category->name.'&showposts=5&offset=1');
    } else {
    	query_posts('category_name='.$category->name.'&showposts=5');
    } ?>

    Now, my PHP is not good enough to get this done properly ... there's something with the way the category stuff is in that array that I do not understand which results in this error message:

    Warning: in_array(): Wrong datatype for second argument in /html/wp-content/themes/dm-mag/index.php on line XX

    Hay-elp mee-hee puh-leese!

  11. mores
    Member
    Posted 5 years ago #

    Well guess what ... this has been posted here about 8 months ago. He who searches shall rule the earth. Well, count me out.

    I think my mistake was in the beginning - I didn't actually create an array. So, you need to do this first:

    $mycats = get_the_category();
    foreach($mycats as $mycat)
    	$mycatids[] = $mycat->term_id;
    	$mycatids[] = $mycat->category_parent;

    Get all the categories the featured post is part of. And after a while I figured out that when using subcategories, you need to include the parent as well. So now you get an array with all the category-ids.
    Then you loop through the categories you want to display on the front page. I want them all, so I my code is different from otto's :

    <?php foreach ($categories as $category) { ?>
    <h1><a href="<?php echo get_category_link($category->id); ?>">Kategorie: <?php echo $category->name; ?></a><H1>
    <?php if (in_array($category->id,$mycatids)) {
    	query_posts('category_name='.$category->name.'&showposts=5&offset=1');
    } else {
    	query_posts('category_name='.$category->name.'&showposts=5');
    }
    if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
    	<p><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></p>
    <?php endwhile; else: ?><p>Nix!</p><?php endif; ?>

    This writes a headline with the category name, then displays 5 posts in that category. If this is the category where the featured post is part of, then offset the query by one and leave out this first featured post.

    I post this in case other people are as stumped as I was.

  12. tilmeister
    Member
    Posted 5 years ago #

    Mores, thank you for the code. I thought it was the problem's solution.. But there's something wrong with it.. Or maybe it's me being silly. Dont know..

    I have "Cat1" and "Feature".. Now I post something i want to be featured in both categories.. and the script works fine. But when I post a new article in "Cat1" but not "Featured", the newest article will not be shown, because the script offsets the Cat1 by 1, because the featured post is in Cat1, as well.

    Effectively duplicating the featured entry.

    Maybe check if the newest entry in the $mycatsid categories is the featured post, and if so, THEN offset by 1?..

    Can someone elaborate? Or help me? ;)

  13. tilmeister
    Member
    Posted 5 years ago #

    This might be a bit rough around the edges...
    Also I don't even know if this is correct PHP :D Am a bit rusty...
    It does work how I want it as far as i can tell...

    Maybe someone got an idea how to change it so it displays more than one post ;)

    <?php
    $feature_id = '3'; //enter the featured cat_id
    
    $feature = new WP_Query('cat='.$feature_id.'&showposts=1');
    while($feature->have_posts()) : $feature->the_post();
    $featured_post_id = $post->ID;
    echo 'featured_post_id: '.$featured_post_id;
    $thecats = get_the_category();
    foreach($thecats as $thecat)
      $feature_post_cats[] = $thecat->term_id;
    endwhile;
    echo '<br />feature_post_cats: '; print_r ($feature_post_cats); ?><br /><br />
    
    <?php $categories = get_categories('exclude='.$feature_id);
    foreach ($categories as $category) {
    echo 'category: '; print_r ($category); echo '<br /><br />';
    $cats = new WP_Query('cat='.$category->cat_ID.'&showposts=2');
    while($cats->have_posts()) : $cats->the_post();
    $check = $post->ID;
    if ($check == $featured_post_id) :
    echo 'post: del->'.$post->ID.' - skip this one<br /><br />'; continue;
    endif;
    echo 'post: keep->'.$post->ID.'<br /><br />'; break;
    endwhile;
    } ?>

    edit: gawd, i've been editing the heck out of this entry ;)

Topic Closed

This topic has been closed to new replies.

About this Topic