Posted on

Excluding posts by taxonomy

Relevanssi has a category exclusion feature built in, but that only works for basic categories and not any other taxonomies. You can use tax_query to restrict the searches as well, but that’s more complicated than adjusting the setting in Relevanssi settings.

However, if the exclusion is permanent, it’s best done in the indexing level. That way the excluded posts are not taking space in the database. It’s really simple. Just add this code to your theme functions.php:

add_filter('relevanssi_do_not_index', 'rlv_exclude_cat', 10, 2);
function rlv_exclude_cat($exclude, $post_id) {
    if (has_term( TERM, TAXONOMY, $post_id )) $exclude = true;
    return $exclude;
}

where TERM is term name, slug or ID of the term you want to exclude, or an array if you plenty and TAXONOMY is the name of the taxonomy (for example “product_cat”, if you’re working with WooCommerce product categories). Then rebuild the index, and you shouldn’t see anything from the excluded category in the results.

20 comments Excluding posts by taxonomy

  1. I tried this. But, I’m getting a PHP Warning error.

    Missing argument 2 for rlv_exclude_cat().

    Could you tell me how to fix it?

    Thanks.

      1. Hi,

        Sorry to re-open this topic, but the code you suggested doesn’t work in my website using woocommerce (Up to now the website is localhost).

        The exact code that I had in my childtheme is :

        add_filter(‘relevanssi_do_not_index’, ‘rlv_exclude_cat’, 10, 2);
        function rlv_exclude_cat($exclude, $post_id) {
        if (has_term( “product_tag”,”product_cat”, $post_id )) $exclude = true;
        return $exclude;
        }

        The setting in the plugin is shown in the picture attached.

        I can’t figure it out.

        Thank you to help me,
        Bruno

        1. What exactly are you trying to do here? Are you trying to exclude posts that have the term “product_tag” from the “product_cat” taxonomy? Because that’s what you’re doing now. If that’s correct, then I’d check if you’re using Relevanssi in the first place.

          1. Hi Mikko,

            I have :
            product …….. post_type=product
            category …… taxonomy=product_cat
            tag …………… taxonomy=product_tag

            I wonder :
            exclude ………. product_cat = 6
            exclude ………. product_tag = 14

            Regards,
            Bruno

          2. Use:

            if (has_term( 6,”product_cat”, $post_id )) $exclude = true;
            if (has_term( 14,”product_tag”, $post_id )) $exclude = true;

            That should work much better.

          3. Hi Miko,

            Thank you for your support (a sunday, that is great!!!).
            I will be able to try this code later in the day.
            I will inform you.

            Bruno

  2. I am using Enhanced media library plugin. I added an ‘exclude-from-search’ category, and that works fine – any images with that category get excluded from search results, using your code example. However, the library now has about 400 images in it, added by other people, and they have not added the categories properly. I only want a few of those images to appear in search results, so I don’t want to have to go through all 400 images one by one, adding the exclude category. It would be easier, in my situation, to have an “include-in-search” category, as I would then only need to tick about ten boxes instead of 390! I have made a few attempts but I’m not an expert coder and no luck so far. Is it doable? If so, would you be able to give me a simple code example? Thanks.

    1. It’s not complicated:

      add_filter('relevanssi_do_not_index', 'rlv_include_cat', 10, 2);
      function rlv_include_cat($exclude, $post_id) {
          $exclude = true;
          if (has_term( TERM, TAXONOMY, $post_id )) $exclude = false;
          return $exclude;
      }

      This will create an inclusion category.

  3. If I use the above recommendation to exclude a category, will child categories also be excluded? I want all children and grandchildren of a particular category to be excluded from search/indexing and hoping I don’t have to specifically list out each and every one ( have many hundreds – all under a single “exclude” category ).

    Thanks,
    Justin

  4. Thanks so much for the quick reply!

    I should have added… I’m using Woocommerce, so I guess I have a “custom” taxonomy. I did modify the code in the lib/tabs/searching-tab.php file so “product_cat” would show up in the admin Searching tab ( and also modified the code in lib/search.php and lib/class-relevanssi-taxonomy-walker.php ) but I didn’t get the behavior I expected. Any suggestions? Perhaps I missed a file?

    Thanks again,
    Justin

    1. Justin, well, modifying the code may be part of it.

      Instead of changing the code, why not just add a tax_query restriction to your search? Use relevanssi_modify_wp_query to add a tax_query automatically to all searches.

      add_filter( 'relevanssi_modify_wp_query', 'rlv_tax_exclusion' );
      function rlv_tax_exclusion( $query ) {
      	$tax_query = array(
      		array(
      			'taxonomy' => 'product_cat',
      			'field'    => 'slug',
      			'terms'    => 'your_exclude_cat',
      			'operator'    => 'NOT IN',
      			'include_children'    => 'true',
      		),
      	);
      	$query->set( 'tax_query', $tax_query );
      	return $query;
      }

      Something like this.

      1. Thanks Mikko!

        Is there a way to get the page’s context to customize the taxonomy included/excluded in a relevanssi_modify_wp_query filter?

        So for example, let’s say I have three pages:
        – Page 1 where I want to search “everything”, so no tax_query restriction needed
        – Page 2 where I want to excluded a category and it’s children ( i.e. search everything except a category and it’s children which your sample code above achieves )
        – Page 3 where I only want to include a category and it’s children ( i.e. restrict the search to one category and it’s children )

        Apologies as I realize this is probably a general WordPress question but curious if you have some sample code handy!

        Thanks,
        Justin

        1. Justin, sure there is. The best way is to add a custom parameter to the search form, like this:

          <input type="hidden" name="source" value="1" />

          and then in the relevanssi_modify_wp_query you can then use that to adjust the filters:

          if ( isset( $_REQUEST['source'] ) && 2 === $_REQUEST['source'] ) {
              // Exclude category
          } elseif ( isset( $_REQUEST['source'] ) && 3 === $_REQUEST['source'] ) {
              // Include category
          }
      2. Thanks Mikko, really appreciate your help.

        I was able to my desired behavior working with one minor change…

        ‘include_children’ => true,

        instead of

        ‘include_children’ => ‘true’,

        Thanks!
        Justin

  5. Hello Mikko –

    Is there a way to exclude only one or two pages from indexing? Thank you pages, and special offers? Really don’t want to create a new post type for only a few pages.

    1. Anne, yes of course! In Relevanssi Premium, this would be a simple checkbox you can check on the post edit page. With the free version, you can use this:

      add_filter( 'relevanssi_do_not_index', 'rlv_block_pages', 10, 2 );
      function rlv_block_pages( $block, $page_id ) {
          if ( $page_id == 100 || $page_id == 200 ) {
              $block = true;
          }
          return $block;
      }

      Adding this function to your theme functions.php would block pages with ID numbers 100 and 200 from the indexing. Just replace 100 and 200 with the appropriate page ID numbers and then rebuild the index.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.