• I have a shortcode which lists entries from a particular post type, with a picture and excerpt. However, for some reason the ‘Continue Reading’ link doesn’t work properly – it just links to the top of the current page. I have absolutely no idea why, and I can’t seem to fix it, whatever I do.

    The code in question is a shortcode, as follows:

    add_shortcode('plants', 'plant_list_shortcode');
    // define the shortcode function
    function plant_list_shortcode($atts) {
        extract(shortcode_atts(array(
        'cat'	=> '',
        'catexclude'	=> '',
        'view' => '',
        'featured' => '',
        'hidetitle' => '',
        'des' => '',
        'maxdes' => '',
        ), $atts));
        
        $tax_query = array (
            "relation" => "AND",
                array(
                "taxonomy" => "plant_list_category",
                "field"    => "slug",
                "terms"    => array($cat)
                ),
            array(
                "taxonomy" => "plant_list_category",
                "field"    => "slug",
                "terms"    => array($catexclude),
                "operator" => "NOT IN"
                ),
        );
    
        if( ! empty( $cat ) )
        {
            $query = array(
                'tax_query' => $tax_query,
                'order'          => 'ASC',
                'orderby' 		 => 'title',
                'post_type'      => 'plant_lists',
                'post_status'    => null,
                'nopaging' 	=> 1,
                'posts_per_page' => -10);
        }
        else
        {
            $query = array(
                'plant_list_category'	 => $cat,
                'order'          => 'ASC',
                'orderby' 		 => 'title',
                'post_type'      => 'plant_lists',
                'post_status'    => null,
                'nopaging' 	=> 1,
                'posts_per_page' => -10);
        }
    
        $plant_lists = new WP_Query( $query );
        
        $countPlants='0';
        $plant_shortcode = '';
        
        if ( !empty( $cat ) && $hidetitle != 'yes' ) 
    	{ 
            global $wpdb; 
            $catname = $wpdb->get_var("SELECT name FROM $wpdb->terms WHERE slug = '$cat'");
    		$plant_shortcode .= '<div class="plant-catname">' . $catname . '</div>'; 
    	}
        
        $plant_shortcode .= '<table class="planttable"><tbody>';
        
        while( $plant_lists->have_posts() ) : $plant_lists->the_post();
            $countPlants++;
            setup_postdata( get_post( $id ));
    
            $theimage = wp_get_attachment_image_src( get_post_thumbnail_id($id) , 'medium');
            
            $plant_shortcode .= '<tr><td width="50%" align="center"><a href="' . get_permalink() . '"><img src="'.$theimage[0].'" alt="" /></a></td>';
            $plant_shortcode .= '<td><div class="plant-title"><a href="' . get_permalink() . '">'. get_the_title().'</a></div>';
            
            $plant_shortcode .= '<div class="plant-excerpt">';
    
            $family = get_post_meta( $id, '_plant_lists_family', true );
            
            if($family != NULL)
            {
                $plant_shortcode .= '<p><strong>Family: '.$family.'</strong></p>';
            }
            
            $plant_shortcode .= '<p>'. get_the_excerpt( $id ) .'</p>';
            $plant_shortcode .= '</div></td></tr>';
        
        endwhile; 
            
        $plant_shortcode .= '</tbody></table>';
    
        if ($countPlants == '0') {
            $plant_shortcode = 'No plants are currently posted in this category';
        }
    
        wp_reset_postdata();
        wp_reset_query();
        
        $plant_shortcode = do_shortcode( $plant_shortcode );
        return (__($plant_shortcode));
    }//ends the plant_shortcode function

    I then add the shortcode to a page or post as follows:

    [plants cat="terrarium-madagascar" hidetitle="yes" featured="no" view="list" buttontext="Details about this plant..." des="yes" maxdes="500"]

    The result is that the ‘Continue Reading’ links within each excerpt link back to the current page. The link on the title is correct, it’s only the continue reading link that’s wrong. You can see an example here:

    https://www.pumpkinbeth.com/2017/04/madagascar-terrarium-planting-list/

    Even more curiously, when I use the shortcode on a page instead of a post, the problem doesn’t happen:

    https://www.pumpkinbeth.com/plants/

    I suspect the issue is something around my use of the WP Loop, but I’m relatively new to WP development so must be missing something. Help! ??

    I’ve seen this issue raised a couple of times around the forums, and on StackOverflow, but nobody seems to know the definitive answer to fix it. I’d really like to solve it. Alternatively, if somebody can show me how to hide the ‘Continue Reading’ link for excerpts – but only within the context of this shortcode – then I’d appreciate it.

Viewing 14 replies - 1 through 14 (of 14 total)
  • Insert this line of code wp_reset_query(); just after this line.
    $plant_shortcode .= '<table class="planttable"><tbody>';

    Hope it should help to you and let me know the feedback.

    Thread Starter Webreaper

    (@webreaper)

    Thanks. Unfortunately that hasn’t had any effect.

    It looks perfect to me. Please check after clear the cache of browser.

    Thread Starter Webreaper

    (@webreaper)

    What looks perfect to you?

    Here’s the page with the issue; WP Cache has been deleted, but it’s still showing the wrong ‘continue reading’ links.

    https://www.pumpkinbeth.com/2017/04/white-terrarium-planting-list/

    If you were referring to https://www.pumpkinbeth.com/plants, that’s a page, not a post, and has always worked correctly, as I specified in my OP.

    Use this code at functions.php file of theme.

    function custom_excerpt_read_more_link($output) {
        global $post;
        return $output . ' <a href="' . get_permalink($post->ID) . '" class="more-link" title="Read More">Continue reading &rarr;</a>';
    }
    add_filter( 'the_excerpt', 'custom_excerpt_read_more_link' );
    Thread Starter Webreaper

    (@webreaper)

    That doesn’t have any effect either.

    What I’d really like to do is understand what is causing the link to break, and fix it, rather than trying to add additional code to try and work around the problem. It seems to me like the loop in my code is a pretty standard thing that must have been written hundreds of times before. ??

    Moderator bcworkz

    (@bcworkz)

    Just remove the setup_postdata() line. You don’t need it because $plant_lists->the_post() does the setup for you. By inappropriately passing get_post( $id ) to setup_postdata(), you’ve unwittingly confused the situation.

    The place to use setup_postdata() is in foreach loops that cannot use WP_Query::the_post(). In such situations you must declare $post as global, assign the current post object to $post, then call setup_postdata( $post );

    Thread Starter Webreaper

    (@webreaper)

    Funnily enough, I only added the setup_postdata() line to try and fix the problem. Removing it has zero effect, unfortunately (but I’ve removed it all the same).

    I would suggest to change the get_the_excerpt($id); with ‘Shakeel-‘.$id.’-‘.get_the_excerpt($post->ID) Hope it should help.

    Thread Starter Webreaper

    (@webreaper)

    Tried changing it to:

    $plant_shortcode .= '<p>'. get_the_excerpt( $post->ID ) .'</p>';

    No effect, unfortunately.

    Thread Starter Webreaper

    (@webreaper)

    Okay, so I’ve managed to put in a fix, although it’s a bit hacky and I don’t understand what’s going on here. Basically, I pull out the excerpt into text, and then find the start and end of the wrong ‘Continue Reading’ anchor, and replace it with my own – using the link from the get_permalink() call I make earlier on in the loop. It seems to work.

    while( $plant_lists->have_posts() ) : $plant_lists->the_post();
            $countPlants++;
    
            $theimage = wp_get_attachment_image_src( get_post_thumbnail_id($id) , 'plant-list');
    
            $plant_permalink = get_permalink();
            $plant_shortcode .= '<tr><td width="50%" align="center"><a href="' . $plant_permalink . '"><img src="'.$theimage[0].'" alt="" /></a></td>';
            $plant_shortcode .= '<td><div class="plant-title"><a href="' . $plant_permalink . '">'. get_the_title().'</a></div>';
            
            $plant_shortcode .= '<div class="plant-excerpt">';
    
            $family = get_post_meta( $id, '_plant_lists_family', true );
            
            if($family != NULL)
            {
                $plant_shortcode .= '<p><strong>Family: '.$family.'</strong></p>';
            }
    
            $the_excerpt = get_the_excerpt( $post->ID );
            $start = strpos( $the_excerpt, "<a href" );
    
            if( $start !== false )
            {
                $end = strpos( $the_excerpt, "</a>", $start + 6 );
    
                if( $end !== false )
                {
                    $link = " <a href='" . $plant_permalink . "'>Continue Reading &rarr;</a>";
                    $the_excerpt = substr_replace( $the_excerpt, $link, $start, $end + 4 );
                }
            }        
    
            $plant_shortcode .= '<p>'. $the_excerpt .'</p>';
            $plant_shortcode .= '</div></td></tr>';
        
        endwhile; 

    The totally bizarre thing is that if I move the code to do the string replace earlier in the loop, the behaviour reverts back to what it was doing before.

    Even if I move the get_the_excerpt() call up to just below the get_permalink call, it breaks again – i.e., it doesn’t work if I do this:

    $plant_permalink = get_permalink();
    $the_excerpt = get_the_excerpt( $post->ID );

    It seems massively fragile. I’m presuming some subsequent code in the loop is messing up some global state as it runs, or there’s some race condition going on.

    So basically, this hack works, but I’ve no idea if it’ll suddenly break in future or even why re-ordering the code doesn’t behave deterministically. Any PHP/WP experts out there can explain exactly what’s going on!??!

    • This reply was modified 7 years, 11 months ago by Webreaper.
    • This reply was modified 7 years, 11 months ago by Webreaper.
    Thread Starter Webreaper

    (@webreaper)

    I’ve just posted a reply, but it appears to have disappeared.
    Ah, there it is.

    • This reply was modified 7 years, 11 months ago by Webreaper.
    Moderator bcworkz

    (@bcworkz)

    We’re sorry the forum isn’t always quick to have posts appear. There are reasons, but I don’t know specifically why in this case. Patience is a virtue ??

    I believe the problem now is using $post in get_the_excerpt( $post->ID );
    Your script does not have access to the global $post unless you declare it first. Either do that or get the current loop $post->ID with get_the_ID().

    In your initial code that just used $id was incorrect because AFAICT it was not defined, or defined earlier incorrectly. Thus the permalink that get_the_excerpt() used came from the main query because it had nothing better to go on.

    You can quickly test if I’m right by commenting out your hack and using get_the_ID(). If that fails, you can always restore your hack ??

    Thread Starter Webreaper

    (@webreaper)

    I previously had the code using get_the_ID() – I added the explicit call to $post->ID to see if that solved the problem. So I don’t think this is going to help, unfortunately, but I’ll give it a try when I have time.

    Re: the post thing – the post appeared, then I edited it, and then it disappeared. But when I posted a new post, it reappeared. Ah well. ??

Viewing 14 replies - 1 through 14 (of 14 total)
  • The topic ‘“Continue Reading” link wrong in post excerpt – anyone know the actual solution?’ is closed to new replies.