Custom Post Types: pretty search URLs and has_archive

Most unfortunate, while my original solution was elegant I did not foresee this complication, and I apologise for the inconvenience.

So, I provide an alternative solution.

Firstly to get your fancy search query:

Your markup will need to change, but this will intercept the URLs and rewrite them correctly internally, it is similar to the other answer but prettier, faster, easier to read, and in a single function

function custom_rewrite( $wp_rewrite ) {
    $feed_rules = array(
        'search/(.+)/(.+)'      =>  'index.php?post_type=".$wp_rewrite->preg_index(1)."&s=" . $wp_rewrite->preg_index(2)
    );
    $wp_rewrite->rules = $feed_rules + $wp_rewrite->rules;
}
// refresh/flush permalinks in the dashboard if this is changed in any way
add_filter( "generate_rewrite_rules', 'custom_rewrite' );

Thus example.com/search/post/bannana will search all posts of type ‘post’ for bannana.

If you would prefer instead not to ‘search’ but to instead show a term, all you need to do is modify the query variables in the rewrite rule.

You can use the monkeyman rewrite rules analyser plugin to help you, by putting in URLs and being shown which rewrite rule handles it and the priority/order of said rules

BUT

However, you will not be able to use the elegant html markup to use these URLs, it will not play nicely, you will need to modify where the forms is submitted to which means while this might sound like a marvellous idea, in practice the implementation means you will need at least 1 redirect for a searchbox to work with these URLs, which is not ideal at all.

For your species search problem

Also modify your species registration to be more specific/accurate:

$args = array(
  'labels' => $labels,
  'public' => true,
  'publicly_queryable' => true,
  'exclude_from_search' => false, // lets not guess what this will be, lets be authorative
  'show_ui' => true,
  'show_in_menu' => true,
  'query_var' => true,
  'has_archive' => true,
  'capability_type' => 'post',
  'has_archive' => true,
  'hierarchical' => false,
  'menu_position' => 5,
  'menu_icon' => $this->plugin_url . 'images/fish20.png',
  'supports' => array('author','thumbnail','excerpt','comments','revisions')
);

But, while this might fix it, I suspect not. Rereading your question, I see it rewrites to /search/term, but WordPress does not do this by default. I suspect you have code somewhere else that rewrites search terms into a prettier version for general post searches, but this is interfering, be it because of the order of where its added in the code or something else.

Since I can’t see your entire codebase, and I’m not sure what this search code prettification looks like, I can’t help you any further than to point you in its directions ( and to conditionally rewrite if post_type is not set rather than always).

edit: give this a try:

function custom_rewrite( $wp_rewrite ) {
    $feed_rules = array(
        'species/(.+?)(/[0-9]+)?/?$'      =>  'index.php?post_type=species&species=".$wp_rewrite->preg_index(1)."&page=".$wp_rewrite->preg_index(2)
    );
    $wp_rewrite->rules = $feed_rules + $wp_rewrite->rules;
}
// refresh/flush permalinks in the dashboard if this is changed in any way
add_filter( "generate_rewrite_rules', 'custom_rewrite' );

Leave a Comment