Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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?

share|improve this question

3 Answers 3

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.

share|improve this answer
    
What you said above is basically what I am attempting to do, with the exception that I was on doing an array_splice of the new link "posts" into the existing $post variable –  Dan Gayle Nov 11 '10 at 0:15
    
Yeah, like I said, I'd recommend not doing it if you can help it. Using a post format, or a post type, or even a category for your links will make your queries a lot easier than using the bookmarks functions. But if you're tied into using bookmarks, I'll post my array map functions... hopefully that will get you most of the way there. –  goldenapples Nov 11 '10 at 0:46
    
Please, yes. I'm working on an existing DB, and they are already using their existing links structure, so I can't really break out of that. –  Dan Gayle Nov 12 '10 at 21:04
    
Hot dang, thanks! In my particular case, I don't need to worry about the "time" of the links, I just need to count posts and insert a link in. –  Dan Gayle Nov 15 '10 at 18:43

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; ?>
share|improve this answer
    
This is probably the easiest way, honestly. I've done this before with other things. It might not be what I need for this project, but I'll definitely try it out. –  Dan Gayle Nov 16 '10 at 1:17
up vote 1 down vote accepted

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

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.