montreyw / Theme-Redesign-and-SEO-Overhaul

Earmilk redesign project
2 stars 0 forks source link

"Related Posts" seems to be broken as on some pages it doesn't output any posts #37

Closed andrebu closed 8 years ago

andrebu commented 8 years ago

"Related Posts" seems to be broken as on some pages it doesn't output any posts.

  1. Example 1: http://earmilk.com/2016/02/11/you-need-to-hear-j-f-l-es-cathartic-lo-fi-affair-entitled-oh-shit-premiere/ screen shot 2016-02-24 at 3 23 33 am
  2. Example 2: http://earmilk.com/2012/01/06/author-live-dmz-exodus/ screen shot 2016-02-24 at 3 23 39 am
andrebu commented 8 years ago

Seeing as how the function works strictly by aggregating the current post's tags and looking for posts with the same tags, I believe the issue is simply tags.

SOLUTION

Either writers must use more or more commonly used and more relevant tags, OR, we can expand the Related Articles function to include some posts from related categories, if there are not enough posts to fill up the widget with tag-related posts.

montreyw commented 8 years ago

Using the plugin that came with theme. Should I find a better one?

Sent from my iPhone

On Feb 24, 2016, at 12:24 AM, Andre notifications@github.com wrote:

"Related Posts" seems to be broken as on some pages it doesn't output any posts.

Example 1: http://earmilk.com/2016/02/11/you-need-to-hear-j-f-l-es-cathartic-lo-fi-affair-entitled-oh-shit-premiere/

Example 2: http://earmilk.com/2012/01/06/author-live-dmz-exodus/

— Reply to this email directly or view it on GitHub.

andrebu commented 8 years ago

It's not a plugin, but just a hardcoded function, like this:

    <?php
        $orig_post = $post;
        global $post;
        $tags = wp_get_post_tags($post->ID);
        if ($tags) {
        $tag_ids = array();
        foreach($tags as $individual_tag) $tag_ids[] = $individual_tag->term_id;
        $args=array(
        'tag__in' => $tag_ids,
        'post__not_in' => array($post->ID),
        'posts_per_page'=>4, // Number of related posts to display.
        'ignore_sticky_posts'=>1
        );
        $my_query = new wp_query( $args );
        while( $my_query->have_posts() ) {
        $my_query->the_post();
    ?>

I'm sure there are plugin, but it's not really necessary. Just gotta add category related posts to that array and have the function draw starting from tags. If 0 tag related posts, it'll pull category related posts. I'm not sure a plugin will do much better than that.

andrebu commented 8 years ago

Current function:

function get_max_related_posts( $recent_posts = array(), $taxonomy_1 = 'post_tag', $taxonomy_2 = 'category', $total_posts = 4 ) {
    // First, make sure we are on a single page, if not, bail
    if ( !is_single() )
        return false;

    // Sanitize and vaidate our incoming data
    if ( 'post_tag' !== $taxonomy_1 ) {
        $taxonomy_1 = filter_var( $taxonomy_1, FILTER_SANITIZE_STRING );
        if ( !taxonomy_exists( $taxonomy_1 ) )
            return false;
    }

    if ( 'category' !== $taxonomy_2 ) {
        $taxonomy_2 = filter_var( $taxonomy_2, FILTER_SANITIZE_STRING );
        if ( !taxonomy_exists( $taxonomy_2 ) )
            return false;
    }

    if ( 4 !== $total_posts ) {
        $total_posts = filter_var( $total_posts, FILTER_VALIDATE_INT );
            if ( !$total_posts )
                return false;
    }

    // Everything checks out and is sanitized, lets get the current post
    $current_post = sanitize_post( $GLOBALS['wp_the_query']->get_queried_object() );

    // Lets get the first taxonomy's terms belonging to the post
    $terms_1 = get_the_terms( $current_post, $taxonomy_1 );

    // Set a varaible to hold the post count from first query
    $count = 0;
    // Set a variable to hold the results from query 1
    $q_1   = [];
    // Set a variable to hold the exclusions
    $sticky = get_option( 'sticky_posts' );
    $exclude = array_merge( [$current_post->ID], $sticky );
    $exclude = array_merge( $exclude, $recent_posts );

    // Make sure we have terms
    if ( $terms_1 ) {
        // Lets get the term ID's
        $term_1_ids = wp_list_pluck( $terms_1, 'term_id' );

        // Lets build the query to get related posts
        $args_1 = [
            'post_type'      => $current_post->post_type,
            'post__not_in'   => $exclude,
            'posts_per_page' => $total_posts,
            'fields'         => 'ids',
            'tax_query'      => [
                [
                    'taxonomy'         => $taxonomy_1,
                    'terms'            => $term_1_ids,
                    'include_children' => false
                ]
            ],
        ];
        $q_1 = get_posts( $args_1 );

        // Update our counter
        $count = count( $q_1 );
        // Update our counter
        $exclude = array_merge( $exclude, $q_1 );
    }

    // We will now run the second query if $count is less than $total_posts
    if ( $count < $total_posts ) {
        $terms_2 = get_the_terms( $current_post, $taxonomy_2 );
        // Make sure we have terms
        if ( $terms_2 ) {
            // Lets get the term ID's
            $term_2_ids = wp_list_pluck( $terms_2, 'term_id' );

            // Calculate the amount of post to get
            $diff = $total_posts - $count;

            $args_2 = [
                'post_type'      => $current_post->post_type,
                'post__not_in'   => $exclude,
                'posts_per_page' => $diff,
                'fields'         => 'ids',
                'tax_query'      => [
                    [
                        'taxonomy'         => $taxonomy_2,
                        'terms'            => $term_2_ids,
                        'include_children' => false
                    ]
                ],
            ];
            $q_2 = get_posts( $args_2 );

            if ( $q_2 ) {
                // Merge the two results into one array of ID's
                $q_1 = array_merge( $q_1, $q_2 );

                // Update our post counter
                $count = count( $q_1 );

                // Update our counter
                $exclude = array_merge( $exclude, $q_2 );
            }
        }
    }

    // We will now run the third query if $count is less than $total_posts
    if ( $count < $total_posts ) {
        // Calculate the amount of post to get
        $diff = $total_posts - $count;

        $args_3 = [
            'post_type'      => $current_post->post_type,
            'post__not_in'   => $exclude,
            'posts_per_page' => $diff,
            'fields'         => 'ids',
        ];
        $q_3 = get_posts( $args_3 );

        if ( $q_3 ) {
            // Merge the two results into one array of ID's
            $q_1 = array_merge( $q_1, $q_3 );
        }
    }

    // Make sure we have an array of ID's
    if ( !$q_1 )
        return false;

    // Run our last query, and output the results
    $final_args = [
        'ignore_sticky_posts' => 1,
        'post_type'           => $current_post->post_type,
        'posts_per_page'      => count( $q_1 ),
        'post__in'            => $q_1,
        'order'               => 'ASC',
        'orderby'             => 'post__in',
        'suppress_filters'    => true,
        'no_found_rows'       => true
    ];
    $final_query = new WP_Query( $final_args );

    return $final_query;
}

Usage:

    <?php
        // where $post_ids is an array of "Recent Posts" widget posts IDs retrieved from previous query:
        //  $anposts = new WP_Query(array('post_type' => 'post', 'posts_per_page' => 4 )); 
        //  $post_ids = wp_list_pluck( $anposts->posts, 'ID' ); 
    $related_query = get_max_related_posts( $post_ids );
        while( $related_query->have_posts() ) {
        $related_query->the_post();
    ?>
    ...
andrebu commented 8 years ago

One more issue exists… on some pages (eg, http://earmilk.com/2015/12/02/boston-bun-and-mayer-hawthorne-releases-paris-groove-visuals/) only 3 posts are output, when there should be 4. However, also notable that on the clone, at the same post (i.e., http://allmilknoduds.com/2015/12/02/boston-bun-and-mayer-hawthorne-releases-paris-groove-visuals/) 4 posts are output.

andrebu commented 8 years ago

The issue is in the post_type parameter of final arguments, here:

    $final_args = [
        'ignore_sticky_posts' => 1,
        // the below line is the problem
        // the below line is the problem
        // the below line is the problem
        'post_type'           => $current_post->post_type,
        // the above line is the problem
        // the above line is the problem
        // the above line is the problem
        'posts_per_page'      => count( $q_1 ),

It should have been:

    $final_args = [
        'ignore_sticky_posts' => 1,
        // the below line is the problem
        // the below line is the problem
        // the below line is the problem
        'post_type'           => 'any',
        // the above line is the problem
        // the above line is the problem
        // the above line is the problem
        'posts_per_page'      => count( $q_1 ),

so that it does not restrict Related Posts to only the exact same type of post we are viewing. This way, if we are seeing a "post" post_type post, we may still see an Event or Album Review or something else as a Related Post.

Examples:

http://earmilk.com/2014/10/15/mayer-hawthorne-stuns-in-his-cover-of-rihannas-stay/

screen shot 2016-03-06 at 12 32 49 am

http://earmilk.com/2015/12/02/boston-bun-and-mayer-hawthorne-releases-paris-groove-visuals/

screen shot 2016-03-06 at 12 33 56 am

http://earmilk.com/2016/03/02/a-chat-with-riton-on-the-release-of-his-new-ep-interview/

screen shot 2016-03-06 at 12 42 14 am screen shot 2016-03-06 at 12 42 30 am