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

Help with Posts to Posts query. WordPress

  • SOLVED

I am using the plugin [[LINK href="https://github.com/scribu/wp-posts-to-posts/wiki"]]Posts to Posts [[/LINK]]by Scribu to connect custom post types “Issues” to “Content” as well as users to issues via this function.

function my_connection_types() {
p2p_register_connection_type( array(
'name' => 'issues_to_content',
'from' => 'solstice_issue',
'to' => 'solstice_article',
'reciprocal' => true,
'sortable' => 'any',
) );

p2p_register_connection_type( array(
'name' => 'solstice_authors',
'from' => 'solstice_issue',
'to' => 'user',
) );


The Content type uses a custom taxonomy called “Genre”.

I believe everything that is needed is well documented on the [[LINK href="https://github.com/scribu/wp-posts-to-posts/wiki"]]github page for the plugin[[/LINK]], but I don’t have the PHP skills to accomplish this.

On the any “Issue” page I want to have 3 queries running which is what i need help with.

Query 1 should pull in only any connected posts with the term slug “editors-note”

The second query should pull in all connected posts except “editors-note”

The third needs to pull in all users connected with the posts and show their author avatar.

I would also like the 3 queries to be as optimized as possible without querying the db for each post if possible.


Currently I have only been able to get the second query to work as follows.

<?php

$issue = get_queried_object();
// Gets every term in the genre taxonomy

$genres = get_terms('genre');

foreach($genres as $genre)

{

$articles = new WP_Query(array(

'taxonomy' => 'genre',
'term' => $genre->slug,
'posts_per_page' => -1,
'connected_orderby' => $meta_key,
'connected_type' => 'issues_to_content',
'connected_from' => $issue,
'post_type' => 'solstice_article',
'tax_query' => array(
array(
'taxonomy' => 'genre',
'field' => 'slug',
'terms' => array('editors-note'),// exclude editor's notes and photography from toc
'operator' => 'NOT IN')

),

)

);


if($articles->have_posts()): ?>



<div class="toc-part column"><h3><?php echo $genre->name ?></h3>

<ul>

<?php while( $articles->have_posts() ) : $articles->the_post(); ?>

<li><a href="<?php the_permalink() ?>"><?php the_title() ?></a>
<br /> by <span><a href="<?php the_permalink() ?>"><?php the_author() ?></a></span></li>



<?php endwhile; ?>
</ul>
</div>


<?php endif;
}
?>





Thanks!

Answers (1)

2016-04-30

dimadin answers:

Your queries don't sound complicated and they are possible, just your description and code example are a little confusing so I need to understand them first.

There are not just 3 queries on that page, it looks like there is more, this is what you have in your code example:

- Search for all terms in 'genre' taxonomy
- Loop through all terms
- Find all posts of 'solstice_article' connected to current 'solstice_issue' that have are attached to looped term and are not attached to 'editors-note' term

Maybe you want to simplify this. Why you don't remove 'tax_query' condition and instead limit result from get_terms() by checking if this is 'editors-note' term?

Like:


foreach( $genres as $genre ) {
if ( 'editors_note' == $genre->slug ) {
continue;
}

....
}


First query you mentioned is the same, just switch 'editors_note' condition:


foreach( $genres as $genre ) {
if ( 'editors_note' != $genre->slug ) {
continue;
}

....
}


You'll save a lot of database queries by this because 'tax_query' adds unnecessary complexion. The only thing here is if I didn't understood something.

For third query you mentioned, I don't understand your sentence 'connected with the posts': connected to what posts?


draivika comments:

Thanks for your response dimadin. Yes what you are saying sounds better and I want the code to be more efficient. For the last query, I want to get all connected users to the issue, since that is the page template I am editing. So when the page loads it pulls connected content by genre and then below that lists all connected users to that issue. I hope that makes sense. [[LINK href="https://github.com/scribu/wp-posts-to-posts/wiki/Posts-2-Users"]]This page on Github[[/LINK]] describes it I think, but I couldn't get it to work for me.

To get a list of users connected to a certain post, you can write:


$users = get_users( array(
'connected_type' => 'multiple_authors',
'connected_items' => $post
) );


dimadin comments:

I think that this code should achieve what you want:


$users = get_users( array(
'connected_type' => 'solstice_authors',
'connected_items' => $issue,
) );

foreach ( $users as $user ) {
echo get_avatar( $user->ID );
};


draivika comments:

Hi, I can't get the first part to work, would you be able to give me the full modified PHP statement with the 3 sections based on my original snippet. I was able to get the users with the last part you provided, but it only shows the avatar and no name. I guess I should have been more specific, but I can't figure out how to get the avatar with the author name and link to author archive as well. Do you know if that is possible?


dimadin comments:

First, you should increase time for this question as soon as possible, there is a link " Extend Question by 1 Day?". If that doesn't work for you, you can contact me from my profile page here so we can finish this.

I modified your code to include changes I made. Those are first two sections, I'll look for third one.

Please note that you have variable $meta_key that isn't defined here, if something doesn't work try to remove it by removing whole line ('connected_orderby' => $meta_key,)


<?php
$issue = get_queried_object();

// Gets every term in the genre taxonomy
$genres = get_terms( 'genre' );

foreach ( $genres as $genre ) {
if ( 'editors_note' == $genre->slug ) {
continue;
}

$articles = new WP_Query(array(
'taxonomy' => 'genre',
'term' => $genre->slug,
'posts_per_page' => -1,
'connected_orderby' => $meta_key,
'connected_type' => 'issues_to_content',
'connected_from' => $issue,
'post_type' => 'solstice_article',
) );

if ( $articles->have_posts() ) : ?>
<div class="toc-part column"><h3><?php echo $genre->name ?></h3>
<ul>
<?php while ( $articles->have_posts() ) : $articles->the_post(); ?>
<li>
<a href="<?php the_permalink() ?>"><?php the_title() ?></a>
<br /> by <span><a href="<?php the_permalink() ?>"><?php the_author() ?></a></span>
</li>
<?php endwhile; ?>
</ul>
</div>
<?php endif;

wp_reset_postdata();
}

foreach ( $genres as $genre ) {
if ( 'editors_note' != $genre->slug ) {
continue;
}

$articles = new WP_Query(array(
'taxonomy' => 'genre',
'term' => $genre->slug,
'posts_per_page' => -1,
'connected_orderby' => $meta_key,
'connected_type' => 'issues_to_content',
'connected_from' => $issue,
'post_type' => 'solstice_article',
) );

if ( $articles->have_posts() ) : ?>
<div class="toc-part column"><h3><?php echo $genre->name ?></h3>
<ul>
<?php while ( $articles->have_posts() ) : $articles->the_post(); ?>
<li>
<a href="<?php the_permalink() ?>"><?php the_title() ?></a>
<br /> by <span><a href="<?php the_permalink() ?>"><?php the_author() ?></a></span>
</li>
<?php endwhile; ?>
</ul>
</div>
<?php endif;

wp_reset_postdata();
}
?>


dimadin comments:

This is the code for users list. Note that you should probably style it according to your theme. Also note that it displays user's name from field "Nicename", you might want to change that.


$users = get_users( array(
'connected_type' => 'solstice_authors',
'connected_items' => $issue,
) );

foreach ( $users as $user ) {
echo '<div><div>' . get_avatar( $user->ID ) . '</div><div><a href="' . get_author_posts_url( $user->ID, $user->user_nicename ) . '">' . $user->user_nicename . '</a></div></div>';
};


draivika comments:

Increased the time. Will try this out later today, but looks good. Thanks very much.


draivika comments:

This worked fine. Thanks, but what I am really trying to do is pull out the editor's note into a separate div. When I try to do that with this it lists everything twice. Is it possible to modify so I can get the editor's note first, then make a new section, then get everything except the editors note term?


<div> Editors note</div>
<div> Everything except editor's note</div>
<div>get connected users</div>


If you could help me with hat, I sincerely appreciate it.


draivika comments:

Anyway to get nickname or name instead of nicename?


draivika comments:

Got it "display_name"