3

I have a problem with a shortcode that I'm creating.

I have 5-10 different custom post types, and rather than creating a template for every individual post type, Id rather use a normal page and import the posts via a shortcode.

So to explain further, I have a page called Attractions and a post type called 'Attraction'. On the page I insert the shortcode -> [feed type="attraction" limit="5"]

This outputs all the posts under the custom post type "attraction".

The problem I'm having, is getting it to paginate correctly. Ive read a thousand ways to paginate custom post types, and the code I'm currently using tends to work according to so many people, however I cannot get this to work inside the shortcode. Is there a reason for this?

Currently the page displays fine, with five posts, but doesn't echo the next, previous posts links. If I type in the url + /page/2 the second page correctly displays with the next 5 posts in the section. So it seems pagination is working, however I cant access them because no Next/Previous Link appears.

The benefit to doing it this way, is that I can use a normal page, import the posts, and I can include content above and below the shortcode called in.

Hope this all makes sense.

Heres my shortcode code -->

    function section_feed_shortcode( $atts ) {
    extract( shortcode_atts( array( 'limit' => -1, 'type' => 'post'), $atts ) );

    global $paged;
    $q = new WP_Query(  array ( 
        'posts_per_page' => $limit, 
        'post_type' => $type, 
        order => 'ASC', 
        orderby =>'menu_order', 
        'paged' => $paged ) );

    $list = ' ';

    while ( $q->have_posts() ) { $q->the_post();

        $list .= '<article class="listing-view clearfix">' 
        . '<div class="listing-content">' 
        . '<h3><a href="' . get_permalink() . '">' . get_the_title() . '</a></h3>' 
        .'<p>' . get_the_excerpt() . '</p>'
        . '<a href="' . get_permalink() . '">' . 'View &raquo;' . '</a>'
        . '</div>'
        . '<a class="listing-thumb" href="' . get_permalink() . '">' . get_the_post_thumbnail($page->ID, 'listing-thumb')  . '<span></span></a>'
        . '</article>';
    }

    return 
    '<div class="listings clearfix">' 
    . $list 
    . '<div class="nav-previous">' . next_posts_link( __( '<span class="meta-nav">&larr;</span> Older posts' ) ) . '</div>'
    . '<div class="nav-next">' . previous_posts_link( __( 'Newer posts <span class="meta-nav">&rarr;</span>' ) ) . '</div>'
    . '</div>' .
    wp_reset_query();

}
add_shortcode( 'feed', 'section_feed_shortcode' );
2
  • 2
    what is the advantage to doing it this way? seems like a lot of effort when WordPress already does custom post type archives with proper pagination. plus, it is inefficient to do a second query when you don't have to. you don't even have if to create a special template as wordpress will fall back to archives.php or even index.php. if you merely need to add them to the menu there is wordpress.org/extend/plugins/cpt-archives-in-nav-menus Jul 18, 2012 at 14:27
  • Well the benefit is I can put them wherever I want them, and If I can put them on a normal page within wordpress I can put content above and below the shortcode. Each section has content above and below the listings, if I create a template, all this content will have to be hardcoded into the template, and makes it difficult to update on the fly. I need the content on these section pages to be easily updatable.
    – Aaron
    Jul 18, 2012 at 14:36

1 Answer 1

3

ok, i still don't love the idea of a second query, but you're right it is hard to add content to the archives pages.

there were 3 problems that i found:

  1. next_posts_link and previous_posts_link both echo, you need their get_ equivalents.

  2. when you look up get_next_posts_link, you find that it relies on the global $wp_query... which in your case was always for the actual "page" and not for the shortcode's query. you need to actually query_posts then and squash the original query. i hope the reset query works, but i'm not 100% sure. you'll have to test that.

  3. not sure this was a problem, but i usually see the $paged variable defined this way so i went with it.

    function section_feed_shortcode( $atts ) {
    extract( shortcode_atts( array( 'limit' => -1, 'type' => 'post'), $atts ) );
    
    $paged = get_query_var('paged') ? get_query_var('paged') : 1;  
    
    query_posts(  array ( 
        'posts_per_page' => $limit, 
        'post_type' => $type, 
        'order' => 'ASC', 
        'orderby' =>'menu_order', 
        'paged' => $paged ) );
    
    $list = ' ';   
    
    while ( have_posts() ) { the_post();
    
        $list .= '<article class="listing-view clearfix">' 
        . '<div class="listing-content">' 
        . '<h3><a href="' . get_permalink() . '">' . get_the_title() . '</a></h3>' 
        .'<p>' . get_the_excerpt() . '</p>'
        . '<a href="' . get_permalink() . '">' . 'View &raquo;' . '</a>'
        . '</div>'
        . '<a class="listing-thumb" href="' . get_permalink() . '">' . get_the_post_thumbnail($page->ID, 'listing-thumb')  . '<span></span></a>'
        . '</article>';
    }
    
    return 
    '<div class="listings clearfix">' 
    . $list 
    . '<div class="nav-previous">' . get_next_posts_link( __( '<span class="meta-nav">&larr;</span> Older posts' ) ) . '</div>'
    . '<div class="nav-next">' . get_previous_posts_link( __( 'Newer posts <span class="meta-nav">&rarr;</span>' ) ) . '</div>'
    . '</div>' .
    wp_reset_query();
    
    }
    add_shortcode( 'feed', 'section_feed_shortcode' );
    
4
  • Thanks alot @helgatheviking! I haven't tried this yet, but will let you know of the outcome when I get round to it. Much appreciated for looking at this for me.
    – Aaron
    Jul 19, 2012 at 11:54
  • sure thing, it it actually works, please mark it as the answer. if not, let me know what is happening instead. Jul 19, 2012 at 14:12
  • Thanks! It worked perfectly. Im just wondering why, Im a little bit of a noob when it comes to wp, however I always thought using wp_query was stronger and had more functionality than query_posts. Thanks again!
    – Aaron
    Jul 20, 2012 at 14:20
  • afaik, they are the same. new WP_query just stores a 'new' object instead of squashing the original page's query, which is generally safer in terms of not messing up pagination/loops. but since next and previous links depend on the global $wp_query you have to change that w/ query_posts Jul 20, 2012 at 16:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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