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 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' );
share|improve this question
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 –  helgatheviking Jul 18 '12 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 '12 at 14:36
add comment

1 Answer

up vote 1 down vote accepted

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' );
    
share|improve this answer
    
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 '12 at 11:54
    
sure thing, it it actually works, please mark it as the answer. if not, let me know what is happening instead. –  helgatheviking Jul 19 '12 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 '12 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 –  helgatheviking Jul 20 '12 at 16:14
add comment

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.