How to create an archive for all posts that do not have a post format?

The title says it all. I need working pagination, correct post count etc. Basically a new page for posts but with a filter for post formats.

Things I have tried so far:

1) Created a new rewrite rule for /no-formats/ that gets the id of the page that loads home.php and appends an argument (?no_post_format=true). Then hooked to ‘pre_get_posts’, checked for that argument and added a tax_query to the main query that excludes all posts with post formats.
This did not work because a rewrite rule to the home page causes a redirect to the actual home page. So /no-formats/ becomes /home/ and my argument is lost.

Not the actual code but to give you an idea of what I mean:

add_rewrite_rule( 'no-formats/?$', 'index.php?p='. get_option( 'page_for_posts' ) . '&no_post_format=true', 'top' );

2) Created a new page and tried to replicate the behavior of the page that displays posts and added the mentioned tax_query exclude. I just couldn’t come up with any way to get an exact duplication of the home page. Maybe have to dig deeper into WP core.

Does somebody have any ideas that could push me into the right direction?

2 Answers
2

For me I’d used a little different approach:

  1. use an endpoint to create an url like http://example.com/no-formats/
  2. hooking pre_get_posts to set the proper query if needed
  3. filter template_include to force WP to use home.php instead of duplicating it

No more.

add_action('init', 'add_no_format_endpoint');

function add_no_format_endpoint() {
  add_rewrite_endpoint( 'no-formats', EP_ROOT );
}

add_action('pre_get_posts', 'handle_no_format');

function handle_no_format( $q ) {
  if ( $q->is_main_query() && is_home() && isset( $q->query['no-formats'] ) ) {
    unset( $q->query['no-formats'] );
    $q->is_home = FALSE; // <- add this if you have setted a static page as frontpage
    $tax_q =  array(
      'taxonomy' => 'post_format',
      'field' => 'id',
      'operator' => 'NOT IN',
      'terms' => get_terms( 'post_format', array( 'fields' => 'ids' ) )
    );
    $q->set( 'tax_query', array( $tax_q) );
    add_filter( 'template_include', 'force_home_template', 999 );
  }
}

function force_home_template() {
  return locate_template( array( 'home.php', 'index.php' ), FALSE );
}

Remember to visit Settings->Permalinks in you dashboard to flush rewrite rules.

Leave a Comment