Paginated HTML Sitemap

I’ve got to the point where I needed to break down my HTML Sitemap into several pages. It contained 2000+ links.

The big layout was showing all post titles under category names on one page. I decided to break it down (paginate it) by alphabetical order using WP_Query, so each page would contain about 60 post titles (links). Also on every page beside the post titles, respective category links were shown and plus one other custom taxonomy.

Read More

I did it, and thought it will be OK, Google wise and Users wise. However soon after, I was bombarded with emails. Users were not liking the new paginated/alphabetical look of the HTML Sitemap. They wanted quick access to all posts from one page (or less number of pages as possible). I reverted back.

I can’t keep that big page, but in the same time I have to go with the Users.

So, is there a way where I can split the HTML Sitemap into pages, and each page to contain posts titles (links) from several categories?

I can do this by creating several templates and hard-code the pagination on every template (link them), but that is the hard way.

I’ve looked into multiple loops, nested loops, custom queries, WP_Query, experimenting a lot but it seems I can’t achieve what I want, in an elegant and clean way.

Related posts

Leave a Reply

1 comment

  1. Haven’t tested this, but here you go, lemmie know how it works. You’ll needa do your own pagination links, but that should be pretty straightforward

    //pagination
    $offset = '0';
    $no_of_posts = the_posts_per_page( false ); //Number of posts to display on each page
    if (preg_match( '/page/', $_SERVER['REQUEST_URI'] ) ) {
        $uri = explode( '/', $_SERVER['REQUEST_URI'] );
        foreach ( $uri as $key => $value ) {
            if ( $value == '' ) {
            unset( $uri[$key] );
            }
        }
        $offset = array_pop( $uri );
        $sql_offset = ( $offset * $no_of_posts ) - $no_of_posts;
    }
    //get categories
    my_category_build( array(), 0 );
    
    //function
    function my_category_build( $args, $offset = 0  ) {
    
        //set defaults
        $defaults = array(
            'type'                     => 'post',
            'parent'                   => 0,
            'orderby'                  => 'name',
            'order'                    => 'ASC',
            'hide_empty'               => 1,
            'hierarchical'             => 1,
            'taxonomy'                 => 'category',
            'pad_counts'               => 1
        );
    
        //parse args
        $args = wp_parse_args( $args, $defaults );
    
        //do real work
        $categories = get_categories( $args );
        $cat_c = count( $categories );
        for( $i=$offset; $i<$offset+2 && $i<$cat_c; $i++ ) {
            //set current category object
            $categories[$i] = $cat;
    
            //drill down deeper
            $args['parent'] = $cat->cat_ID;
            $children = get_categories( $args );
            if( count( $children ) > 0 ) {
                my_category_build( $args );
            }
    
            //output posts from category
            $wp_query_args = array(
                'posts_per_page' => -1,
                'post_status'    => 'publish',
                'cat'            => $cat->cat_ID
            );
            $posts = new WP_Query( $wp_query_args );
            foreach( $posts as $p ) {
                //your output here
            }
        }
    }