سؤال

I want to create a loop where 2 or 3 items from my blogroll are spliced in like this:

<loop>
    <post1>
    <post2>
    <blogroll1>
    <post3>
    <blogroll3>        
</loop>

I'll be using images and excerpts for the loop, and the goal is to get the wp_links links to display EXACTLY like the wp_posts, so if I can actually splice in the links to the $post variable somehow and loop over them AS IF they were posts, that would be great.

Getting the posts via get_bookmarks is easy, but how would I fake WP into thinking they're $posts and how would I splice them into the $post object?

هل كانت مفيدة؟

المحلول 3

Thanks to everyone. Here is the solution that I ultimately ended up with. Rather than messing around in the loop itself, I chose to hook into the_post with a function that recreates the markup of the loop using data from $links.

    <?php
global $links;
global $links_count;
$links = get_bookmarks("limit=5");

function dg_archive_insert_links(){
    global $post;
    if (!is_singular()){
        add_action('the_post', 'dg_insert_links');
    }
}
add_action('wp', 'dg_archive_insert_links');

function dg_insert_links(){
    global $wp_query;
    global $links_count;
    global $links;
    if ( ($wp_query->current_post % 3) == 0 && ($wp_query->current_post > 0) && $links[$links_count]->link_url):
    ?>
    <div class="post type-post hentry">     
        <h2><a href="<?php echo $links[$links_count]->link_url; ?>" rel="bookmark" title='Click to read: "<?php echo $links[$links_count]->link_name; ?>"'><?php echo $links[$links_count]->link_name; ?></a></h2>
        <?php if ($links[$links_count]->link_description): ?><div class="entry-summary"><?php echo $links[$links_count]->link_description; ?></div><?php endif; ?>
        <?php if ($links[$links_count]->link_image && $links[$links_count]->link_description): ?>
            <a href="<?php echo $links[$links_count]->link_url; ?>" rel="bookmark" title="<?php echo $links[$links_count]->link_description; ?>" class="post_thumbnail" ><img src="<?php echo $links[$links_count]->link_image; ?>" width="150px" alt="<?php echo $links[$links_count]->link_description; ?>" /> </a>
        <?php endif; ?>         
    </div>
    <?php
    $links_count++;
    endif;
}

There's no need to create a new var to count, since it already exists at $wp_query->current_post

نصائح أخرى

I've tried something similar to that (well, slightly different, what I did was try to create a timeline where posts and comments showed up in the same timeline)...

Merging those two arrays is not easy, because the post object has completely different properties to the link object. If you wanted to do it, you'd have to run an array map over the response returned by get_bookmarks to make each of those objects conform to the structure of the $post object; then merge the two arrays, and then finally usort them using your own comparison function. A lot of headache for very little gain.

If you're just getting started out with this, why not make your links a custom post type so that you can merge your links and posts in one query?

Or better yet, if you can work with the development versions of 3.1, make your links a post format! That way there's no messing with the query at all, and it'll just work for you off the bat.

Edit: I originally entered this code in a separate answer. I'm following Jan's recommendation to combine my answers into one so that its more clear.

OK, so this is really wonky, and I reiterate that I don't recommend that you do this, but if you have to, this should do it for you:

$links = get_bookmarks('show_updated=true');

/* Map the properties of the link to the structure of a post object */
$linkposts = array_map( 'link2postobj', $links );
function link2postobj( $obj ) {
    $post_object = array( 
        'post_name' => $obj->link_name,
        'post_content' => '<a href="'.$obj->link_href.'" >'.
                 $obj->link_name.'</a><p>'.
                 $obj->link_description.'</p>', // the "content"
        'post_author' => $obj->link_owner,
        'post_date' => $obj->link_updated,
        'post_status' => 'link', // just a tag to mark this as a link
        'guid' => $obj->link_href   );
        return (object)$post_object;
}

/* Merge links returned with posts in query */
global $wp_query;
$posts = array_merge( $wp_query->posts, $linkposts );

/* Sort together by your function (this uses link_updated date to merge in the timeline.
    Note that link_updated is not a reliable property to depend on. */
usort( $posts, 'sortbydate' );
function sortbydate( $a, $b ) {
    return ( strtotime($a->post_date) > strtotime($b->post_date) );
    }

/* now just loop through your timeline */
foreach ( $posts as $post ) :
    if ( 'link' == $post->post_status ) {
        // template for links here
    } else {
        setup_postdata( $post );
        // template for regular posts here
    }
endforeach;

In addition to the other problems I foresaw, I noticed that the link_updated field isn't very reliable ( alot of links out of my db returned 0 as the link_updated value). So you probably need to look at the data you have and come up with a different function to sort your links and posts on.

Seriously, though, consider getting on the bleeding edge and migrating all your links into posts with the "link" format. I think for what you're trying to do, it just makes a lot more sense, and the time required to run a script and create new posts for each of your links will be much less than the hassle of maintaining a format like this.

You could use the normal wp loop (no need for complications) and get_bookmarks($args) to get the links you want.

Something like this:

$i = 1;
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
//your posts here
if ($i&1) echo 'blogroll '.$i;//blogroll 2, 4, etc.
$i++;
<?php endwhile; endif; ?>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى wordpress.stackexchange
scroll top